From 3e8120d532821e351e7a6e8298644007273d7baa Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Mon, 28 May 2018 13:47:53 +0900 Subject: [PATCH 001/445] Make "Clear this track" undoable Fixes #4375 --- src/core/Track.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 8af5393dc..fa500da33 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -1813,6 +1813,7 @@ void TrackOperationsWidget::cloneTrack() void TrackOperationsWidget::clearTrack() { Track * t = m_trackView->getTrack(); + t->addJournalCheckPoint(); t->lock(); t->deleteTCOs(); t->unlock(); From a2cb7e96ea057de604003ecdc70745a80e4b40e0 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sat, 10 Feb 2018 13:24:59 +0100 Subject: [PATCH 002/445] Fix VST sub-window creation glitches in project loading Fixes bugs where during project loading (observed with VST effects), empty widgets and sub-windows would be left floating around. These were caused by inconsistencies between the way VST UIs were created when loading a project and when adding an effect in an existing project. In some situations, this caused createUI to be called twice, leaving over multiple empty widgets. This commit refactors some code in order to avoid creating unnecessary sub- windows, which aren't needed with VST effects, but were still created, usually being invisible. All sub-window related code was moved out of VstPlugin into vestige.cpp, which is the only place where sub-window VSTs are actually used. A new sub-class of VstPlugin, VstInstrumentPlugin, now handles VST sub-windows and is used by vestigeInstrument. "guivisible" attribute loading was moved out of VstPlugin as well and is now done in VstEffectControls' and vestigeInstrument's loadSettings method respectively. This causes some minor code duplication unfortunately. Closes #4110 --- plugins/VstEffect/VstEffectControlDialog.cpp | 26 ++-- plugins/VstEffect/VstEffectControlDialog.h | 3 +- plugins/VstEffect/VstEffectControls.cpp | 14 +- plugins/VstEffect/VstEffectControls.h | 6 +- plugins/vestige/vestige.cpp | 62 ++++++++- plugins/vst_base/VstPlugin.cpp | 136 +++++-------------- plugins/vst_base/VstPlugin.h | 15 +- 7 files changed, 136 insertions(+), 126 deletions(-) diff --git a/plugins/VstEffect/VstEffectControlDialog.cpp b/plugins/VstEffect/VstEffectControlDialog.cpp index 34ad097c9..ad2666392 100644 --- a/plugins/VstEffect/VstEffectControlDialog.cpp +++ b/plugins/VstEffect/VstEffectControlDialog.cpp @@ -45,6 +45,7 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) : EffectControlDialog( _ctl ), m_pluginWidget( NULL ), + m_plugin( NULL ), tbLabel( NULL ) { @@ -62,16 +63,10 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) : embed_vst = m_plugin->embedMethod() != "none"; if (embed_vst) { - m_plugin->createUI( nullptr, true ); - m_pluginWidget = m_plugin->pluginWidget( false ); - -#ifdef LMMS_BUILD_WIN32 - if( !m_pluginWidget ) - { - m_pluginWidget = m_plugin->pluginWidget( false ); + if (! m_plugin->pluginWidget()) { + m_plugin->createUI(nullptr); } -#endif - + m_pluginWidget = m_plugin->pluginWidget(); } } @@ -79,7 +74,7 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) : { setWindowTitle( m_plugin->name() ); - QPushButton * btn = new QPushButton( tr( "Show/hide" ) ); + QPushButton * btn = new QPushButton( tr( "Show/hide" )); if (embed_vst) { btn->setCheckable( true ); @@ -95,6 +90,7 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) : btn->setMaximumWidth( 78 ); btn->setMinimumHeight( 24 ); btn->setMaximumHeight( 24 ); + m_togglePluginButton = btn; m_managePluginButton = new PixmapButton( this, "" ); m_managePluginButton->setCheckable( false ); @@ -295,6 +291,14 @@ void VstEffectControlDialog::togglePluginUI( bool checked ) return; } - m_plugin->toggleUI(); + if ( m_togglePluginButton->isChecked() != checked ) { + m_togglePluginButton->setChecked( checked ); + } + + if ( checked ) { + m_plugin->showUI(); + } else { + m_plugin->hideUI(); + } } diff --git a/plugins/VstEffect/VstEffectControlDialog.h b/plugins/VstEffect/VstEffectControlDialog.h index ddbbef878..e20915019 100644 --- a/plugins/VstEffect/VstEffectControlDialog.h +++ b/plugins/VstEffect/VstEffectControlDialog.h @@ -54,6 +54,7 @@ protected: private: QWidget * m_pluginWidget; + QPushButton * m_togglePluginButton; PixmapButton * m_openPresetButton; PixmapButton * m_rolLPresetButton; PixmapButton * m_rolRPresetButton; @@ -64,7 +65,7 @@ private: QLabel * tbLabel; -private slots: +public slots: void togglePluginUI( bool checked ); } ; diff --git a/plugins/VstEffect/VstEffectControls.cpp b/plugins/VstEffect/VstEffectControls.cpp index 92688545b..ef5a59463 100644 --- a/plugins/VstEffect/VstEffectControls.cpp +++ b/plugins/VstEffect/VstEffectControls.cpp @@ -40,7 +40,8 @@ VstEffectControls::VstEffectControls( VstEffect * _eff ) : m_subWindow( NULL ), knobFModel( NULL ), ctrHandle( NULL ), - lastPosInMenu (0) + lastPosInMenu (0), + m_vstGuiVisible ( true ) // m_presetLabel ( NULL ) { } @@ -64,6 +65,8 @@ void VstEffectControls::loadSettings( const QDomElement & _this ) m_effect->m_pluginMutex.lock(); if( m_effect->m_plugin != NULL ) { + m_vstGuiVisible = _this.attribute( "guivisible" ).toInt(); + m_effect->m_plugin->loadSettings( _this ); const QMap & dump = m_effect->m_plugin->parameterDump(); @@ -144,6 +147,15 @@ int VstEffectControls::controlCount() +EffectControlDialog *VstEffectControls::createView() +{ + auto dialog = new VstEffectControlDialog( this ); + dialog->togglePluginUI( m_vstGuiVisible ); + return dialog; +} + + + void VstEffectControls::managePlugin( void ) { diff --git a/plugins/VstEffect/VstEffectControls.h b/plugins/VstEffect/VstEffectControls.h index 7328f2f42..e4f099fd1 100644 --- a/plugins/VstEffect/VstEffectControls.h +++ b/plugins/VstEffect/VstEffectControls.h @@ -59,10 +59,7 @@ public: virtual int controlCount(); - virtual EffectControlDialog * createView() - { - return new VstEffectControlDialog( this ); - } + virtual EffectControlDialog * createView(); protected slots: @@ -96,6 +93,7 @@ private: friend class VstEffectControlDialog; friend class manageVSTEffectView; + bool m_vstGuiVisible; } ; diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index db9cf5bba..c54c6c3a8 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -24,6 +24,8 @@ #include "vestige.h" +#include + #include #include #include @@ -73,6 +75,57 @@ Plugin::Descriptor PLUGIN_EXPORT vestige_plugin_descriptor = } +class vstSubWin : public QMdiSubWindow +{ +public: + vstSubWin( QWidget * _parent ) : + QMdiSubWindow( _parent ) + { + setAttribute( Qt::WA_DeleteOnClose, false ); + setWindowFlags( Qt::WindowCloseButtonHint ); + } + + virtual ~vstSubWin() + { + } + + virtual void closeEvent( QCloseEvent * e ) + { + // ignore close-events - for some reason otherwise the VST GUI + // remains hidden when re-opening + hide(); + e->ignore(); + } +}; + + +class VstInstrumentPlugin : public VstPlugin +{ +public: + using VstPlugin::VstPlugin; + + void createUI( QWidget *parent ) override + { + Q_UNUSED(parent); + VstPlugin::createUI( nullptr ); + if ( embedMethod() != "none" ) { + m_pluginSubWindow.reset(new vstSubWin( gui->mainWindow()->workspace() )); + m_pluginSubWindow->setWidget(pluginWidget()); + } + } + + /// Overwrite editor() to return the sub window instead of the embed widget + /// itself. This makes toggleUI() and related functions toggle the + /// sub window's visibility. + QWidget* editor() override + { + return m_pluginSubWindow.get(); + } +private: + unique_ptr m_pluginSubWindow; +}; + + QPixmap * VestigeInstrumentView::s_artwork = NULL; QPixmap * manageVestigeInstrumentView::s_artwork = NULL; @@ -127,6 +180,12 @@ void vestigeInstrument::loadSettings( const QDomElement & _this ) { m_plugin->loadSettings( _this ); + if ( _this.attribute( "guivisible" ).toInt() ) { + m_plugin->showUI(); + } else { + m_plugin->hideUI(); + } + const QMap & dump = m_plugin->parameterDump(); paramCount = dump.size(); char paramStr[35]; @@ -267,7 +326,7 @@ void vestigeInstrument::loadFile( const QString & _file ) } m_pluginMutex.lock(); - m_plugin = new VstPlugin( m_pluginDLL ); + m_plugin = new VstInstrumentPlugin( m_pluginDLL ); if( m_plugin->failed() ) { m_pluginMutex.unlock(); @@ -278,6 +337,7 @@ void vestigeInstrument::loadFile( const QString & _file ) return; } + m_plugin->createUI(nullptr); m_plugin->showUI(); if( set_ch_name ) diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 5c7504dd1..32230cd8d 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -62,28 +62,6 @@ #include "templates.h" #include "FileDialog.h" -class vstSubWin : public QMdiSubWindow -{ -public: - vstSubWin( QWidget * _parent ) : - QMdiSubWindow( _parent ) - { - setAttribute( Qt::WA_DeleteOnClose, false ); - } - - virtual ~vstSubWin() - { - } - - virtual void closeEvent( QCloseEvent * e ) - { - // ignore close-events - for some reason otherwise the VST GUI - // remains hidden when re-opening - hide(); - e->ignore(); - } -} ; - VstPlugin::VstPlugin( const QString & _plugin ) : m_plugin( _plugin ), @@ -124,7 +102,6 @@ VstPlugin::VstPlugin( const QString & _plugin ) : VstPlugin::~VstPlugin() { - delete m_pluginSubWindow; delete m_pluginWidget; } @@ -174,41 +151,8 @@ void VstPlugin::tryLoad( const QString &remoteVstPluginExecutable ) -void VstPlugin::hideEditor() -{ - QWidget * w = pluginWidget(); - if( w ) - { - w->hide(); - } -} - - - - -void VstPlugin::toggleEditor() -{ - QWidget * w = pluginWidget(); - if( w ) - { - w->setVisible( !w->isVisible() ); - } -} - - - - void VstPlugin::loadSettings( const QDomElement & _this ) { - if( _this.attribute( "guivisible" ).toInt() ) - { - showUI(); - } - else - { - hideUI(); - } - const int num_params = _this.attribute( "numparams" ).toInt(); // if it exists try to load settings chunk if( _this.hasAttribute( "chunk" ) ) @@ -286,7 +230,7 @@ void VstPlugin::toggleUI() } else if (pluginWidget()) { - toggleEditor(); + toggleEditorVisibility(); } } @@ -362,21 +306,9 @@ void VstPlugin::setParameterDump( const QMap & _pdump ) unlock(); } -QWidget *VstPlugin::pluginWidget(bool _top_widget) +QWidget *VstPlugin::pluginWidget() { - if ( m_embedMethod == "none" || !m_pluginWidget ) - { - return nullptr; - } - - if ( _top_widget && m_pluginWidget->parentWidget() == m_pluginSubWindow ) - { - return m_pluginSubWindow; - } - else - { - return m_pluginWidget; - } + return m_pluginWidget; } @@ -458,6 +390,10 @@ bool VstPlugin::processMessage( const message & _m ) } +QWidget *VstPlugin::editor() +{ + return m_pluginWidget; +} void VstPlugin::openPreset( ) @@ -579,15 +515,10 @@ void VstPlugin::showUI() } else if ( m_embedMethod != "headless" ) { - if (! pluginWidget()) { - createUI( NULL, false ); - } - - QWidget * w = pluginWidget(); - if( w ) - { - w->show(); + if (! editor()) { + qWarning() << "VstPlugin::showUI called before VstPlugin::createUI"; } + toggleEditorVisibility( true ); } } @@ -599,7 +530,7 @@ void VstPlugin::hideUI() } else if ( pluginWidget() != nullptr ) { - hideEditor(); + toggleEditorVisibility( false ); } } @@ -654,22 +585,39 @@ QByteArray VstPlugin::saveChunk() return a; } -void VstPlugin::createUI( QWidget * parent, bool isEffect ) +void VstPlugin::toggleEditorVisibility( int visible ) { + QWidget* w = editor(); + if ( ! w ) { + return; + } + + if ( visible < 0 ) { + visible = ! w->isVisible(); + } + w->setVisible( visible ); +} + +void VstPlugin::createUI( QWidget * parent ) +{ + if ( m_pluginWidget ) { + qWarning() << "VstPlugin::createUI called twice"; + m_pluginWidget->setParent( parent ); + return; + } + if( m_pluginWindowID == 0 ) { return; } QWidget* container = nullptr; - m_pluginSubWindow = new vstSubWin( gui->mainWindow()->workspace() ); - auto sw = m_pluginSubWindow.data(); #if QT_VERSION >= 0x050100 if (m_embedMethod == "qt" ) { QWindow* vw = QWindow::fromWinId(m_pluginWindowID); - container = QWidget::createWindowContainer(vw, sw ); + container = QWidget::createWindowContainer(vw, parent ); container->installEventFilter(this); } else #endif @@ -708,7 +656,7 @@ void VstPlugin::createUI( QWidget * parent, bool isEffect ) #ifdef LMMS_BUILD_LINUX if (m_embedMethod == "xembed" ) { - QX11EmbedContainer * embedContainer = new QX11EmbedContainer( sw ); + QX11EmbedContainer * embedContainer = new QX11EmbedContainer( parent ); connect(embedContainer, SIGNAL(clientIsEmbedded()), this, SLOT(handleClientEmbed())); embedContainer->embedClient( m_pluginWindowID ); container = embedContainer; @@ -716,29 +664,13 @@ void VstPlugin::createUI( QWidget * parent, bool isEffect ) #endif { qCritical() << "Unknown embed method" << m_embedMethod; - delete m_pluginSubWindow; return; } container->setFixedSize( m_pluginGeometry ); container->setWindowTitle( name() ); - if( parent == NULL ) - { - m_pluginWidget = container; - - sw->setWidget(container); - - if( isEffect ) - { - sw->setAttribute( Qt::WA_TranslucentBackground ); - sw->setWindowFlags( Qt::FramelessWindowHint ); - } - else - { - sw->setWindowFlags( Qt::WindowCloseButtonHint ); - } - }; + m_pluginWidget = container; container->setFixedSize( m_pluginGeometry ); } diff --git a/plugins/vst_base/VstPlugin.h b/plugins/vst_base/VstPlugin.h index f3d6bea8e..9e8b39771 100644 --- a/plugins/vst_base/VstPlugin.h +++ b/plugins/vst_base/VstPlugin.h @@ -54,8 +54,10 @@ public: return m_pluginWindowID != 0; } - void hideEditor(); - void toggleEditor(); + /// Same as pluginWidget(), but can be overwritten in sub-classes to modify + /// behavior the UI. This is used in VstInstrumentPlugin to wrap the VST UI + /// in a QMdiSubWindow + virtual QWidget* editor(); inline const QString & name() const { @@ -93,7 +95,7 @@ public: void setParameterDump( const QMap & _pdump ); - QWidget * pluginWidget( bool _top_widget = true ); + QWidget * pluginWidget(); virtual void loadSettings( const QDomElement & _this ); virtual void saveSettings( QDomDocument & _doc, QDomElement & _this ); @@ -103,9 +105,8 @@ public: return "vstplugin"; } - void toggleUI() override; - void createUI( QWidget *parent, bool isEffect ); + virtual void createUI(QWidget *parent); bool eventFilter(QObject *obj, QEvent *event); QString embedMethod() const; @@ -123,6 +124,7 @@ public slots: void showUI() override; void hideUI() override; + void toggleUI() override; void handleClientEmbed(); @@ -130,9 +132,10 @@ private: void loadChunk( const QByteArray & _chunk ); QByteArray saveChunk(); + void toggleEditorVisibility(int visible = -1); + QString m_plugin; QPointer m_pluginWidget; - QPointer m_pluginSubWindow; int m_pluginWindowID; QSize m_pluginGeometry; const QString m_embedMethod; From 1220374a7f03d91baae50abb665d8bed0f49c43b Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sat, 10 Feb 2018 13:47:40 +0100 Subject: [PATCH 003/445] Fix effect dialog layout glitches QMdiSubWindow::setSizePolicy doesn't have any effect because QMdiSubWindow uses a layout. This patch uses QMdiSubWindow::layout()->setSizeConstraint instead. This may cause effects that don't have a layout and don't implement sizeHint() to now be resizable. For effects that do though, it fixes the size constraint. --- src/gui/widgets/EffectView.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/widgets/EffectView.cpp b/src/gui/widgets/EffectView.cpp index 0a5e46b3f..5faae3517 100644 --- a/src/gui/widgets/EffectView.cpp +++ b/src/gui/widgets/EffectView.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include "EffectView.h" #include "DummyEffect.h" @@ -109,7 +110,9 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) : { m_subWindow = gui->mainWindow()->addWindowedWidget( m_controlView ); m_subWindow->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); - m_subWindow->setFixedSize( m_subWindow->size() ); + if (m_subWindow->layout()) { + m_subWindow->layout()->setSizeConstraint(QLayout::SetFixedSize); + } Qt::WindowFlags flags = m_subWindow->windowFlags(); flags &= ~Qt::WindowMaximizeButtonHint; From 55da698d7c864397c695583ff9da8c1a76718e8f Mon Sep 17 00:00:00 2001 From: DomClark Date: Sat, 24 Mar 2018 15:04:37 +0000 Subject: [PATCH 004/445] Fix X11 embedding on Qt4 --- plugins/VstEffect/VstEffectControlDialog.cpp | 2 +- plugins/vestige/vestige.cpp | 4 +++- plugins/vst_base/VstPlugin.cpp | 6 ++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/plugins/VstEffect/VstEffectControlDialog.cpp b/plugins/VstEffect/VstEffectControlDialog.cpp index ad2666392..ea2581349 100644 --- a/plugins/VstEffect/VstEffectControlDialog.cpp +++ b/plugins/VstEffect/VstEffectControlDialog.cpp @@ -64,7 +64,7 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) : if (embed_vst) { if (! m_plugin->pluginWidget()) { - m_plugin->createUI(nullptr); + m_plugin->createUI(this); } m_pluginWidget = m_plugin->pluginWidget(); } diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index c54c6c3a8..9ea053e8e 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -107,10 +107,12 @@ public: void createUI( QWidget *parent ) override { Q_UNUSED(parent); - VstPlugin::createUI( nullptr ); if ( embedMethod() != "none" ) { m_pluginSubWindow.reset(new vstSubWin( gui->mainWindow()->workspace() )); + VstPlugin::createUI( m_pluginSubWindow.get() ); m_pluginSubWindow->setWidget(pluginWidget()); + } else { + VstPlugin::createUI( nullptr ); } } diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 32230cd8d..d9d9cc9f7 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -656,6 +656,10 @@ void VstPlugin::createUI( QWidget * parent ) #ifdef LMMS_BUILD_LINUX if (m_embedMethod == "xembed" ) { + if (parent) + { + parent->setAttribute(Qt::WA_NativeWindow); + } QX11EmbedContainer * embedContainer = new QX11EmbedContainer( parent ); connect(embedContainer, SIGNAL(clientIsEmbedded()), this, SLOT(handleClientEmbed())); embedContainer->embedClient( m_pluginWindowID ); @@ -671,8 +675,6 @@ void VstPlugin::createUI( QWidget * parent ) container->setWindowTitle( name() ); m_pluginWidget = container; - - container->setFixedSize( m_pluginGeometry ); } bool VstPlugin::eventFilter(QObject *obj, QEvent *event) From 49dcd385f5f545210532338c98aa5bac17a13517 Mon Sep 17 00:00:00 2001 From: DomClark Date: Fri, 13 Apr 2018 00:24:41 +0100 Subject: [PATCH 005/445] Fix VST effect load crash on non-primary monitor --- src/gui/SubWindow.cpp | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index 284e116d8..0a0effc45 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -113,8 +113,11 @@ void SubWindow::paintEvent( QPaintEvent * ) p.drawLine( width() - 1, m_titleBarHeight, width() - 1, height() - 1 ); // window icon - QPixmap winicon( widget()->windowIcon().pixmap( m_buttonSize ) ); - p.drawPixmap( 3, 3, m_buttonSize.width(), m_buttonSize.height(), winicon ); + if( widget() ) + { + QPixmap winicon( widget()->windowIcon().pixmap( m_buttonSize ) ); + p.drawPixmap( 3, 3, m_buttonSize.width(), m_buttonSize.height(), winicon ); + } } @@ -267,25 +270,31 @@ void SubWindow::adjustTitleBar() // we're keeping the restore button around if we open projects // from older versions that have saved minimized windows m_restoreBtn->setVisible( isMaximized() || isMinimized() ); - - // title QLabel adjustments - m_windowTitle->setAlignment( Qt::AlignHCenter ); - m_windowTitle->setFixedWidth( widget()->width() - ( menuButtonSpace + buttonBarWidth ) ); - m_windowTitle->move( menuButtonSpace, - ( m_titleBarHeight / 2 ) - ( m_windowTitle->sizeHint().height() / 2 ) - 1 ); - - // if minimized we can't use widget()->width(). We have to hard code the width, - // as the width of all minimized windows is the same. if( isMinimized() ) { m_restoreBtn->move( m_maximizeBtn->isHidden() ? middleButtonPos : leftButtonPos ); - m_windowTitle->setFixedWidth( 120 ); } - // truncate the label string if the window is to small. Adds "..." - elideText( m_windowTitle, widget()->windowTitle() ); - m_windowTitle->setTextInteractionFlags( Qt::NoTextInteraction ); - m_windowTitle->adjustSize(); + if( widget() ) + { + // title QLabel adjustments + m_windowTitle->setAlignment( Qt::AlignHCenter ); + m_windowTitle->setFixedWidth( widget()->width() - ( menuButtonSpace + buttonBarWidth ) ); + m_windowTitle->move( menuButtonSpace, + ( m_titleBarHeight / 2 ) - ( m_windowTitle->sizeHint().height() / 2 ) - 1 ); + + // if minimized we can't use widget()->width(). We have to hard code the width, + // as the width of all minimized windows is the same. + if( isMinimized() ) + { + m_windowTitle->setFixedWidth( 120 ); + } + + // truncate the label string if the window is to small. Adds "..." + elideText( m_windowTitle, widget()->windowTitle() ); + m_windowTitle->setTextInteractionFlags( Qt::NoTextInteraction ); + m_windowTitle->adjustSize(); + } } From ee18011dc73cc93504aa461937e81e3fa72c7968 Mon Sep 17 00:00:00 2001 From: DomClark Date: Fri, 13 Apr 2018 00:33:08 +0100 Subject: [PATCH 006/445] Fix toggling UI for non-embedded VST effects --- plugins/VstEffect/VstEffectControlDialog.cpp | 4 ++-- plugins/vst_base/RemoteVstPlugin.cpp | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/plugins/VstEffect/VstEffectControlDialog.cpp b/plugins/VstEffect/VstEffectControlDialog.cpp index ea2581349..ef033ddb1 100644 --- a/plugins/VstEffect/VstEffectControlDialog.cpp +++ b/plugins/VstEffect/VstEffectControlDialog.cpp @@ -82,8 +82,8 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) : connect( btn, SIGNAL( toggled( bool ) ), SLOT( togglePluginUI( bool ) ) ); } else { - connect( btn, SIGNAL( clicked( bool ) ), - SLOT( togglePluginUI( bool ) ) ); + connect( btn, SIGNAL( clicked() ), + m_plugin.data(), SLOT( toggleUI() ) ); } btn->setMinimumWidth( 78 ); diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 71ebf74c0..bca09b1a2 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -293,8 +293,8 @@ public: static DWORD WINAPI processingThread( LPVOID _param ); static bool setupMessageWindow(); static DWORD WINAPI guiEventLoop(); - static LRESULT CALLBACK messageWndProc( HWND hwnd, UINT uMsg, - WPARAM wParam, LPARAM lParam ); + static LRESULT CALLBACK wndProc( HWND hwnd, UINT uMsg, + WPARAM wParam, LPARAM lParam ); private: @@ -1884,8 +1884,6 @@ bool RemoteVstPlugin::setupMessageWindow() __MessageHwnd = CreateWindowEx( 0, "LVSL", "dummy", 0, 0, 0, 0, 0, NULL, NULL, hInst, NULL ); - SetWindowLongPtr( __MessageHwnd, GWLP_WNDPROC, - reinterpret_cast( RemoteVstPlugin::messageWndProc ) ); // install GUI update timer SetTimer( __MessageHwnd, 1000, 50, NULL ); @@ -1910,7 +1908,7 @@ DWORD WINAPI RemoteVstPlugin::guiEventLoop() -LRESULT CALLBACK RemoteVstPlugin::messageWndProc( HWND hwnd, UINT uMsg, +LRESULT CALLBACK RemoteVstPlugin::wndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { if( uMsg == WM_TIMER && __plugin->isInitialized() ) @@ -2004,7 +2002,7 @@ int main( int _argc, char * * _argv ) WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = DefWindowProc; + wc.lpfnWndProc = RemoteVstPlugin::wndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; From fcc883f8873974cdb8f3f09e715912a8ec039139 Mon Sep 17 00:00:00 2001 From: DomClark Date: Fri, 20 Apr 2018 21:57:55 +0100 Subject: [PATCH 007/445] Preserve VST GUI positions and keep them on top --- plugins/vst_base/RemoteVstPlugin.cpp | 41 ++++++++++++++++++++++------ plugins/vst_base/VstPlugin.cpp | 22 ++++++++++++++- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index bca09b1a2..4e8f34ac8 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -134,6 +134,8 @@ public: void init( const std::string & _plugin_file ); void initEditor(); + void showEditor(); + void hideEditor(); void destroyEditor(); virtual void process( const sampleFrame * _in, sampleFrame * _out ); @@ -507,27 +509,28 @@ bool RemoteVstPlugin::processMessage( const message & _m ) switch( _m.id ) { case IdShowUI: - initEditor(); + showEditor(); return true; case IdHideUI: - destroyEditor(); + hideEditor(); return true; case IdToggleUI: - if( m_window ) + if( m_window && IsWindowVisible( m_window ) ) { - destroyEditor(); + hideEditor(); } else { - initEditor(); + showEditor(); } return true; case IdIsUIVisible: + bool visible = m_window && IsWindowVisible( m_window ); sendMessage( message( IdIsUIVisible ) - .addInt( m_window ? 1 : 0 ) ); + .addInt( visible ? 1 : 0 ) ); return true; } } @@ -709,7 +712,7 @@ void RemoteVstPlugin::initEditor() dwStyle = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX; } - m_window = CreateWindowEx( 0, "LVSL", pluginName(), + m_window = CreateWindowEx( WS_EX_APPWINDOW, "LVSL", pluginName(), dwStyle, 0, 0, 10, 10, NULL, NULL, hInst, NULL ); if( m_window == NULL ) @@ -733,7 +736,7 @@ void RemoteVstPlugin::initEditor() pluginDispatch( effEditTop ); if (! EMBED) { - ShowWindow( m_window, SW_SHOWNORMAL ); + showEditor(); } #ifdef LMMS_BUILD_LINUX @@ -747,6 +750,26 @@ void RemoteVstPlugin::initEditor() +void RemoteVstPlugin::showEditor() { + if( !EMBED && !HEADLESS && m_window ) + { + ShowWindow( m_window, SW_SHOWNORMAL ); + } +} + + + + +void RemoteVstPlugin::hideEditor() { + if( !EMBED && !HEADLESS && m_window ) + { + ShowWindow( m_window, SW_HIDE ); + } +} + + + + void RemoteVstPlugin::destroyEditor() { if( m_window == NULL ) @@ -1947,7 +1970,7 @@ LRESULT CALLBACK RemoteVstPlugin::wndProc( HWND hwnd, UINT uMsg, } else if( uMsg == WM_SYSCOMMAND && wParam == SC_CLOSE ) { - __plugin->destroyEditor(); + __plugin->hideEditor(); return 0; } diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index d9d9cc9f7..26c789275 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -34,9 +34,9 @@ #include #ifdef LMMS_BUILD_LINUX +# include # if QT_VERSION < 0x050000 # include -# include # else # include "X11EmbedContainer.h" # include @@ -62,6 +62,10 @@ #include "templates.h" #include "FileDialog.h" +#ifdef LMMS_BUILD_LINUX +# include +#endif + VstPlugin::VstPlugin( const QString & _plugin ) : m_plugin( _plugin ), @@ -324,6 +328,22 @@ bool VstPlugin::processMessage( const message & _m ) case IdVstPluginWindowID: m_pluginWindowID = _m.getInt(); + if( m_embedMethod == "none" ) + { +#ifdef LMMS_BUILD_WIN32 + // We're changing the owner, not the parent, + // so this is legal despite MSDN's warning + SetWindowLongPtr( (HWND)(intptr_t) m_pluginWindowID, + GWLP_HWNDPARENT, + (LONG_PTR) gui->mainWindow()->winId() ); +#endif + +#ifdef LMMS_BUILD_LINUX + XSetTransientForHint( QX11Info::display(), + m_pluginWindowID, + gui->mainWindow()->winId() ); +#endif + } break; case IdVstPluginEditorGeometry: From 8e9f74df377dca8303d497e731065a3b05a82152 Mon Sep 17 00:00:00 2001 From: DomClark Date: Fri, 20 Apr 2018 22:03:11 +0100 Subject: [PATCH 008/445] Minor fixes From MSDN: "In WM_SYSCOMMAND messages, the four low-order bits of the wParam parameter are used internally by the system. To obtain the correct result when testing the value of wParam, an application must combine the value 0xFFF0 with the wParam value by using the bitwise AND operator." Also calculate the required window size using AdjustWindowRect, rather than hard-coding some constants. --- plugins/vst_base/RemoteVstPlugin.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 4e8f34ac8..a51ac9d9a 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -730,8 +730,10 @@ void RemoteVstPlugin::initEditor() m_windowWidth = er->right - er->left; m_windowHeight = er->bottom - er->top; - SetWindowPos( m_window, 0, 0, 0, m_windowWidth + 8, - m_windowHeight + 26, SWP_NOACTIVATE | + RECT windowSize = { 0, 0, m_windowWidth, m_windowHeight }; + AdjustWindowRect( &windowSize, dwStyle, false ); + SetWindowPos( m_window, 0, 0, 0, windowSize.right - windowSize.left, + windowSize.bottom - windowSize.top, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER ); pluginDispatch( effEditTop ); @@ -1968,7 +1970,7 @@ LRESULT CALLBACK RemoteVstPlugin::wndProc( HWND hwnd, UINT uMsg, break; } } - else if( uMsg == WM_SYSCOMMAND && wParam == SC_CLOSE ) + else if( uMsg == WM_SYSCOMMAND && (wParam & 0xfff0) == SC_CLOSE ) { __plugin->hideEditor(); return 0; From b8086319759dd40e2a957ca69998b73897b48132 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 29 Apr 2018 08:02:25 +0200 Subject: [PATCH 009/445] VST: Add workaround for small effect window on project load --- plugins/VstEffect/VstEffectControlDialog.cpp | 12 +++++++++++- plugins/VstEffect/VstEffectControlDialog.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/plugins/VstEffect/VstEffectControlDialog.cpp b/plugins/VstEffect/VstEffectControlDialog.cpp index ef033ddb1..8445e97cc 100644 --- a/plugins/VstEffect/VstEffectControlDialog.cpp +++ b/plugins/VstEffect/VstEffectControlDialog.cpp @@ -41,7 +41,6 @@ #include #include - VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) : EffectControlDialog( _ctl ), m_pluginWidget( NULL ), @@ -274,6 +273,17 @@ void VstEffectControlDialog::paintEvent( QPaintEvent * ) } } +void VstEffectControlDialog::showEvent(QShowEvent *_se) +{ + EffectControlDialog::showEvent( _se ); + // Workaround for a (unexplained) bug where on project-load the effect + // control window has size 0 and would only restore to the proper size upon + // moving the window or interacting with it. + if (parentWidget()) { + parentWidget()->adjustSize(); + } +} + diff --git a/plugins/VstEffect/VstEffectControlDialog.h b/plugins/VstEffect/VstEffectControlDialog.h index e20915019..3cd9af360 100644 --- a/plugins/VstEffect/VstEffectControlDialog.h +++ b/plugins/VstEffect/VstEffectControlDialog.h @@ -50,6 +50,7 @@ public: protected: virtual void paintEvent( QPaintEvent * _pe ); + virtual void showEvent( QShowEvent* _se ) override; private: QWidget * m_pluginWidget; From 55d3fbc9085c19a0ca4976328358a03ebb886da9 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Sun, 20 May 2018 15:40:36 +0900 Subject: [PATCH 010/445] Fix RemoteVstPlugin not exiting when effect removed --- plugins/VstEffect/VstEffectControlDialog.cpp | 7 ++++++- src/gui/widgets/EffectView.cpp | 11 ----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/plugins/VstEffect/VstEffectControlDialog.cpp b/plugins/VstEffect/VstEffectControlDialog.cpp index 8445e97cc..14866ec56 100644 --- a/plugins/VstEffect/VstEffectControlDialog.cpp +++ b/plugins/VstEffect/VstEffectControlDialog.cpp @@ -289,7 +289,12 @@ void VstEffectControlDialog::showEvent(QShowEvent *_se) VstEffectControlDialog::~VstEffectControlDialog() { - //delete m_pluginWidget; +#if !(QT_VERSION < 0x050000 && defined(LMMS_BUILD_LINUX)) + if (m_pluginWidget && layout()) { + layout()->removeWidget(m_pluginWidget); + m_pluginWidget->setParent(nullptr); + } +#endif } diff --git a/src/gui/widgets/EffectView.cpp b/src/gui/widgets/EffectView.cpp index 5faae3517..6c74a459c 100644 --- a/src/gui/widgets/EffectView.cpp +++ b/src/gui/widgets/EffectView.cpp @@ -164,18 +164,7 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) : EffectView::~EffectView() { - -#ifdef LMMS_BUILD_LINUX - delete m_subWindow; -#else - if( m_subWindow ) - { - // otherwise on win32 build VST GUI can get lost - m_subWindow->hide(); - } -#endif - } From 235e8eef6fef278dee2dbe0869256aa915afb068 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Sun, 20 May 2018 15:45:50 +0900 Subject: [PATCH 011/445] Allow controlling VST effects without own GUI --- plugins/VstEffect/VstEffectControlDialog.cpp | 8 ++++---- plugins/VstEffect/VstEffectControls.cpp | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/plugins/VstEffect/VstEffectControlDialog.cpp b/plugins/VstEffect/VstEffectControlDialog.cpp index 14866ec56..84548bfde 100644 --- a/plugins/VstEffect/VstEffectControlDialog.cpp +++ b/plugins/VstEffect/VstEffectControlDialog.cpp @@ -62,14 +62,14 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) : embed_vst = m_plugin->embedMethod() != "none"; if (embed_vst) { - if (! m_plugin->pluginWidget()) { + if (m_plugin->hasEditor() && ! m_plugin->pluginWidget()) { m_plugin->createUI(this); } m_pluginWidget = m_plugin->pluginWidget(); } } - if ( m_plugin && (!embed_vst || m_pluginWidget) ) + if (m_plugin) { setWindowTitle( m_plugin->name() ); @@ -218,7 +218,7 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) : int newSize = 0; - if (embed_vst) { + if (m_pluginWidget) { newSize = m_pluginWidget->width() + 20; } newSize = std::max(newSize, 250); @@ -234,7 +234,7 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) : l->addItem( new QSpacerItem( newSize - 20, 30, QSizePolicy::Fixed, QSizePolicy::Fixed ), 1, 0 ); l->addWidget( resize, 2, 0, 1, 1, Qt::AlignCenter ); - if (embed_vst) { + if (m_pluginWidget) { l->addWidget( m_pluginWidget, 3, 0, 1, 1, Qt::AlignCenter ); } l->setRowStretch( 5, 1 ); diff --git a/plugins/VstEffect/VstEffectControls.cpp b/plugins/VstEffect/VstEffectControls.cpp index ef5a59463..4e5aa1a5c 100644 --- a/plugins/VstEffect/VstEffectControls.cpp +++ b/plugins/VstEffect/VstEffectControls.cpp @@ -141,8 +141,7 @@ void VstEffectControls::saveSettings( QDomDocument & _doc, QDomElement & _this ) int VstEffectControls::controlCount() { - return m_effect->m_plugin != NULL && - m_effect->m_plugin->hasEditor() ? 1 : 0; + return m_effect->m_plugin != NULL ? 1 : 0; } From 24ae559de55bf09d3caf2d5594dcfec8a679e67b Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Wed, 23 May 2018 20:24:12 +0900 Subject: [PATCH 012/445] Fix crash when re-opening VST effect manage dialog Unset Qt::WA_DeleteOnClose for the dialog to avoid deletion when closed --- plugins/VstEffect/VstEffectControls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/VstEffect/VstEffectControls.cpp b/plugins/VstEffect/VstEffectControls.cpp index 4e5aa1a5c..21d940ddc 100644 --- a/plugins/VstEffect/VstEffectControls.cpp +++ b/plugins/VstEffect/VstEffectControls.cpp @@ -317,7 +317,7 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls * m_vi->m_subWindow->setWidget(m_vi->m_scrollArea); m_vi->m_subWindow->setWindowTitle( _eff->m_plugin->name() + tr( " - VST parameter control" ) ); m_vi->m_subWindow->setWindowIcon( PLUGIN_NAME::getIconPixmap( "logo" ) ); - //m_vi->m_subWindow->setAttribute(Qt::WA_DeleteOnClose); + m_vi->m_subWindow->setAttribute(Qt::WA_DeleteOnClose, false); l->setContentsMargins( 20, 10, 10, 10 ); From 75a65021004681402e9b4a03463eb19c18ecdab7 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Wed, 30 May 2018 19:14:06 +0900 Subject: [PATCH 013/445] Fix Mallets crash when STK rawwave files can't be loaded --- plugins/stk/mallets/mallets.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/stk/mallets/mallets.h b/plugins/stk/mallets/mallets.h index 649b8ff45..3928c531c 100644 --- a/plugins/stk/mallets/mallets.h +++ b/plugins/stk/mallets/mallets.h @@ -85,7 +85,7 @@ public: inline ~malletsSynth() { - m_voice->noteOff( 0.0 ); + if (m_voice) {m_voice->noteOff(0.0);} delete[] m_delay; delete m_voice; } From 1349d45d72d74b83d30cdf8a092b51e2e1b73afe Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Fri, 1 Jun 2018 09:04:01 +0900 Subject: [PATCH 014/445] Bump version to 1.2.0-rc6 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f269ee64..da5be324a 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 "rc5") +SET(VERSION_STAGE "rc6") SET(VERSION_BUILD "0") SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE}") IF(VERSION_STAGE) From d3c90a81b916ae6f7a49bf402ce3271d06f41e22 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Fri, 1 Jun 2018 13:53:14 +0200 Subject: [PATCH 015/445] Fix automation processing priority Fixes regression from 75077f6200a5aee3a5821aae48a3b8466ed8714a that caused global automation tracks to have priority in processing. Adds a test checking for the desired behaviour. Fixes #4268 --- src/core/Song.cpp | 2 +- tests/src/tracks/AutomationTrackTest.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 5f8e75320..9936585ab 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -816,7 +816,7 @@ AutomationPattern * Song::tempoAutomationPattern() AutomatedValueMap Song::automatedValuesAt(MidiTime time, int tcoNum) const { - return TrackContainer::automatedValuesFromTracks(TrackList(tracks()) << m_globalAutomationTrack, time, tcoNum); + return TrackContainer::automatedValuesFromTracks(TrackList{m_globalAutomationTrack} << tracks(), time, tcoNum); } diff --git a/tests/src/tracks/AutomationTrackTest.cpp b/tests/src/tracks/AutomationTrackTest.cpp index bd5257253..ef204963d 100644 --- a/tests/src/tracks/AutomationTrackTest.cpp +++ b/tests/src/tracks/AutomationTrackTest.cpp @@ -195,6 +195,30 @@ private slots: QCOMPARE(song->automatedValuesAt(5)[&model], 0.5f); QCOMPARE(song->automatedValuesAt(MidiTime::ticksPerTact() + 5)[&model], 0.5f); } + + void testGlobalAutomation() + { + // Global automation should not have priority, see https://github.com/LMMS/lmms/issues/4268 + // Tests regression caused by 75077f6200a5aee3a5821aae48a3b8466ed8714a + auto song = Engine::getSong(); + + auto globalTrack = song->globalAutomationTrack(); + AutomationPattern globalPattern(globalTrack); + + AutomationTrack localTrack(song); + AutomationPattern localPattern(&localTrack); + + FloatModel model; + globalPattern.setProgressionType(AutomationPattern::DiscreteProgression); + localPattern.setProgressionType(AutomationPattern::DiscreteProgression); + globalPattern.addObject(&model); + localPattern.addObject(&model); + globalPattern.putValue(0, 100.0f, false); + localPattern.putValue(0, 50.0f, false); + + QCOMPARE(song->automatedValuesAt(0)[&model], 50.0f); + } + } AutomationTrackTest; #include "AutomationTrackTest.moc" From 0d7ea273dc782ed6146891d77f55e6096f7a008e Mon Sep 17 00:00:00 2001 From: Douglas <34612565+DouglasDGI@users.noreply.github.com> Date: Fri, 1 Jun 2018 21:41:52 -0600 Subject: [PATCH 016/445] Initialize peak controller last sample with base value (#4382) * Bug fix in peak_controller_effect.cpp This change makes it so that when an LMMS project is loaded, each knob connected to a Peak Controller will be set to the Peak Controller's Base value, rather than its minimum possible value. --- plugins/peak_controller_effect/peak_controller_effect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/peak_controller_effect/peak_controller_effect.cpp b/plugins/peak_controller_effect/peak_controller_effect.cpp index d4d81b137..87f6cc600 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( 0 ), + 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_autoController( NULL ) { m_autoController = new PeakController( Engine::getSong(), this ); From a9b5b92a2b39b4062f08c00812792d28e2ae770e Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Sun, 3 Jun 2018 21:35:36 +0900 Subject: [PATCH 017/445] Deselect FX channel's name text when losing focus (#4293) --- src/gui/widgets/FxLine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/widgets/FxLine.cpp b/src/gui/widgets/FxLine.cpp index c6e6fd9ae..6cb6363c3 100644 --- a/src/gui/widgets/FxLine.cpp +++ b/src/gui/widgets/FxLine.cpp @@ -262,6 +262,7 @@ void FxLine::renameChannel() void FxLine::renameFinished() { m_inRename = false; + m_renameLineEdit->deselect(); m_renameLineEdit->setReadOnly( true ); m_renameLineEdit->setFixedWidth( 65 ); m_lcd->show(); From 3bf3fab0e33b7bb199b2c4b32b1ccd0e1da096ca Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Sun, 3 Jun 2018 22:12:28 +0900 Subject: [PATCH 018/445] Piano roll: Fix some crashes when no pattern is open (#4392) --- src/gui/editors/PianoRoll.cpp | 39 +++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 888425ddc..486a2e826 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -949,6 +949,8 @@ void PianoRoll::clearSelectedNotes() void PianoRoll::shiftSemiTone( int amount ) // shift notes by amount semitones { + if (!hasValidPattern()) {return;} + bool useAllNotes = ! isSelection(); for( Note *note : m_pattern->notes() ) { @@ -973,6 +975,8 @@ void PianoRoll::shiftSemiTone( int amount ) // shift notes by amount semitones void PianoRoll::shiftPos( int amount ) //shift notes pos by amount { + if (!hasValidPattern()) {return;} + bool useAllNotes = ! isSelection(); bool first = true; @@ -1063,12 +1067,18 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke ) { // shift selection up an octave // if nothing selected, shift _everything_ - shiftSemiTone( 12 * direction ); + if (hasValidPattern()) + { + shiftSemiTone( 12 * direction ); + } } else if((ke->modifiers() & Qt::ShiftModifier) && m_action == ActionNone) { // Move selected notes up by one semitone - shiftSemiTone( 1 * direction ); + if (hasValidPattern()) + { + shiftSemiTone( 1 * direction ); + } } else { @@ -1098,22 +1108,32 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke ) if( ke->modifiers() & Qt::ControlModifier && m_action == ActionNone ) { // Move selected notes by one bar to the left - shiftPos( direction * MidiTime::ticksPerTact() ); + if (hasValidPattern()) + { + shiftPos( direction * MidiTime::ticksPerTact() ); + } } else if( ke->modifiers() & Qt::ShiftModifier && m_action == ActionNone) { // move notes - bool quantized = ! ( ke->modifiers() & Qt::AltModifier ); - int amt = quantized ? quantization() : 1; - shiftPos( direction * amt ); + if (hasValidPattern()) + { + bool quantized = ! ( ke->modifiers() & Qt::AltModifier ); + int amt = quantized ? quantization() : 1; + shiftPos( direction * amt ); + } } else if( ke->modifiers() & Qt::AltModifier) { // switch to editing a pattern adjacent to this one in the song editor - Pattern * p = direction > 0 ? m_pattern->nextPattern() : m_pattern->previousPattern(); - if(p != NULL) + if (hasValidPattern()) { - setCurrentPattern(p); + Pattern * p = direction > 0 ? m_pattern->nextPattern() + : m_pattern->previousPattern(); + if(p != NULL) + { + setCurrentPattern(p); + } } } else @@ -3188,6 +3208,7 @@ void PianoRoll::wheelEvent(QWheelEvent * we ) if( we->x() > noteEditLeft() && we->x() < noteEditRight() && we->y() > noteEditTop() && we->y() < noteEditBottom() ) { + if (!hasValidPattern()) {return;} // get values for going through notes int pixel_range = 8; int x = we->x() - WHITE_KEY_WIDTH; From 2f19fa11c886374adcc74990e52d3ed0473fbf08 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 5 Jun 2018 17:39:04 +0900 Subject: [PATCH 019/445] Piano roll: reset editing mode when lost focus (#4393) --- src/gui/editors/PianoRoll.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 486a2e826..6950c0005 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -177,6 +177,7 @@ PianoRoll::PianoRoll() : m_startKey( INITIAL_START_KEY ), m_lastKey( 0 ), m_editMode( ModeDraw ), + m_ctrlMode( ModeDraw ), m_mouseDownRight( false ), m_scrollBack( false ), m_barLineColor( 0, 0, 0 ), @@ -3343,8 +3344,9 @@ void PianoRoll::focusOutEvent( QFocusEvent * ) m_pattern->instrumentTrack()->pianoModel()->midiEventProcessor()->processInEvent( MidiEvent( MidiNoteOff, -1, i, 0 ) ); m_pattern->instrumentTrack()->pianoModel()->setKeyState( i, false ); } - update(); } + m_editMode = m_ctrlMode; + update(); } @@ -3552,7 +3554,7 @@ void PianoRoll::verScrolled( int new_pos ) void PianoRoll::setEditMode(int mode) { - m_editMode = (EditModes) mode; + m_ctrlMode = m_editMode = (EditModes) mode; } From 407973ad6f304c9af07dd50fa94fe498df188896 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 13 Jun 2018 14:50:27 +0900 Subject: [PATCH 020/445] Fix crash when loading project with missing peak controller effect (#4391) * Fix crash when loading project with missing peak controller effect * Don't load/save dummy controller connections --- src/core/AutomatableModel.cpp | 3 ++- src/core/ControllerConnection.cpp | 7 ++++++- src/core/Song.cpp | 15 ++++++++++++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index e2a088e04..0b2a1522b 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -110,7 +110,8 @@ void AutomatableModel::saveSettings( QDomDocument& doc, QDomElement& element, co element.setAttribute( name, m_value ); } - if( m_controllerConnection ) + if( m_controllerConnection && m_controllerConnection->getController()->type() + != Controller::DummyController ) { QDomElement controllerElement; diff --git a/src/core/ControllerConnection.cpp b/src/core/ControllerConnection.cpp index 280ed709c..4f04cbc20 100644 --- a/src/core/ControllerConnection.cpp +++ b/src/core/ControllerConnection.cpp @@ -162,6 +162,11 @@ void ControllerConnection::finalizeConnections() c->setController( Engine::getSong()-> controllers().at( c->m_controllerId ) ); } + else if (c->getController()->type() == Controller::DummyController) + { + delete c; + --i; + } } } @@ -199,7 +204,7 @@ void ControllerConnection::loadSettings( const QDomElement & _this ) } else { - if( _this.attribute( "id" ).toInt() >= 0 ) + if( _this.attribute( "id", "-1" ).toInt() >= 0 ) { m_controllerId = _this.attribute( "id" ).toInt(); } diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 9936585ab..be0c7dddc 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -1122,6 +1122,11 @@ void Song::loadProject( const QString & fileName ) // now that everything is loaded ControllerConnection::finalizeConnections(); + // Remove dummy controllers that was added for correct connections + m_controllers.erase(std::remove_if(m_controllers.begin(), m_controllers.end(), + [](Controller* c){return c->type() == Controller::DummyController;}), + m_controllers.end()); + // resolve all IDs so that autoModels are automated AutomationPattern::resolveAllIDs(); @@ -1289,9 +1294,13 @@ void Song::restoreControllerStates( const QDomElement & element ) while( !node.isNull() && !isCancelled() ) { Controller * c = Controller::create( node.toElement(), this ); - Q_ASSERT( c != NULL ); - - addController( c ); + if (c) {addController(c);} + else + { + // Fix indices to ensure correct connections + m_controllers.append(Controller::create( + Controller::DummyController, this)); + } node = node.nextSibling(); } From d11966a7eaf597750ac92fedd9bca060c37d8ec0 Mon Sep 17 00:00:00 2001 From: dobbelaj Date: Sun, 17 Jun 2018 11:20:00 +0200 Subject: [PATCH 021/445] Introduce UI_CTRL_KEY and use where appropriate (#4431) This is an abstraction for the name of the 'Ctrl' (or equivalent) key on linux, windows and apple --- include/lmms_basics.h | 6 ++ src/core/AutomationPattern.cpp | 7 +-- src/core/Track.cpp | 21 +------ src/gui/TimeLineWidget.cpp | 14 +---- src/gui/editors/AutomationEditor.cpp | 21 +------ src/gui/editors/PianoRoll.cpp | 21 +------ src/gui/widgets/ProjectNotes.cpp | 84 ++++------------------------ src/tracks/SampleTrack.cpp | 7 +-- 8 files changed, 31 insertions(+), 150 deletions(-) diff --git a/include/lmms_basics.h b/include/lmms_basics.h index 637867b4d..cca04e97d 100644 --- a/include/lmms_basics.h +++ b/include/lmms_basics.h @@ -141,5 +141,11 @@ typedef sample_t sampleFrameA[DEFAULT_CHANNELS] __attribute__((__aligned__(ALIGN #define STRINGIFY(s) STR(s) #define STR(PN) #PN +// Abstract away GUI CTRL key (linux/windows) vs ⌘ (apple) +#ifdef LMMS_BUILD_APPLE +# define UI_CTRL_KEY "⌘" +#else +# define UI_CTRL_KEY "Ctrl" +#endif #endif diff --git a/src/core/AutomationPattern.cpp b/src/core/AutomationPattern.cpp index 9345ad566..ab74c6eab 100644 --- a/src/core/AutomationPattern.cpp +++ b/src/core/AutomationPattern.cpp @@ -619,12 +619,7 @@ const QString AutomationPattern::name() const { return m_objects.first()->fullDisplayName(); } - return tr( "Drag a control while pressing <%1>" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘"); - #else - "Ctrl"); - #endif + return tr( "Drag a control while pressing <%1>" ).arg(UI_CTRL_KEY); } diff --git a/src/core/Track.cpp b/src/core/Track.cpp index e11529249..2a59334aa 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -791,12 +791,7 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) QString hint = m_action == Move || m_action == MoveSelection ? tr( "Press <%1> and drag to make a copy." ) : tr( "Press <%1> for free resizing." ); - m_hint = TextFloat::displayMessage( tr( "Hint" ), hint.arg( - #ifdef LMMS_BUILD_APPLE - "⌘"), - #else - "Ctrl"), - #endif + m_hint = TextFloat::displayMessage( tr( "Hint" ), hint.arg(UI_CTRL_KEY), embed::getIconPixmap( "hint" ), 0 ); } } @@ -1093,12 +1088,7 @@ void TrackContentObjectView::contextMenuEvent( QContextMenuEvent * cme ) tr( "Paste" ), m_tco, SLOT( paste() ) ); contextMenu.addSeparator(); contextMenu.addAction( embed::getIconPixmap( "muted" ), - tr( "Mute/unmute (<%1> + middle click)" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘"), - #else - "Ctrl"), - #endif + tr( "Mute/unmute (<%1> + middle click)" ).arg(UI_CTRL_KEY), m_tco, SLOT( toggleMute() ) ); constructContextMenu( &contextMenu ); @@ -1734,12 +1724,7 @@ TrackOperationsWidget::TrackOperationsWidget( TrackView * parent ) : m_trackView( parent ) /*!< The parent track view */ { ToolTip::add( this, tr( "Press <%1> while clicking on move-grip " - "to begin a new drag'n'drop action." ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘") ); - #else - "Ctrl") ); - #endif + "to begin a new drag'n'drop action." ).arg(UI_CTRL_KEY) ); QMenu * toMenu = new QMenu( this ); toMenu->setFont( pointSize<9>( toMenu->font() ) ); diff --git a/src/gui/TimeLineWidget.cpp b/src/gui/TimeLineWidget.cpp index ccf32add1..5c91cfcf8 100644 --- a/src/gui/TimeLineWidget.cpp +++ b/src/gui/TimeLineWidget.cpp @@ -337,24 +337,14 @@ void TimeLineWidget::mousePressEvent( QMouseEvent* event ) { delete m_hint; m_hint = TextFloat::displayMessage( tr( "Hint" ), - tr( "Press <%1> to disable magnetic loop points." ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘"), - #else - "Ctrl"), - #endif + tr( "Press <%1> to disable magnetic loop points." ).arg(UI_CTRL_KEY), embed::getIconPixmap( "hint" ), 0 ); } else if( m_action == MoveLoopEnd ) { delete m_hint; m_hint = TextFloat::displayMessage( tr( "Hint" ), - tr( "Hold to move the begin loop point; Press <%1> to disable magnetic loop points." ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘"), - #else - "Ctrl"), - #endif + tr( "Hold to move the begin loop point; Press <%1> to disable magnetic loop points." ).arg(UI_CTRL_KEY), embed::getIconPixmap( "hint" ), 0 ); } diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 890bb2346..e00c107d1 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -2294,26 +2294,11 @@ AutomationEditorWindow::AutomationEditorWindow() : /*DropToolBar *copyPasteActionsToolBar = addDropToolBarToTop(tr("Copy paste actions"));*/ QAction* cutAction = new QAction(embed::getIconPixmap("edit_cut"), - tr("Cut selected values (%1+X)").arg( - #ifdef LMMS_BUILD_APPLE - "⌘"), this); - #else - "Ctrl"), this); - #endif + tr("Cut selected values (%1+X)").arg(UI_CTRL_KEY), this); QAction* copyAction = new QAction(embed::getIconPixmap("edit_copy"), - tr("Copy selected values (%1+C)").arg( - #ifdef LMMS_BUILD_APPLE - "⌘"), this); - #else - "Ctrl"), this); - #endif + tr("Copy selected values (%1+C)").arg(UI_CTRL_KEY), this); QAction* pasteAction = new QAction(embed::getIconPixmap("edit_paste"), - tr("Paste values from clipboard (%1+V)").arg( - #ifdef LMMS_BUILD_APPLE - "⌘"), this); - #else - "Ctrl"), this); - #endif + tr("Paste values from clipboard (%1+V)").arg(UI_CTRL_KEY), this); cutAction->setShortcut(Qt::CTRL | Qt::Key_X); copyAction->setShortcut(Qt::CTRL | Qt::Key_C); diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 1060574c9..1ec23724c 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -4090,28 +4090,13 @@ PianoRollWindow::PianoRollWindow() : DropToolBar *copyPasteActionsToolBar = addDropToolBarToTop( tr( "Copy paste controls" ) ); QAction* cutAction = new QAction(embed::getIconPixmap( "edit_cut" ), - tr( "Cut (%1+X)" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘" ), this ); - #else - "Ctrl" ), this ); - #endif + tr( "Cut (%1+X)" ).arg(UI_CTRL_KEY), this ); QAction* copyAction = new QAction(embed::getIconPixmap( "edit_copy" ), - tr( "Copy (%1+C)" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘"), this); - #else - "Ctrl" ), this ); - #endif + tr( "Copy (%1+C)" ).arg(UI_CTRL_KEY), this ); QAction* pasteAction = new QAction(embed::getIconPixmap( "edit_paste" ), - tr( "Paste (%1+V)" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘" ), this ); - #else - "Ctrl" ), this ); - #endif + tr( "Paste (%1+V)" ).arg(UI_CTRL_KEY), this ); cutAction->setShortcut( Qt::CTRL | Qt::Key_X ); copyAction->setShortcut( Qt::CTRL | Qt::Key_C ); diff --git a/src/gui/widgets/ProjectNotes.cpp b/src/gui/widgets/ProjectNotes.cpp index d8d6636c4..7fc35b446 100644 --- a/src/gui/widgets/ProjectNotes.cpp +++ b/src/gui/widgets/ProjectNotes.cpp @@ -115,56 +115,31 @@ void ProjectNotes::setupActions() a = new QAction( embed::getIconPixmap( "edit_undo" ), tr( "&Undo" ), this ); - a->setShortcut( tr( "%1+Z" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘") ); - #else - "Ctrl") ); - #endif + a->setShortcut( tr( "%1+Z" ).arg(UI_CTRL_KEY) ); connect( a, SIGNAL( triggered() ), m_edit, SLOT( undo() ) ); tb->addAction( a ); a = new QAction( embed::getIconPixmap( "edit_redo" ), tr( "&Redo" ), this ); - a->setShortcut( tr( "%1+Y" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘") ); - #else - "Ctrl") ); - #endif + a->setShortcut( tr( "%1+Y" ).arg(UI_CTRL_KEY) ); connect( a, SIGNAL( triggered() ), m_edit, SLOT( redo() ) ); tb->addAction( a ); a = new QAction( embed::getIconPixmap( "edit_copy" ), tr( "&Copy" ), this ); - a->setShortcut( tr( "%1+C" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘") ); - #else - "Ctrl") ); - #endif + a->setShortcut( tr( "%1+C" ).arg(UI_CTRL_KEY) ); connect( a, SIGNAL( triggered() ), m_edit, SLOT( copy() ) ); tb->addAction( a ); a = new QAction( embed::getIconPixmap( "edit_cut" ), tr( "Cu&t" ), this ); - a->setShortcut( tr( "%1+X" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘") ); - #else - "Ctrl") ); - #endif + a->setShortcut( tr( "%1+X" ).arg(UI_CTRL_KEY) ); connect( a, SIGNAL( triggered() ), m_edit, SLOT( cut() ) ); tb->addAction( a ); a = new QAction( embed::getIconPixmap( "edit_paste" ), tr( "&Paste" ), this ); - a->setShortcut( tr( "%1+V" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘") ); - #else - "Ctrl") ); - #endif + a->setShortcut( tr( "%1+V" ).arg(UI_CTRL_KEY) ); connect( a, SIGNAL( triggered() ), m_edit, SLOT( paste() ) ); tb->addAction( a ); @@ -194,24 +169,14 @@ void ProjectNotes::setupActions() m_actionTextBold = new QAction( embed::getIconPixmap( "text_bold" ), tr( "&Bold" ), this ); - m_actionTextBold->setShortcut( tr( "%1+B" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘") ); - #else - "Ctrl") ); - #endif + m_actionTextBold->setShortcut( tr( "%1+B" ).arg(UI_CTRL_KEY) ); m_actionTextBold->setCheckable( true ); connect( m_actionTextBold, SIGNAL( triggered() ), this, SLOT( textBold() ) ); m_actionTextItalic = new QAction( embed::getIconPixmap( "text_italic" ), tr( "&Italic" ), this ); - m_actionTextItalic->setShortcut( tr( "%1+I" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘") ); - #else - "Ctrl") ); - #endif + m_actionTextItalic->setShortcut( tr( "%1+I" ).arg(UI_CTRL_KEY) ); m_actionTextItalic->setCheckable( true ); connect( m_actionTextItalic, SIGNAL( triggered() ), this, SLOT( textItalic() ) ); @@ -219,12 +184,7 @@ void ProjectNotes::setupActions() m_actionTextUnderline = new QAction( embed::getIconPixmap( "text_under" ), tr( "&Underline" ), this ); - m_actionTextUnderline->setShortcut( tr( "%1+U" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘") ); - #else - "Ctrl") ); - #endif + m_actionTextUnderline->setShortcut( tr( "%1+U" ).arg(UI_CTRL_KEY) ); m_actionTextUnderline->setCheckable( true ); connect( m_actionTextUnderline, SIGNAL( triggered() ), this, SLOT( textUnderline() ) ); @@ -236,12 +196,7 @@ void ProjectNotes::setupActions() m_actionAlignLeft = new QAction( embed::getIconPixmap( "text_left" ), tr( "&Left" ), m_edit ); - m_actionAlignLeft->setShortcut( tr( "%1+L" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘") ); - #else - "Ctrl") ); - #endif + m_actionAlignLeft->setShortcut( tr( "%1+L" ).arg(UI_CTRL_KEY) ); m_actionAlignLeft->setCheckable( true ); grp->addAction( m_actionAlignLeft ); @@ -249,36 +204,21 @@ void ProjectNotes::setupActions() "text_center" ), tr( "C&enter" ), m_edit ); m_actionAlignCenter->setShortcutContext( Qt::WidgetShortcut ); - m_actionAlignCenter->setShortcut( tr( "%1+E" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘") ); - #else - "Ctrl") ); - #endif + m_actionAlignCenter->setShortcut( tr( "%1+E" ).arg(UI_CTRL_KEY) ); m_actionAlignCenter->setCheckable( true ); grp->addAction( m_actionAlignCenter ); m_actionAlignRight = new QAction( embed::getIconPixmap( "text_right" ), tr( "&Right" ), m_edit ); m_actionAlignRight->setShortcutContext( Qt::WidgetShortcut ); - m_actionAlignRight->setShortcut( tr( "%1+R" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘") ); - #else - "Ctrl") ); - #endif + m_actionAlignRight->setShortcut( tr( "%1+R" ).arg(UI_CTRL_KEY) ); m_actionAlignRight->setCheckable( true ); grp->addAction( m_actionAlignRight ); m_actionAlignJustify = new QAction( embed::getIconPixmap( "text_block" ), tr( "&Justify" ), m_edit ); - m_actionAlignJustify->setShortcut( tr( "%1+J" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘") ); - #else - "Ctrl") ); - #endif + m_actionAlignJustify->setShortcut( tr( "%1+J" ).arg(UI_CTRL_KEY) ); m_actionAlignJustify->setCheckable( true ); grp->addAction( m_actionAlignJustify ); diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 3315ccb55..bd70a3a08 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -338,12 +338,7 @@ void SampleTCOView::contextMenuEvent( QContextMenuEvent * _cme ) tr( "Paste" ), m_tco, SLOT( paste() ) ); contextMenu.addSeparator(); contextMenu.addAction( embed::getIconPixmap( "muted" ), - tr( "Mute/unmute (<%1> + middle click)" ).arg( - #ifdef LMMS_BUILD_APPLE - "⌘"), - #else - "Ctrl"), - #endif + tr( "Mute/unmute (<%1> + middle click)" ).arg(UI_CTRL_KEY), m_tco, SLOT( toggleMute() ) ); /*contextMenu.addAction( embed::getIconPixmap( "record" ), tr( "Set/clear record" ), From da1c78ce8639874f9749035e17999857c2157207 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sat, 28 Apr 2018 12:04:44 +0200 Subject: [PATCH 022/445] Remove Qt4 compatibility code --- cmake/toolchains/common/MSYS.cmake | 16 +------------- include/MainApplication.h | 6 +----- plugins/GigPlayer/PatchesDialog.cpp | 4 ---- plugins/VstEffect/VstEffectControlDialog.cpp | 2 +- plugins/lb302/lb302.cpp | 12 ----------- plugins/sf2_player/patches_dialog.cpp | 4 ---- plugins/vst_base/VstPlugin.cpp | 11 ++-------- plugins/zynaddsubfx/CMakeLists.txt | 5 ----- src/CMakeLists.txt | 5 ----- src/core/ConfigManager.cpp | 13 ------------ src/core/main.cpp | 22 ++++++-------------- src/gui/EffectSelectDialog.cpp | 12 +++-------- src/gui/FileBrowser.cpp | 2 -- src/gui/LmmsStyle.cpp | 4 ---- src/gui/MainApplication.cpp | 4 +--- src/gui/MainWindow.cpp | 8 +++---- src/gui/SetupDialog.cpp | 4 ---- src/gui/TimeLineWidget.cpp | 5 ----- src/gui/dialogs/FileDialog.cpp | 14 +------------ src/gui/editors/PianoRoll.cpp | 4 ---- 20 files changed, 20 insertions(+), 137 deletions(-) diff --git a/cmake/toolchains/common/MSYS.cmake b/cmake/toolchains/common/MSYS.cmake index dc295d670..3a58bf8ff 100644 --- a/cmake/toolchains/common/MSYS.cmake +++ b/cmake/toolchains/common/MSYS.cmake @@ -20,18 +20,4 @@ ENDIF() SET(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES OFF) SET(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES OFF) -# Variable to assist override Qt debug libraries with release versions -SET(QT_OVERRIDE_LIBRARIES - optimized;${MINGW_PREFIX}/bin/QtGui4.dll; - optimized;${MINGW_PREFIX}/bin/QtCore4.dll; - optimized;${MINGW_PREFIX}/bin/QtXml4.dll; - debug;${MINGW_PREFIX}/bin/QtGui4.dll; - debug;${MINGW_PREFIX}/bin/QtCore4.dll; - debug;${MINGW_PREFIX}/bin/QtXml4.dll; -) -IF(LMMS_BUILD_MSYS AND CMAKE_BUILD_TYPE STREQUAL "Debug") - # Override Qt debug libraries with release versions - SET(QT_LIBRARIES "${QT_OVERRIDE_LIBRARIES}") -ENDIF() - -SET(LMMS_BUILD_MSYS 1) \ No newline at end of file +SET(LMMS_BUILD_MSYS 1) diff --git a/include/MainApplication.h b/include/MainApplication.h index d3acb95ca..bd1974a3a 100644 --- a/include/MainApplication.h +++ b/include/MainApplication.h @@ -31,12 +31,10 @@ #ifdef LMMS_BUILD_WIN32 #include -#if QT_VERSION >= 0x050000 #include #endif -#endif -#if defined(LMMS_BUILD_WIN32) && QT_VERSION >= 0x050000 +#if defined(LMMS_BUILD_WIN32) class MainApplication : public QApplication, public QAbstractNativeEventFilter #else class MainApplication : public QApplication @@ -47,10 +45,8 @@ public: bool event(QEvent* event); #ifdef LMMS_BUILD_WIN32 bool winEventFilter(MSG* msg, long* result); -#if QT_VERSION >= 0x050000 bool nativeEventFilter(const QByteArray& eventType, void* message, long* result); -#endif #endif inline QString& queuedFile() { diff --git a/plugins/GigPlayer/PatchesDialog.cpp b/plugins/GigPlayer/PatchesDialog.cpp index ac7c4d330..7be3bfd98 100644 --- a/plugins/GigPlayer/PatchesDialog.cpp +++ b/plugins/GigPlayer/PatchesDialog.cpp @@ -74,11 +74,7 @@ PatchesDialog::PatchesDialog( QWidget * pParent, Qt::WindowFlags wflags ) // Soundfonts list view... QHeaderView * pHeader = m_progListView->header(); pHeader->setDefaultAlignment( Qt::AlignLeft ); -#if QT_VERSION >= 0x050000 pHeader->setSectionsMovable( false ); -#else - pHeader->setMovable( false ); -#endif pHeader->setStretchLastSection( true ); m_progListView->resizeColumnToContents( 0 ); // Prog. diff --git a/plugins/VstEffect/VstEffectControlDialog.cpp b/plugins/VstEffect/VstEffectControlDialog.cpp index 797818979..3435cefb3 100644 --- a/plugins/VstEffect/VstEffectControlDialog.cpp +++ b/plugins/VstEffect/VstEffectControlDialog.cpp @@ -272,7 +272,7 @@ void VstEffectControlDialog::showEvent(QShowEvent *_se) VstEffectControlDialog::~VstEffectControlDialog() { -#if !(QT_VERSION < 0x050000 && defined(LMMS_BUILD_LINUX)) +#ifndef LMMS_BUILD_LINUX if (m_pluginWidget && layout()) { layout()->removeWidget(m_pluginWidget); m_pluginWidget->setParent(nullptr); diff --git a/plugins/lb302/lb302.cpp b/plugins/lb302/lb302.cpp index 66b77ac35..b0ea91776 100644 --- a/plugins/lb302/lb302.cpp +++ b/plugins/lb302/lb302.cpp @@ -434,11 +434,7 @@ QString lb302Synth::nodeName() const // OBSOLETE. Break apart once we get Q_OBJECT to work. >:[ void lb302Synth::recalcFilter() { -#if QT_VERSION >= 0x050000 vcf.load()->recalc(); -#else - vcf->recalc(); -#endif // THIS IS OLD 3pole/24dB code, I may reintegrate it. Don't need it // right now. Should be toggled by LB_24_RES_TRICK at the moment. @@ -464,11 +460,7 @@ int lb302Synth::process(sampleFrame *outbuf, const int size) float samp; // Hold on to the current VCF, and use it throughout this period -#if QT_VERSION >= 0x050000 lb302Filter *filter = vcf.loadAcquire(); -#else - lb302Filter *filter = vcf; -#endif if( release_frame == 0 || ! m_playingNote ) { @@ -692,11 +684,7 @@ void lb302Synth::initNote( lb302Note *n) if(n->dead ==0){ // Swap next two blocks?? -#if QT_VERSION >= 0x050000 vcf.load()->playNote(); -#else - vcf->playNote(); -#endif // Ensure envelope is recalculated vcf_envpos = ENVINC; diff --git a/plugins/sf2_player/patches_dialog.cpp b/plugins/sf2_player/patches_dialog.cpp index 6ae791c15..bb8801f49 100644 --- a/plugins/sf2_player/patches_dialog.cpp +++ b/plugins/sf2_player/patches_dialog.cpp @@ -75,11 +75,7 @@ patchesDialog::patchesDialog( QWidget *pParent, Qt::WindowFlags wflags ) // pHeader->setResizeMode(QHeaderView::Custom); pHeader->setDefaultAlignment(Qt::AlignLeft); // pHeader->setDefaultSectionSize(200); -#if QT_VERSION >= 0x050000 pHeader->setSectionsMovable(false); -#else - pHeader->setMovable(false); -#endif pHeader->setStretchLastSection(true); m_progListView->resizeColumnToContents(0); // Prog. diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 26c789275..792feef76 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -35,17 +35,10 @@ #ifdef LMMS_BUILD_LINUX # include -# if QT_VERSION < 0x050000 -# include -# else -# include "X11EmbedContainer.h" -# include -# endif +# include "X11EmbedContainer.h" #endif -#if QT_VERSION >= 0x050000 -# include -#endif +#include #include diff --git a/plugins/zynaddsubfx/CMakeLists.txt b/plugins/zynaddsubfx/CMakeLists.txt index ff9d7219d..bdc10bf32 100644 --- a/plugins/zynaddsubfx/CMakeLists.txt +++ b/plugins/zynaddsubfx/CMakeLists.txt @@ -122,11 +122,6 @@ ELSE() ENDIF() TARGET_LINK_LIBRARIES(ZynAddSubFxCore zynaddsubfx_nio ${FFTW3F_LIBRARIES} ${QT_LIBRARIES} -lz -lpthread) -# required libs for debug msys builds -IF(LMMS_BUILD_MSYS AND CMAKE_BUILD_TYPE STREQUAL "Debug") - TARGET_LINK_LIBRARIES(ZynAddSubFxCore QtCore4 QtGui4 QtXml4) -ENDIF() - TARGET_LINK_LIBRARIES(ZynAddSubFxCore Qt5::Widgets Qt5::Xml) IF(LMMS_BUILD_WIN32) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ff0ca8a8e..ca6f57cd4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -161,11 +161,6 @@ FOREACH(LIB ${LMMS_REQUIRED_LIBS}) ENDFOREACH() -# Required libs for debug msys builds -IF(LMMS_BUILD_MSYS AND CMAKE_BUILD_TYPE STREQUAL "Debug") - TARGET_LINK_LIBRARIES(lmms QtCore4 QtGui4 QtXml4) -ENDIF() - # Install IF(LMMS_BUILD_WIN32) SET_TARGET_PROPERTIES(lmms PROPERTIES diff --git a/src/core/ConfigManager.cpp b/src/core/ConfigManager.cpp index f52e10ac7..9d6781f7c 100644 --- a/src/core/ConfigManager.cpp +++ b/src/core/ConfigManager.cpp @@ -26,11 +26,7 @@ #include #include #include -#if QT_VERSION >= 0x050000 #include -#else -#include -#endif #include #include "ConfigManager.h" @@ -55,11 +51,7 @@ ConfigManager * ConfigManager::s_instanceOfMe = NULL; ConfigManager::ConfigManager() : m_lmmsRcFile( QDir::home().absolutePath() +"/.lmmsrc.xml" ), - #if QT_VERSION >= 0x050000 m_workingDir( QStandardPaths::writableLocation( QStandardPaths::DocumentsLocation ) + "/lmms/"), - #else - m_workingDir( QDesktopServices::storageLocation( QDesktopServices::DocumentsLocation ) + "/lmms/"), - #endif m_dataDir( "data:/" ), m_artworkDir( defaultArtworkDir() ), m_vstDir( m_workingDir + "vst/" ), @@ -210,13 +202,8 @@ QStringList ConfigManager::availabeVstEmbedMethods() methods.append("win32"); #endif #ifdef LMMS_BUILD_LINUX -#if QT_VERSION >= 0x050000 if (static_cast(QApplication::instance())-> platformName() == "xcb") -#else - if (qgetenv("QT_QPA_PLATFORM").isNull() - || qgetenv("QT_QPA_PLATFORM") == "xcb") -#endif { methods.append("xembed"); } diff --git a/src/core/main.cpp b/src/core/main.cpp index 078e9f26d..71440654e 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -818,22 +818,12 @@ int main( int argc, char * * argv ) QPushButton * discard; QPushButton * exit; - #if QT_VERSION >= 0x050000 - // setting all buttons to the same roles allows us - // to have a custom layout - discard = mb.addButton( MainWindow::tr( "Discard" ), - QMessageBox::AcceptRole ); - recover = mb.addButton( MainWindow::tr( "Recover" ), - QMessageBox::AcceptRole ); - - # else - // in qt4 the button order is reversed - recover = mb.addButton( MainWindow::tr( "Recover" ), - QMessageBox::AcceptRole ); - discard = mb.addButton( MainWindow::tr( "Discard" ), - QMessageBox::AcceptRole ); - - #endif + // setting all buttons to the same roles allows us + // to have a custom layout + discard = mb.addButton( MainWindow::tr( "Discard" ), + QMessageBox::AcceptRole ); + recover = mb.addButton( MainWindow::tr( "Recover" ), + QMessageBox::AcceptRole ); // have a hidden exit button exit = mb.addButton( "", QMessageBox::RejectRole); diff --git a/src/gui/EffectSelectDialog.cpp b/src/gui/EffectSelectDialog.cpp index deb39d901..64b180d48 100644 --- a/src/gui/EffectSelectDialog.cpp +++ b/src/gui/EffectSelectDialog.cpp @@ -120,21 +120,15 @@ EffectSelectDialog::EffectSelectDialog( QWidget * _parent ) : connect( ui->buttonBox, SIGNAL( accepted() ), this, SLOT( acceptSelection() ) ); -#if QT_VERSION >= 0x050000 -#define setResizeMode setSectionResizeMode ui->filterEdit->setClearButtonEnabled( true ); -#endif - ui->pluginList->verticalHeader()->setResizeMode( + ui->pluginList->verticalHeader()->setSectionResizeMode( QHeaderView::ResizeToContents ); ui->pluginList->verticalHeader()->hide(); - ui->pluginList->horizontalHeader()->setResizeMode( 0, + ui->pluginList->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::Stretch ); - ui->pluginList->horizontalHeader()->setResizeMode( 1, + ui->pluginList->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::ResizeToContents ); ui->pluginList->sortByColumn( 0, Qt::AscendingOrder ); -#if QT_VERSION >= 0x050000 -#undef setResizeMode -#endif updateSelection(); show(); diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 91804d136..24b8b89f1 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -83,9 +83,7 @@ FileBrowser::FileBrowser(const QString & directories, const QString & filter, m_filterEdit = new QLineEdit( searchWidget ); m_filterEdit->setPlaceholderText( tr("Search") ); -#if QT_VERSION >= 0x050000 m_filterEdit->setClearButtonEnabled( true ); -#endif connect( m_filterEdit, SIGNAL( textEdited( const QString & ) ), this, SLOT( filterItems( const QString & ) ) ); diff --git a/src/gui/LmmsStyle.cpp b/src/gui/LmmsStyle.cpp index e57e29e47..b6a139bbb 100644 --- a/src/gui/LmmsStyle.cpp +++ b/src/gui/LmmsStyle.cpp @@ -132,11 +132,7 @@ LmmsStyle::LmmsStyle() : if( s_palette != NULL ) { qApp->setPalette( *s_palette ); } -#if QT_VERSION >= 0x050000 setBaseStyle( QStyleFactory::create( "Fusion" ) ); -#else - setBaseStyle( QStyleFactory::create( "Plastique" ) ); -#endif } diff --git a/src/gui/MainApplication.cpp b/src/gui/MainApplication.cpp index 5210dd76c..c88949d32 100644 --- a/src/gui/MainApplication.cpp +++ b/src/gui/MainApplication.cpp @@ -35,7 +35,7 @@ MainApplication::MainApplication(int& argc, char** argv) : QApplication(argc, argv), m_queuedFile() { -#if defined(LMMS_BUILD_WIN32) && QT_VERSION >= 0x050000 +#if defined(LMMS_BUILD_WIN32) installNativeEventFilter(this); #endif } @@ -92,7 +92,6 @@ bool MainApplication::winEventFilter(MSG* msg, long* result) } } -#if QT_VERSION >= 0x050000 bool MainApplication::nativeEventFilter(const QByteArray& eventType, void* message, long* result) { @@ -103,4 +102,3 @@ bool MainApplication::nativeEventFilter(const QByteArray& eventType, return false; } #endif -#endif diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 8f2fd4bad..a48a50044 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -69,7 +69,7 @@ #include "lmmsversion.h" -#if !defined(LMMS_BUILD_WIN32) && !defined(LMMS_BUILD_APPLE) && !defined(LMMS_BUILD_HAIKU) && QT_VERSION >= 0x050000 +#if !defined(LMMS_BUILD_WIN32) && !defined(LMMS_BUILD_APPLE) && !defined(LMMS_BUILD_HAIKU) //Work around an issue on KDE5 as per https://bugs.kde.org/show_bug.cgi?id=337491#c21 void disableAutoKeyAccelerators(QWidget* mainWindow) { @@ -96,7 +96,7 @@ MainWindow::MainWindow() : m_metronomeToggle( 0 ), m_session( Normal ) { -#if !defined(LMMS_BUILD_WIN32) && !defined(LMMS_BUILD_APPLE) && !defined(LMMS_BUILD_HAIKU) && QT_VERSION >= 0x050000 +#if !defined(LMMS_BUILD_WIN32) && !defined(LMMS_BUILD_APPLE) && !defined(LMMS_BUILD_HAIKU) disableAutoKeyAccelerators(this); #endif setAttribute( Qt::WA_DeleteOnClose ); @@ -336,7 +336,7 @@ void MainWindow::finalize() Qt::CTRL + Qt::Key_M ); // Prevent dangling separator at end of menu per https://bugreports.qt.io/browse/QTBUG-40071 -#if !(defined(LMMS_BUILD_APPLE) && (QT_VERSION >= 0x050000) && (QT_VERSION < 0x050600)) +#if !(defined(LMMS_BUILD_APPLE) && (QT_VERSION < 0x050600)) project_menu->addSeparator(); #endif project_menu->addAction( embed::getIconPixmap( "exit" ), tr( "&Quit" ), @@ -411,7 +411,7 @@ void MainWindow::finalize() } // Prevent dangling separator at end of menu per https://bugreports.qt.io/browse/QTBUG-40071 -#if !(defined(LMMS_BUILD_APPLE) && (QT_VERSION >= 0x050000) && (QT_VERSION < 0x050600)) +#if !(defined(LMMS_BUILD_APPLE) && (QT_VERSION < 0x050600)) help_menu->addSeparator(); #endif help_menu->addAction( embed::getIconPixmap( "icon" ), tr( "About" ), diff --git a/src/gui/SetupDialog.cpp b/src/gui/SetupDialog.cpp index 2f567a869..ad2ac9fb5 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -1053,11 +1053,7 @@ void SetupDialog::accept() QString::number( m_disableAutoQuit ) ); ConfigManager::inst()->setValue( "app", "language", m_lang ); ConfigManager::inst()->setValue( "ui", "vstembedmethod", -#if QT_VERSION >= 0x050000 m_vstEmbedComboBox->currentData().toString() ); -#else - m_vstEmbedComboBox->itemData(m_vstEmbedComboBox->currentIndex()).toString() ); -#endif ConfigManager::inst()->setWorkingDir(QDir::fromNativeSeparators(m_workingDir)); diff --git a/src/gui/TimeLineWidget.cpp b/src/gui/TimeLineWidget.cpp index 5c91cfcf8..71b384dc8 100644 --- a/src/gui/TimeLineWidget.cpp +++ b/src/gui/TimeLineWidget.cpp @@ -40,11 +40,6 @@ #include "SongEditor.h" -#if QT_VERSION < 0x040800 -#define MiddleButton MidButton -#endif - - QPixmap * TimeLineWidget::s_posMarkerPixmap = NULL; TimeLineWidget::TimeLineWidget( const int xoff, const int yoff, const float ppt, diff --git a/src/gui/dialogs/FileDialog.cpp b/src/gui/dialogs/FileDialog.cpp index fb9c7faac..3ce10760a 100644 --- a/src/gui/dialogs/FileDialog.cpp +++ b/src/gui/dialogs/FileDialog.cpp @@ -35,7 +35,7 @@ FileDialog::FileDialog( QWidget *parent, const QString &caption, const QString &directory, const QString &filter ) : QFileDialog( parent, caption, directory, filter ) { -#if (QT_VERSION >= 0x040806 && QT_VERSION < 0x050000) || QT_VERSION > 0x050200 +#if QT_VERSION > 0x050200 setOption( QFileDialog::DontUseCustomDirectoryIcons ); #endif @@ -43,27 +43,15 @@ FileDialog::FileDialog( QWidget *parent, const QString &caption, // Add additional locations to the sidebar QList urls = sidebarUrls(); -#if QT_VERSION >= 0x050000 urls << QUrl::fromLocalFile( QStandardPaths::writableLocation( QStandardPaths::DesktopLocation ) ); -#else - urls << QUrl::fromLocalFile( QDesktopServices::storageLocation( QDesktopServices::DesktopLocation ) ); -#endif // Find downloads directory QDir downloadDir( QDir::homePath() + "/Downloads" ); if ( ! downloadDir.exists() ) -#if QT_VERSION >= 0x050000 downloadDir = QStandardPaths::writableLocation( QStandardPaths::DownloadLocation ); -#else - downloadDir = QDesktopServices::storageLocation( QDesktopServices::DocumentsLocation ) + "/Downloads"; -#endif if ( downloadDir.exists() ) urls << QUrl::fromLocalFile( downloadDir.absolutePath() ); -#if QT_VERSION >= 0x050000 urls << QUrl::fromLocalFile( QStandardPaths::writableLocation( QStandardPaths::MusicLocation ) ); -#else - urls << QUrl::fromLocalFile( QDesktopServices::storageLocation( QDesktopServices::MusicLocation ) ); -#endif urls << QUrl::fromLocalFile( ConfigManager::inst()->workingDir() ); // Add `/Volumes` directory on OS X systems, this allows the user to browse diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index ffcc10c1a..2960a31a3 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -64,10 +64,6 @@ #include "TimeLineWidget.h" -#if QT_VERSION < 0x040800 -#define MiddleButton MidButton -#endif - using std::move; typedef AutomationPattern::timeMap timeMap; From fefec9a8c691e2fc49ac14c70f7021157ad6bba3 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 17 Jun 2018 14:03:01 +0200 Subject: [PATCH 023/445] Fix cleanup logic error --- plugins/VstEffect/VstEffectControlDialog.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/VstEffect/VstEffectControlDialog.cpp b/plugins/VstEffect/VstEffectControlDialog.cpp index 3435cefb3..156eaae01 100644 --- a/plugins/VstEffect/VstEffectControlDialog.cpp +++ b/plugins/VstEffect/VstEffectControlDialog.cpp @@ -272,12 +272,10 @@ void VstEffectControlDialog::showEvent(QShowEvent *_se) VstEffectControlDialog::~VstEffectControlDialog() { -#ifndef LMMS_BUILD_LINUX if (m_pluginWidget && layout()) { layout()->removeWidget(m_pluginWidget); m_pluginWidget->setParent(nullptr); } -#endif } From 11c693205e62f8b0779253ec41e0a74f76066db6 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 17 Jun 2018 14:27:28 +0200 Subject: [PATCH 024/445] Remove usage of deprecated Qt API Removes usage of the following deprecated Qt functions: - QPixmap::grabWidget - QString::null - qFind - qSort - qGreater - qCopy --- include/AutomatableButton.h | 4 ++-- include/AutomatableSlider.h | 2 +- include/FileBrowser.h | 6 +++--- include/LcdSpinBox.h | 4 ++-- include/LcdWidget.h | 6 +++--- include/LedCheckbox.h | 4 ++-- include/MidiApple.h | 4 ++-- include/MidiDummy.h | 4 ++-- include/MidiWinMM.h | 4 ++-- include/Model.h | 2 +- include/PixmapButton.h | 2 +- include/RemotePlugin.h | 8 ++++---- include/embed.h | 6 +++--- plugins/patman/patman.cpp | 4 ++-- plugins/vibed/nine_button_selector.cpp | 4 ++-- src/core/AutomatableModel.cpp | 2 +- src/core/EffectChain.cpp | 2 +- src/core/LadspaManager.cpp | 2 +- src/core/Mixer.cpp | 6 +++--- src/core/Model.cpp | 2 +- src/core/SampleBuffer.cpp | 4 ++-- src/core/Track.cpp | 13 ++++++------- src/core/audio/AudioPort.cpp | 2 +- src/core/midi/MidiClient.cpp | 2 +- src/gui/AutomatableModelView.cpp | 4 ++-- src/gui/AutomationPatternView.cpp | 4 ++-- src/gui/FileBrowser.cpp | 6 +++--- src/gui/FxMixerView.cpp | 2 +- src/gui/MidiSetupWidget.cpp | 2 +- src/gui/SetupDialog.cpp | 18 +++++++++--------- src/gui/StringPairDrag.cpp | 2 +- src/gui/SubWindow.cpp | 6 +++--- src/gui/editors/PianoRoll.cpp | 6 +++--- src/gui/widgets/AutomatableButton.cpp | 2 +- src/gui/widgets/ComboBox.cpp | 2 +- src/gui/widgets/ControllerRackView.cpp | 2 +- src/gui/widgets/EffectRackView.cpp | 4 ++-- src/gui/widgets/Graph.cpp | 2 +- src/gui/widgets/LadspaControlView.cpp | 2 +- src/tracks/InstrumentTrack.cpp | 2 +- 40 files changed, 82 insertions(+), 83 deletions(-) diff --git a/include/AutomatableButton.h b/include/AutomatableButton.h index 014f1eed8..ec9b3e316 100644 --- a/include/AutomatableButton.h +++ b/include/AutomatableButton.h @@ -39,7 +39,7 @@ class EXPORT AutomatableButton : public QPushButton, public BoolModelView Q_OBJECT public: AutomatableButton( QWidget * _parent, const QString & _name - = QString::null ); + = QString() ); virtual ~AutomatableButton(); inline void setCheckable( bool _on ) @@ -84,7 +84,7 @@ class EXPORT automatableButtonGroup : public QWidget, public IntModelView Q_OBJECT public: automatableButtonGroup( QWidget * _parent, const QString & _name - = QString::null ); + = QString() ); virtual ~automatableButtonGroup(); void addButton( AutomatableButton * _btn ); diff --git a/include/AutomatableSlider.h b/include/AutomatableSlider.h index 0fbd3adf6..f58d4a059 100644 --- a/include/AutomatableSlider.h +++ b/include/AutomatableSlider.h @@ -36,7 +36,7 @@ class AutomatableSlider : public QSlider, public IntModelView { Q_OBJECT public: - AutomatableSlider( QWidget * _parent, const QString & _name = QString::null ); + AutomatableSlider( QWidget * _parent, const QString & _name = QString() ); virtual ~AutomatableSlider(); bool showStatus() diff --git a/include/FileBrowser.h b/include/FileBrowser.h index 91a58831d..1565017d1 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -129,13 +129,13 @@ public: void update( void ); - inline QString fullName( QString path = QString::null ) + inline QString fullName( QString path = QString() ) { - if( path == QString::null ) + if( path == QString() ) { path = m_directories[0]; } - if( path != QString::null ) + if( path != QString() ) { path += QDir::separator(); } diff --git a/include/LcdSpinBox.h b/include/LcdSpinBox.h index d6896f52b..d5b5b0812 100644 --- a/include/LcdSpinBox.h +++ b/include/LcdSpinBox.h @@ -34,9 +34,9 @@ class EXPORT LcdSpinBox : public LcdWidget, public IntModelView { Q_OBJECT public: - LcdSpinBox( int numDigits, QWidget* parent, const QString& name = QString::null ); + LcdSpinBox( int numDigits, QWidget* parent, const QString& name = QString() ); - LcdSpinBox( int numDigits, const QString& style, QWidget* parent, const QString& name = QString::null ); + LcdSpinBox( int numDigits, const QString& style, QWidget* parent, const QString& name = QString() ); virtual ~LcdSpinBox() = default; diff --git a/include/LcdWidget.h b/include/LcdWidget.h index 89bafd1d1..592a93639 100644 --- a/include/LcdWidget.h +++ b/include/LcdWidget.h @@ -40,9 +40,9 @@ class EXPORT LcdWidget : public QWidget Q_PROPERTY( QColor textShadowColor READ textShadowColor WRITE setTextShadowColor ) public: - LcdWidget( QWidget* parent, const QString& name = QString::null ); - LcdWidget( int numDigits, QWidget* parent, const QString& name = QString::null ); - LcdWidget( int numDigits, const QString& style, QWidget* parent, const QString& name = QString::null ); + LcdWidget( QWidget* parent, const QString& name = QString() ); + LcdWidget( int numDigits, QWidget* parent, const QString& name = QString() ); + LcdWidget( int numDigits, const QString& style, QWidget* parent, const QString& name = QString() ); virtual ~LcdWidget(); diff --git a/include/LedCheckbox.h b/include/LedCheckbox.h index b1c901ed6..f59a0ed5b 100644 --- a/include/LedCheckbox.h +++ b/include/LedCheckbox.h @@ -45,10 +45,10 @@ public: } ; LedCheckBox( const QString & _txt, QWidget * _parent, - const QString & _name = QString::null, + const QString & _name = QString(), LedColors _color = Yellow ); LedCheckBox( QWidget * _parent, - const QString & _name = QString::null, + const QString & _name = QString(), LedColors _color = Yellow ); virtual ~LedCheckBox(); diff --git a/include/MidiApple.h b/include/MidiApple.h index dcef23a83..21b88073b 100644 --- a/include/MidiApple.h +++ b/include/MidiApple.h @@ -47,7 +47,7 @@ public: inline static QString probeDevice() { - return QString::Null(); // no midi device name + return QString(); // no midi device name } inline static QString name() @@ -56,7 +56,7 @@ public: } inline static QString configSection() { - return QString::Null(); // no configuration settings + return QString(); // no configuration settings } virtual void processOutEvent( const MidiEvent & _me, diff --git a/include/MidiDummy.h b/include/MidiDummy.h index 980afe288..dffd1ce51 100644 --- a/include/MidiDummy.h +++ b/include/MidiDummy.h @@ -46,12 +46,12 @@ public: inline static QString probeDevice() { - return QString::Null(); // no midi device name + return QString(); // no midi device name } inline static QString configSection() { - return QString::Null(); // no configuration settings + return QString(); // no configuration settings } diff --git a/include/MidiWinMM.h b/include/MidiWinMM.h index 08e49c108..a51fa7ed6 100644 --- a/include/MidiWinMM.h +++ b/include/MidiWinMM.h @@ -47,7 +47,7 @@ public: inline static QString probeDevice() { - return QString::Null(); // no midi device name + return QString(); // no midi device name } @@ -58,7 +58,7 @@ public: inline static QString configSection() { - return QString::Null(); // no configuration settings + return QString(); // no configuration settings } diff --git a/include/Model.h b/include/Model.h index 55e735a05..b216d0241 100644 --- a/include/Model.h +++ b/include/Model.h @@ -35,7 +35,7 @@ class EXPORT Model : public QObject { Q_OBJECT public: - Model( Model * _parent, QString _display_name = QString::null, + Model( Model * _parent, QString _display_name = QString(), bool _default_constructed = false ) : QObject( _parent ), m_displayName( _display_name ), diff --git a/include/PixmapButton.h b/include/PixmapButton.h index 9f6ef8071..fafa71465 100644 --- a/include/PixmapButton.h +++ b/include/PixmapButton.h @@ -36,7 +36,7 @@ class EXPORT PixmapButton : public AutomatableButton Q_OBJECT public: PixmapButton( QWidget * _parent, - const QString & _name = QString::null ); + const QString & _name = QString() ); virtual ~PixmapButton(); void setActiveGraphic( const QPixmap & _pm ); diff --git a/include/RemotePlugin.h b/include/RemotePlugin.h index e0df85003..076a1d95b 100644 --- a/include/RemotePlugin.h +++ b/include/RemotePlugin.h @@ -138,8 +138,8 @@ public: m_shmID( -1 ), #endif m_data( NULL ), - m_dataSem( QString::null ), - m_messageSem( QString::null ), + m_dataSem( QString() ), + m_messageSem( QString() ), m_lockDepth( 0 ) { #ifdef USE_QT_SHMEM @@ -181,8 +181,8 @@ public: m_shmID( shmget( _shm_key, 0, 0 ) ), #endif m_data( NULL ), - m_dataSem( QString::null ), - m_messageSem( QString::null ), + m_dataSem( QString() ), + m_messageSem( QString() ), m_lockDepth( 0 ) { #ifdef USE_QT_SHMEM diff --git a/include/embed.h b/include/embed.h index 57ca743cd..4bb1d710d 100644 --- a/include/embed.h +++ b/include/embed.h @@ -60,11 +60,11 @@ class PixmapLoader { public: PixmapLoader( const PixmapLoader * _ref ) : - m_name( _ref != NULL ? _ref->m_name : QString::null ) + m_name( _ref != NULL ? _ref->m_name : QString() ) { } - PixmapLoader( const QString & _name = QString::null ) : + PixmapLoader( const QString & _name = QString() ) : m_name( _name ) { } @@ -96,7 +96,7 @@ protected: class PluginPixmapLoader : public PixmapLoader { public: - PluginPixmapLoader( const QString & _name = QString::null ) : + PluginPixmapLoader( const QString & _name = QString() ) : PixmapLoader( _name ) { } diff --git a/plugins/patman/patman.cpp b/plugins/patman/patman.cpp index bf24c6d32..bf1275321 100644 --- a/plugins/patman/patman.cpp +++ b/plugins/patman/patman.cpp @@ -78,7 +78,7 @@ PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) patmanInstrument::patmanInstrument( InstrumentTrack * _instrument_track ) : Instrument( _instrument_track, &patman_plugin_descriptor ), - m_patchFile( QString::null ), + m_patchFile( QString() ), m_loopedModel( true, this ), m_tunedModel( true, this ) { @@ -182,7 +182,7 @@ void patmanInstrument::setFile( const QString & _patch_file, bool _rename ) { if( _patch_file.size() <= 0 ) { - m_patchFile = QString::null; + m_patchFile = QString(); return; } diff --git a/plugins/vibed/nine_button_selector.cpp b/plugins/vibed/nine_button_selector.cpp index 0c48c66c9..edcfc2f51 100644 --- a/plugins/vibed/nine_button_selector.cpp +++ b/plugins/vibed/nine_button_selector.cpp @@ -52,8 +52,8 @@ nineButtonSelector::nineButtonSelector( QPixmap _button0_on, int _x, int _y, QWidget * _parent ): QWidget( _parent ), - IntModelView( new nineButtonSelectorModel(0, 8, _default, NULL, - QString::null, true ), this ) + IntModelView( new nineButtonSelectorModel(0, 8, _default, NULL, + QString(), true ), this ) { setFixedSize( 50, 50 ); move( _x, _y ); diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index 30732e052..e3ed6e445 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -409,7 +409,7 @@ void AutomatableModel::linkModel( AutomatableModel* model ) void AutomatableModel::unlinkModel( AutomatableModel* model ) { - AutoModelVector::Iterator it = qFind( m_linkedModels.begin(), m_linkedModels.end(), model ); + AutoModelVector::Iterator it = std::find( m_linkedModels.begin(), m_linkedModels.end(), model ); if( it != m_linkedModels.end() ) { m_linkedModels.erase( it ); diff --git a/src/core/EffectChain.cpp b/src/core/EffectChain.cpp index 886899c04..8439fd91e 100644 --- a/src/core/EffectChain.cpp +++ b/src/core/EffectChain.cpp @@ -137,7 +137,7 @@ void EffectChain::removeEffect( Effect * _effect ) { Engine::mixer()->requestChangeInModel(); - Effect ** found = qFind( m_effects.begin(), m_effects.end(), _effect ); + Effect ** found = std::find( m_effects.begin(), m_effects.end(), _effect ); if( found == m_effects.end() ) { Engine::mixer()->doneChangeInModel(); diff --git a/src/core/LadspaManager.cpp b/src/core/LadspaManager.cpp index 176fde18b..4336e50a5 100644 --- a/src/core/LadspaManager.cpp +++ b/src/core/LadspaManager.cpp @@ -103,7 +103,7 @@ LadspaManager::LadspaManager() { m_sortedPlugins.append( qMakePair( getName( *it ), *it ) ); } - qSort( m_sortedPlugins ); + std::sort( m_sortedPlugins.begin(), m_sortedPlugins.end() ); } diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index 3298d3dd0..b508b968b 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -393,7 +393,7 @@ const surroundSampleFrame * Mixer::renderNextBuffer() ConstPlayHandleList::Iterator it_rem = m_playHandlesToRemove.begin(); while( it_rem != m_playHandlesToRemove.end() ) { - PlayHandleList::Iterator it = qFind( m_playHandles.begin(), m_playHandles.end(), *it_rem ); + PlayHandleList::Iterator it = std::find( m_playHandles.begin(), m_playHandles.end(), *it_rem ); if( it != m_playHandles.end() ) { @@ -659,7 +659,7 @@ void Mixer::restoreAudioDevice() void Mixer::removeAudioPort( AudioPort * _port ) { requestChangeInModel(); - QVector::Iterator it = qFind( m_audioPorts.begin(), + QVector::Iterator it = std::find( m_audioPorts.begin(), m_audioPorts.end(), _port ); if( it != m_audioPorts.end() ) @@ -720,7 +720,7 @@ void Mixer::removePlayHandle( PlayHandle * _ph ) } } // Now check m_playHandles - PlayHandleList::Iterator it = qFind( m_playHandles.begin(), + PlayHandleList::Iterator it = std::find( m_playHandles.begin(), m_playHandles.end(), _ph ); if( it != m_playHandles.end() ) { diff --git a/src/core/Model.cpp b/src/core/Model.cpp index 04a1f2f33..597d0340d 100644 --- a/src/core/Model.cpp +++ b/src/core/Model.cpp @@ -33,7 +33,7 @@ QString Model::fullDisplayName() const const QString p = parentModel()->fullDisplayName(); if( n.isEmpty() && p.isEmpty() ) { - return QString::null; + return QString(); } else if( p.isEmpty() ) { diff --git a/src/core/SampleBuffer.cpp b/src/core/SampleBuffer.cpp index 9cde88cf5..63059010d 100644 --- a/src/core/SampleBuffer.cpp +++ b/src/core/SampleBuffer.cpp @@ -1009,12 +1009,12 @@ QString SampleBuffer::openAudioFile() const { if( ofd.selectedFiles().isEmpty() ) { - return QString::null; + return QString(); } return tryToMakeRelative( ofd.selectedFiles()[0] ); } - return QString::null; + return QString(); } diff --git a/src/core/Track.cpp b/src/core/Track.cpp index e7aa15cd0..36d649e77 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -95,7 +95,7 @@ TextFloat * TrackContentObjectView::s_textFloat = NULL; TrackContentObject::TrackContentObject( Track * track ) : Model( track ), m_track( track ), - m_name( QString::null ), + m_name( QString() ), m_startPosition(), m_length(), m_mutedModel( false, this, tr( "Mute" ) ), @@ -870,7 +870,7 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) DataFile dataFile = createTCODataFiles( tcoViews ); // TODO -- thumbnail for all selected - QPixmap thumbnail = QPixmap::grabWidget( this ).scaled( + QPixmap thumbnail = grab().scaled( 128, 128, Qt::KeepAspectRatio, Qt::SmoothTransformation ); @@ -1242,7 +1242,7 @@ void TrackContentWidget::addTCOView( TrackContentObjectView * tcov ) */ void TrackContentWidget::removeTCOView( TrackContentObjectView * tcov ) { - tcoViewVector::iterator it = qFind( m_tcoViews.begin(), + tcoViewVector::iterator it = std::find( m_tcoViews.begin(), m_tcoViews.end(), tcov ); if( it != m_tcoViews.end() ) @@ -1808,8 +1808,7 @@ void TrackOperationsWidget::mousePressEvent( QMouseEvent * me ) m_trackView->getTrack()->saveState( dataFile, dataFile.content() ); new StringPairDrag( QString( "track_%1" ).arg( m_trackView->getTrack()->type() ), - dataFile.toString(), QPixmap::grabWidget( - m_trackView->getTrackSettingsWidget() ), + dataFile.toString(), m_trackView->getTrackSettingsWidget()->grab(), this ); } else if( me->button() == Qt::LeftButton ) @@ -2259,7 +2258,7 @@ TrackContentObject * Track::addTCO( TrackContentObject * tco ) */ void Track::removeTCO( TrackContentObject * tco ) { - tcoVector::iterator it = qFind( m_trackContentObjects.begin(), + tcoVector::iterator it = std::find( m_trackContentObjects.begin(), m_trackContentObjects.end(), tco ); if( it != m_trackContentObjects.end() ) @@ -2331,7 +2330,7 @@ TrackContentObject * Track::getTCO( int tcoNum ) int Track::getTCONum( const TrackContentObject * tco ) { // for( int i = 0; i < getTrackContentWidget()->numOfTCOs(); ++i ) - tcoVector::iterator it = qFind( m_trackContentObjects.begin(), + tcoVector::iterator it = std::find( m_trackContentObjects.begin(), m_trackContentObjects.end(), tco ); if( it != m_trackContentObjects.end() ) diff --git a/src/core/audio/AudioPort.cpp b/src/core/audio/AudioPort.cpp index e9beb3c0e..eda000bb9 100644 --- a/src/core/audio/AudioPort.cpp +++ b/src/core/audio/AudioPort.cpp @@ -238,7 +238,7 @@ void AudioPort::addPlayHandle( PlayHandle * handle ) void AudioPort::removePlayHandle( PlayHandle * handle ) { m_playHandleLock.lock(); - PlayHandleList::Iterator it = qFind( m_playHandles.begin(), m_playHandles.end(), handle ); + PlayHandleList::Iterator it = std::find( m_playHandles.begin(), m_playHandles.end(), handle ); if( it != m_playHandles.end() ) { m_playHandles.erase( it ); diff --git a/src/core/midi/MidiClient.cpp b/src/core/midi/MidiClient.cpp index b88c64db1..03eec4e38 100644 --- a/src/core/midi/MidiClient.cpp +++ b/src/core/midi/MidiClient.cpp @@ -77,7 +77,7 @@ void MidiClient::removePort( MidiPort* port ) } QVector::Iterator it = - qFind( m_midiPorts.begin(), m_midiPorts.end(), port ); + std::find( m_midiPorts.begin(), m_midiPorts.end(), port ); if( it != m_midiPorts.end() ) { m_midiPorts.erase( it ); diff --git a/src/gui/AutomatableModelView.cpp b/src/gui/AutomatableModelView.cpp index 0597cf2f5..cdb1a5a04 100644 --- a/src/gui/AutomatableModelView.cpp +++ b/src/gui/AutomatableModelView.cpp @@ -43,8 +43,8 @@ static float floatFromClipboard(bool* ok=nullptr); AutomatableModelView::AutomatableModelView( ::Model* model, QWidget* _this ) : ModelView( model, _this ), - m_description( QString::null ), - m_unit( QString::null ) + m_description( QString() ), + m_unit( QString() ) { widget()->setAcceptDrops( true ); widget()->setCursor( QCursor( embed::getIconPixmap( "hand" ), 3, 3 ) ); diff --git a/src/gui/AutomationPatternView.cpp b/src/gui/AutomationPatternView.cpp index 92e7b7377..6879b5bbd 100644 --- a/src/gui/AutomationPatternView.cpp +++ b/src/gui/AutomationPatternView.cpp @@ -91,7 +91,7 @@ void AutomationPatternView::update() void AutomationPatternView::resetName() { - m_pat->setName( QString::null ); + m_pat->setName( QString() ); } @@ -118,7 +118,7 @@ void AutomationPatternView::disconnectObject( QAction * _a ) float oldMin = m_pat->getMin(); float oldMax = m_pat->getMax(); - m_pat->m_objects.erase( qFind( m_pat->m_objects.begin(), + m_pat->m_objects.erase( std::find( m_pat->m_objects.begin(), m_pat->m_objects.end(), dynamic_cast( j ) ) ); update(); diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 24b8b89f1..05727d332 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -89,7 +89,7 @@ FileBrowser::FileBrowser(const QString & directories, const QString & filter, QPushButton * reload_btn = new QPushButton( embed::getIconPixmap( "reload" ), - QString::null, searchWidget ); + QString(), searchWidget ); reload_btn->setToolTip( tr( "Refresh list" ) ); connect( reload_btn, SIGNAL( clicked() ), this, SLOT( reloadTree() ) ); @@ -129,7 +129,7 @@ bool FileBrowser::filterItems( const QString & filter, QTreeWidgetItem * item ) { // yes, then show everything below it->setHidden( false ); - filterItems( QString::null, it ); + filterItems( QString(), it ); anyMatched = true; } else @@ -219,7 +219,7 @@ void FileBrowser::addItems(const QString & path ) { if( m_dirsAsItems ) { - m_fileBrowserTreeWidget->addTopLevelItem( new Directory( path, QString::null, m_filter ) ); + m_fileBrowserTreeWidget->addTopLevelItem( new Directory( path, QString(), m_filter ) ); return; } diff --git a/src/gui/FxMixerView.cpp b/src/gui/FxMixerView.cpp index cbcfd0a47..043ec3637 100644 --- a/src/gui/FxMixerView.cpp +++ b/src/gui/FxMixerView.cpp @@ -131,7 +131,7 @@ FxMixerView::FxMixerView() : ml->addWidget( channelArea, 1, Qt::AlignTop ); // show the add new effect channel button - QPushButton * newChannelBtn = new QPushButton( embed::getIconPixmap( "new_channel" ), QString::null, this ); + QPushButton * newChannelBtn = new QPushButton( embed::getIconPixmap( "new_channel" ), QString(), this ); newChannelBtn->setObjectName( "newChannelBtn" ); newChannelBtn->setFixedSize( fxLineSize ); connect( newChannelBtn, SIGNAL( clicked() ), this, SLOT( addNewChannel() ) ); diff --git a/src/gui/MidiSetupWidget.cpp b/src/gui/MidiSetupWidget.cpp index ccde9f29e..f3001b3af 100644 --- a/src/gui/MidiSetupWidget.cpp +++ b/src/gui/MidiSetupWidget.cpp @@ -36,7 +36,7 @@ MidiSetupWidget::MidiSetupWidget( const QString & caption, const QString & confi m_configSection(configSection), m_device(nullptr) { - // supply devName=QString::Null() (distinct from QString("")) + // supply devName=QString() (distinct from QString("")) // to indicate that there is no editable DEVICE field if (!devName.isNull()) { diff --git a/src/gui/SetupDialog.cpp b/src/gui/SetupDialog.cpp index ad2ac9fb5..555969fb3 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -1269,7 +1269,7 @@ void SetupDialog::openWorkingDir() { QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose LMMS working directory" ), m_workingDir ); - if( new_dir != QString::null ) + if( new_dir != QString() ) { m_wdLineEdit->setText( new_dir ); } @@ -1280,7 +1280,7 @@ void SetupDialog::openGIGDir() QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose your GIG directory" ), m_gigDir ); - if( new_dir != QString::null ) + if( new_dir != QString() ) { m_gigLineEdit->setText( new_dir ); } @@ -1291,7 +1291,7 @@ void SetupDialog::openSF2Dir() QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose your SF2 directory" ), m_sf2Dir ); - if( new_dir != QString::null ) + if( new_dir != QString() ) { m_sf2LineEdit->setText( new_dir ); } @@ -1313,7 +1313,7 @@ void SetupDialog::openVSTDir() QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose your VST-plugin directory" ), m_vstDir ); - if( new_dir != QString::null ) + if( new_dir != QString() ) { m_vdLineEdit->setText( new_dir ); } @@ -1345,7 +1345,7 @@ void SetupDialog::openArtworkDir() QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose artwork-theme directory" ), m_artworkDir ); - if( new_dir != QString::null ) + if( new_dir != QString() ) { m_adLineEdit->setText( new_dir ); } @@ -1367,7 +1367,7 @@ void SetupDialog::openLADSPADir() QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose LADSPA plugin directory" ), m_ladDir ); - if( new_dir != QString::null ) + if( new_dir != QString() ) { if( m_ladLineEdit->text() == "" ) { @@ -1389,7 +1389,7 @@ void SetupDialog::openSTKDir() QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose STK rawwave directory" ), m_stkDir ); - if( new_dir != QString::null ) + if( new_dir != QString() ) { m_stkLineEdit->setText( new_dir ); } @@ -1406,7 +1406,7 @@ void SetupDialog::openDefaultSoundfont() tr( "Choose default SoundFont" ), m_defaultSoundfont, "SoundFont2 Files (*.sf2)" ); - if( new_file != QString::null ) + if( new_file != QString() ) { m_sfLineEdit->setText( new_file ); } @@ -1439,7 +1439,7 @@ void SetupDialog::openBackgroundArtwork() tr( "Choose background artwork" ), dir, "Image Files (" + fileTypes + ")" ); - if( new_file != QString::null ) + if( new_file != QString() ) { m_baLineEdit->setText( new_file ); } diff --git a/src/gui/StringPairDrag.cpp b/src/gui/StringPairDrag.cpp index a10d31c5c..f754e2d39 100644 --- a/src/gui/StringPairDrag.cpp +++ b/src/gui/StringPairDrag.cpp @@ -40,7 +40,7 @@ StringPairDrag::StringPairDrag( const QString & _key, const QString & _value, { if( _icon.isNull() && _w ) { - setPixmap( QPixmap::grabWidget( _w ).scaled( + setPixmap( _w->grab().scaled( 64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation ) ); diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index 9e3876d24..7340d428c 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -52,7 +52,7 @@ SubWindow::SubWindow( QWidget *parent, Qt::WindowFlags windowFlags ) : m_borderColor = Qt::black; // close, maximize and restore (after maximizing) buttons - m_closeBtn = new QPushButton( embed::getIconPixmap( "close" ), QString::null, this ); + m_closeBtn = new QPushButton( embed::getIconPixmap( "close" ), QString(), this ); m_closeBtn->resize( m_buttonSize ); m_closeBtn->setFocusPolicy( Qt::NoFocus ); m_closeBtn->setCursor( Qt::ArrowCursor ); @@ -60,7 +60,7 @@ SubWindow::SubWindow( QWidget *parent, Qt::WindowFlags windowFlags ) : m_closeBtn->setToolTip( tr( "Close" ) ); connect( m_closeBtn, SIGNAL( clicked( bool ) ), this, SLOT( close() ) ); - m_maximizeBtn = new QPushButton( embed::getIconPixmap( "maximize" ), QString::null, this ); + m_maximizeBtn = new QPushButton( embed::getIconPixmap( "maximize" ), QString(), this ); m_maximizeBtn->resize( m_buttonSize ); m_maximizeBtn->setFocusPolicy( Qt::NoFocus ); m_maximizeBtn->setCursor( Qt::ArrowCursor ); @@ -68,7 +68,7 @@ SubWindow::SubWindow( QWidget *parent, Qt::WindowFlags windowFlags ) : m_maximizeBtn->setToolTip( tr( "Maximize" ) ); connect( m_maximizeBtn, SIGNAL( clicked( bool ) ), this, SLOT( showMaximized() ) ); - m_restoreBtn = new QPushButton( embed::getIconPixmap( "restore" ), QString::null, this ); + m_restoreBtn = new QPushButton( embed::getIconPixmap( "restore" ), QString(), this ); m_restoreBtn->resize( m_buttonSize ); m_restoreBtn->setFocusPolicy( Qt::NoFocus ); m_restoreBtn->setCursor( Qt::ArrowCursor ); diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 2960a31a3..f13b2f2b0 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -513,7 +513,7 @@ void PianoRoll::markSemiTone( int i ) break; case stmaMarkCurrentSemiTone: { - QList::iterator it = qFind( m_markedSemiTones.begin(), m_markedSemiTones.end(), key ); + QList::iterator it = std::find( m_markedSemiTones.begin(), m_markedSemiTones.end(), key ); if( it != m_markedSemiTones.end() ) { m_markedSemiTones.erase( it ); @@ -534,7 +534,7 @@ void PianoRoll::markSemiTone( int i ) QList::iterator i; for (int ix = 0; ix < aok.size(); ++ix) { - i = qFind(m_markedSemiTones.begin(), m_markedSemiTones.end(), aok.at(ix)); + i = std::find(m_markedSemiTones.begin(), m_markedSemiTones.end(), aok.at(ix)); m_markedSemiTones.erase(i); } } @@ -588,7 +588,7 @@ void PianoRoll::markSemiTone( int i ) ; } - qSort( m_markedSemiTones.begin(), m_markedSemiTones.end(), qGreater() ); + std::sort( m_markedSemiTones.begin(), m_markedSemiTones.end(), std::greater() ); QList::iterator new_end = std::unique( m_markedSemiTones.begin(), m_markedSemiTones.end() ); m_markedSemiTones.erase( new_end, m_markedSemiTones.end() ); } diff --git a/src/gui/widgets/AutomatableButton.cpp b/src/gui/widgets/AutomatableButton.cpp index d760ab06f..1d9cecce8 100644 --- a/src/gui/widgets/AutomatableButton.cpp +++ b/src/gui/widgets/AutomatableButton.cpp @@ -220,7 +220,7 @@ void automatableButtonGroup::addButton( AutomatableButton * _btn ) void automatableButtonGroup::removeButton( AutomatableButton * _btn ) { - m_buttons.erase( qFind( m_buttons.begin(), m_buttons.end(), _btn ) ); + m_buttons.erase( std::find( m_buttons.begin(), m_buttons.end(), _btn ) ); _btn->m_group = NULL; } diff --git a/src/gui/widgets/ComboBox.cpp b/src/gui/widgets/ComboBox.cpp index 99a06c5d5..0673ee32d 100644 --- a/src/gui/widgets/ComboBox.cpp +++ b/src/gui/widgets/ComboBox.cpp @@ -47,7 +47,7 @@ const int CB_ARROW_BTN_WIDTH = 20; ComboBox::ComboBox( QWidget * _parent, const QString & _name ) : QWidget( _parent ), - IntModelView( new ComboBoxModel( NULL, QString::null, true ), this ), + IntModelView( new ComboBoxModel( NULL, QString(), true ), this ), m_menu( this ), m_pressed( false ) { diff --git a/src/gui/widgets/ControllerRackView.cpp b/src/gui/widgets/ControllerRackView.cpp index 79e1bafa0..621c41c73 100644 --- a/src/gui/widgets/ControllerRackView.cpp +++ b/src/gui/widgets/ControllerRackView.cpp @@ -176,7 +176,7 @@ void ControllerRackView::onControllerRemoved( Controller * removedController ) if (viewOfRemovedController ) { - m_controllerViews.erase( qFind( m_controllerViews.begin(), + m_controllerViews.erase( std::find( m_controllerViews.begin(), m_controllerViews.end(), viewOfRemovedController ) ); delete viewOfRemovedController; diff --git a/src/gui/widgets/EffectRackView.cpp b/src/gui/widgets/EffectRackView.cpp index c1e36547e..6af490a42 100644 --- a/src/gui/widgets/EffectRackView.cpp +++ b/src/gui/widgets/EffectRackView.cpp @@ -126,7 +126,7 @@ void EffectRackView::moveDown( EffectView* view ) if( view != m_effectViews.last() ) { // moving next effect up is the same - moveUp( *( qFind( m_effectViews.begin(), m_effectViews.end(), view ) + 1 ) ); + moveUp( *( std::find( m_effectViews.begin(), m_effectViews.end(), view ) + 1 ) ); } } @@ -136,7 +136,7 @@ void EffectRackView::moveDown( EffectView* view ) void EffectRackView::deletePlugin( EffectView* view ) { Effect * e = view->effect(); - m_effectViews.erase( qFind( m_effectViews.begin(), m_effectViews.end(), view ) ); + m_effectViews.erase( std::find( m_effectViews.begin(), m_effectViews.end(), view ) ); delete view; fxChain()->removeEffect( e ); e->deleteLater(); diff --git a/src/gui/widgets/Graph.cpp b/src/gui/widgets/Graph.cpp index ed57dcea6..e9a00c304 100644 --- a/src/gui/widgets/Graph.cpp +++ b/src/gui/widgets/Graph.cpp @@ -510,7 +510,7 @@ void graphModel::setSampleAt( int x, float val ) void graphModel::setSamples( const float * _samples ) { - qCopy( _samples, _samples + length(), m_samples.begin()); + std::copy( _samples, _samples + length(), m_samples.begin()); emit samplesChanged( 0, length()-1 ); } diff --git a/src/gui/widgets/LadspaControlView.cpp b/src/gui/widgets/LadspaControlView.cpp index 800eae4e9..39ed1c3ea 100644 --- a/src/gui/widgets/LadspaControlView.cpp +++ b/src/gui/widgets/LadspaControlView.cpp @@ -60,7 +60,7 @@ LadspaControlView::LadspaControlView( QWidget * _parent, case TOGGLED: { LedCheckBox * toggle = new LedCheckBox( - m_ctl->port()->name, this, QString::null, LedCheckBox::Green ); + m_ctl->port()->name, this, QString(), LedCheckBox::Green ); toggle->setModel( m_ctl->toggledModel() ); layout->addWidget( toggle ); if( link != NULL ) diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 5b4a255d1..e1101580f 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -496,7 +496,7 @@ QString InstrumentTrack::instrumentName() const { return m_instrument->displayName(); } - return QString::null; + return QString(); } From 1bae047b98558981c20c85edc44550f4aa9714d9 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 18 Jun 2018 10:58:45 +0900 Subject: [PATCH 025/445] Fix wrong accelerator character in sv.ts Fixes #4415 --- data/locale/sv.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/locale/sv.ts b/data/locale/sv.ts index 173b1f76e..74153c7e9 100644 --- a/data/locale/sv.ts +++ b/data/locale/sv.ts @@ -3939,7 +3939,7 @@ Besök https://lmms.io/documentation/ för dokumentation (Engelska). &View - %Visa + &Visa Toggle metronome @@ -9950,4 +9950,4 @@ The LED in the lower right corner of the waveform editor determines whether the Utgångsförstärkning - \ No newline at end of file + From b52861f19f174d20b868466ef61bd25fdb2785fd Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 18 Jun 2018 12:35:17 +0900 Subject: [PATCH 026/445] Fixup 1bae047b98558981c20c85edc44550f4aa9714d9 --- data/locale/sv.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/locale/sv.ts b/data/locale/sv.ts index 74153c7e9..ec36538f0 100644 --- a/data/locale/sv.ts +++ b/data/locale/sv.ts @@ -3939,7 +3939,7 @@ Besök https://lmms.io/documentation/ för dokumentation (Engelska). &View - &Visa + &Visa Toggle metronome From 6af5154bec3a7807be64d67ad80983f8c69d58b3 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 19 Jun 2018 09:32:11 +0900 Subject: [PATCH 027/445] LADSPA: Fix undefined reference due to vectorization (#4434) --- plugins/LadspaEffect/swh/CMakeLists.txt | 22 ++++++++++------------ plugins/LadspaEffect/tap/CMakeLists.txt | 11 +++-------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/plugins/LadspaEffect/swh/CMakeLists.txt b/plugins/LadspaEffect/swh/CMakeLists.txt index a14fc1428..07893c8a4 100644 --- a/plugins/LadspaEffect/swh/CMakeLists.txt +++ b/plugins/LadspaEffect/swh/CMakeLists.txt @@ -7,6 +7,11 @@ LINK_DIRECTORIES(${FFTW3F_LIBRARY_DIRS}) FILE(GLOB PLUGIN_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.c") LIST(SORT PLUGIN_SOURCES) +SET(COMPILE_FLAGS "${COMPILE_FLAGS} -O3 -Wall -fomit-frame-pointer -funroll-loops -ffast-math -fno-strict-aliasing") +IF(NOT LMMS_BUILD_WIN32) + SET(COMPILE_FLAGS "${COMPILE_FLAGS} -fPIC -DPIC") +ENDIF() + FOREACH(_item ${PLUGIN_SOURCES}) GET_FILENAME_COMPONENT(_plugin "${_item}" NAME_WE) @@ -15,22 +20,15 @@ FOREACH(_item ${PLUGIN_SOURCES}) IF(NOT ("${_plugin}" STREQUAL "vocoder_1337")) TARGET_LINK_LIBRARIES("${_plugin}" -lfftw3f) ENDIF() + IF(NOT MSVC) + TARGET_LINK_LIBRARIES("${_plugin}" m) + ENDIF() INSTALL(TARGETS "${_plugin}" LIBRARY DESTINATION "${PLUGIN_DIR}/ladspa") SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES PREFIX "") - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES COMPILE_FLAGS "-O3 -Wall -fomit-frame-pointer -fstrength-reduce -funroll-loops -ffast-math -c -fno-strict-aliasing") IF(LMMS_BUILD_WIN32) ADD_CUSTOM_COMMAND(TARGET "${_plugin}" POST_BUILD COMMAND "${STRIP}" \"$\") - ELSE(LMMS_BUILD_WIN32) - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -fPIC -DPIC") - ENDIF(LMMS_BUILD_WIN32) - IF(LMMS_BUILD_APPLE) - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Bsymbolic -lm") - ELSEIF(NOT LMMS_BUILD_APPLE AND NOT LMMS_BUILD_OPENBSD) - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -Wl,-no-undefined -Wl,-Bsymbolic -lm") - ENDIF(LMMS_BUILD_APPLE) - IF(LMMS_BUILD_LINUX OR LMMS_BUILD_HAIKU) - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES LINK_FLAGS "${LINK_FLAGS}") - ENDIF(LMMS_BUILD_LINUX OR LMMS_BUILD_HAIKU) + ENDIF() + SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS}") ENDFOREACH(_item ${PLUGIN_SOURCES}) diff --git a/plugins/LadspaEffect/tap/CMakeLists.txt b/plugins/LadspaEffect/tap/CMakeLists.txt index 309283da6..02e131ce7 100644 --- a/plugins/LadspaEffect/tap/CMakeLists.txt +++ b/plugins/LadspaEffect/tap/CMakeLists.txt @@ -10,13 +10,8 @@ FOREACH(_item ${PLUGIN_SOURCES}) IF(LMMS_BUILD_WIN32) ADD_CUSTOM_COMMAND(TARGET "${_plugin}" POST_BUILD COMMAND "${STRIP}" \"$\") ENDIF(LMMS_BUILD_WIN32) - IF(LMMS_BUILD_APPLE) - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Bsymbolic -lm") - ELSEIF(NOT LMMS_BUILD_OPENBSD) - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -Wl,-no-undefined -Wl,-Bsymbolic -lm") - ENDIF(LMMS_BUILD_APPLE) - IF(LMMS_BUILD_LINUX OR LMMS_BUILD_HAIKU) - SET_TARGET_PROPERTIES("${_plugin}" PROPERTIES LINK_FLAGS "${LINK_FLAGS}") - ENDIF(LMMS_BUILD_LINUX OR LMMS_BUILD_HAIKU) + IF(NOT MSVC) + TARGET_LINK_LIBRARIES("${_plugin}" m) + ENDIF() ENDFOREACH(_item ${PLUGIN_SOURCES}) From 583e42e5bb5e7546e6e93923b29e5867772d54ae Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Tue, 19 Jun 2018 21:59:12 +0200 Subject: [PATCH 028/445] Quit exit if failing to save project (#4428) * Quit exiting when failing to save project *Test outcome of save in MainWindow::saveProjectAsNewVersion() --- src/gui/MainWindow.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 18bd49144..6ff55f06f 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -943,15 +943,15 @@ bool MainWindow::saveProject() { return( saveProjectAs() ); } - else + else if( Engine::getSong()->guiSaveProject() ) { - Engine::getSong()->guiSaveProject(); if( getSession() == Recover ) { sessionCleanup(); } + return true; } - return( true ); + return false; } @@ -997,14 +997,16 @@ bool MainWindow::saveProjectAs() } } } - Engine::getSong()->guiSaveProjectAs( fname ); - if( getSession() == Recover ) + if( Engine::getSong()->guiSaveProjectAs( fname ) ) { - sessionCleanup(); + if( getSession() == Recover ) + { + sessionCleanup(); + } + return true; } - return( true ); } - return( false ); + return false; } @@ -1022,8 +1024,7 @@ bool MainWindow::saveProjectAsNewVersion() do VersionedSaveDialog::changeFileNameVersion( fileName, true ); while ( QFile( fileName ).exists() ); - Engine::getSong()->guiSaveProjectAs( fileName ); - return true; + return Engine::getSong()->guiSaveProjectAs( fileName ); } } From d1c36d7b9664a2bde688cf06e600c4dad8055429 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Tue, 19 Jun 2018 21:16:45 +0200 Subject: [PATCH 029/445] CMake: Fix errors when path contains spaces --- cmake/modules/BuildPlugin.cmake | 16 ++++++++-------- plugins/CMakeLists.txt | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cmake/modules/BuildPlugin.cmake b/cmake/modules/BuildPlugin.cmake index a107ef5ac..f1dd95db6 100644 --- a/cmake/modules/BuildPlugin.cmake +++ b/cmake/modules/BuildPlugin.cmake @@ -7,7 +7,7 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) CMAKE_PARSE_ARGUMENTS(PLUGIN "" "" "MOCFILES;EMBEDDED_RESOURCES;UICFILES;LINK" ${ARGN}) SET(PLUGIN_SOURCES ${PLUGIN_UNPARSED_ARGUMENTS}) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/src/gui) + INCLUDE_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/include" "${CMAKE_SOURCE_DIR}/src/gui") ADD_DEFINITIONS(-DPLUGIN_NAME=${PLUGIN_NAME}) @@ -20,15 +20,15 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) FILE(GLOB EXPANDED "${ARG}") LIST(SORT EXPANDED) FOREACH(ITEM ${EXPANDED}) - LIST(APPEND NEW_ARGS ${ITEM}) + LIST(APPEND NEW_ARGS "${ITEM}") ENDFOREACH() ENDFOREACH() SET(PLUGIN_EMBEDDED_RESOURCES ${NEW_ARGS}) - SET(ER_H ${CMAKE_CURRENT_BINARY_DIR}/embedded_resources.h) + SET(ER_H "${CMAKE_CURRENT_BINARY_DIR}/embedded_resources.h") ADD_CUSTOM_COMMAND(OUTPUT ${ER_H} COMMAND ${BIN2RES} - ARGS ${PLUGIN_EMBEDDED_RESOURCES} > ${ER_H} + ARGS ${PLUGIN_EMBEDDED_RESOURCES} > "${ER_H}" DEPENDS bin2res) ENDIF(ER_LEN) @@ -45,11 +45,11 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) ENDFOREACH(f) IF(LMMS_BUILD_APPLE) - LINK_DIRECTORIES(${CMAKE_BINARY_DIR}) + LINK_DIRECTORIES("${CMAKE_BINARY_DIR}") LINK_LIBRARIES(${QT_LIBRARIES}) ENDIF(LMMS_BUILD_APPLE) IF(LMMS_BUILD_WIN32) - LINK_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}) + LINK_DIRECTORIES("${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}") LINK_LIBRARIES(${QT_LIBRARIES}) ENDIF(LMMS_BUILD_WIN32) IF(LMMS_BUILD_MSYS AND CMAKE_BUILD_TYPE STREQUAL "Debug") @@ -73,12 +73,12 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) INSTALL(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION "${PLUGIN_DIR}") IF(LMMS_BUILD_APPLE) - SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LINK_FLAGS "-bundle_loader ${CMAKE_BINARY_DIR}/lmms") + SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LINK_FLAGS "-bundle_loader \"${CMAKE_BINARY_DIR}/lmms\"") ADD_DEPENDENCIES(${PLUGIN_NAME} lmms) ENDIF(LMMS_BUILD_APPLE) IF(LMMS_BUILD_WIN32) SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES PREFIX "") - ADD_CUSTOM_COMMAND(TARGET ${PLUGIN_NAME} POST_BUILD COMMAND ${STRIP} $) + ADD_CUSTOM_COMMAND(TARGET ${PLUGIN_NAME} POST_BUILD COMMAND ${STRIP} "$") ENDIF(LMMS_BUILD_WIN32) SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${ER_H} ${plugin_MOC_out}") diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 24c15e391..4a1196886 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -1,5 +1,5 @@ -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) -SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") +SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") # Enable C++11 ADD_DEFINITIONS(-std=c++0x) From c45a21aac3beb0bba4c1796cf591ea44d2f2bc46 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Wed, 20 Jun 2018 08:42:26 +0200 Subject: [PATCH 030/445] CMake: Fix FindSndio module Fixes a bug where the module would set SNDIO_LIBRARY to NOT-FOUND resulting in a CMake error when trying to link to ${SNDIO_LIBRARY}. --- cmake/modules/FindSndio.cmake | 20 +++++++++++--------- src/CMakeLists.txt | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/cmake/modules/FindSndio.cmake b/cmake/modules/FindSndio.cmake index bf5b24c39..3fcd71360 100644 --- a/cmake/modules/FindSndio.cmake +++ b/cmake/modules/FindSndio.cmake @@ -19,14 +19,16 @@ if(SNDIO_LIBRARY) get_filename_component(SNDIO_LIBRARY_DIR ${SNDIO_LIBRARY} PATH) endif(SNDIO_LIBRARY) -check_library_exists(sndio sio_open "${SNDIO_LIBRARY_DIR}" HAVE_SNDIO) -if(HAVE_SNDIO) - message(STATUS "Found sndio: ${SNDIO_LIBRARY}") -else(HAVE_SNDIO) - message(STATUS "sndio not found") +check_library_exists(sndio sio_open "${SNDIO_LIBRARY_DIR}" HAVE_SIO_OPEN) + +find_path(SNDIO_INCLUDE_DIR sndio.h) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(SNDIO DEFAULT_MSG SNDIO_LIBRARY SNDIO_INCLUDE_DIR HAVE_SIO_OPEN) + +if(SNDIO_FOUND) + set(SNDIO_INCLUDE_DIRS "${SNDIO_INCLUDE_DIR}") + set(SNDIO_LIBRARIES "${SNDIO_LIBRARY}") endif(HAVE_SNDIO) -set(SNDIO_FOUND ${HAVE_SNDIO}) -find_path(SNDIO_INCLUDES sndio.h) - -mark_as_advanced(SNDIO_INCLUDES SNDIO_LIBRARY) +mark_as_advanced(SNDIO_INCLUDE_DIR SNDIO_LIBRARY SNDIO_INCLUDE_DIRS SNDIO_LIBRARIES) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 17695b5a0..b18fa897e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -138,7 +138,7 @@ SET(LMMS_REQUIRED_LIBS ${LMMS_REQUIRED_LIBS} ${SDL_LIBRARY} ${PORTAUDIO_LIBRARIES} ${SOUNDIO_LIBRARY} - ${SNDIO_LIBRARY} + ${SNDIO_LIBRARIES} ${PULSEAUDIO_LIBRARIES} ${JACK_LIBRARIES} ${OGGVORBIS_LIBRARIES} From c3575a4c17954d3af960f4140308e50fdbf2cf88 Mon Sep 17 00:00:00 2001 From: wadej Date: Fri, 4 May 2018 13:35:09 -0400 Subject: [PATCH 031/445] Ensure MSVC startup project is LMMS --- src/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ff0ca8a8e..cd3a37fcc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -107,6 +107,12 @@ ADD_EXECUTABLE(lmms "${WINRC}" ) +# Set Visual Studio startup project to lmms +# https://stackoverflow.com/a/37994396/8166701 +IF(NOT CMAKE_VERSION VERSION_LESS 3.6) + SET_PROPERTY(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT lmms) +ENDIF() + SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${LMMS_RCC_OUT} ${LMMS_UI_OUT} lmmsconfig.h lmms.1.gz") IF(LMMS_BUILD_WIN32) From 392c7534d5f18b9921c7cc8e917282afd1c76dc6 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Mon, 18 Jun 2018 16:21:44 +0200 Subject: [PATCH 032/445] Fix Clang compilation --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 34ca5a20f..a9c4404cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -539,7 +539,7 @@ ENDIF() # we somehow have to make LMMS-binary depend on MOC-files ADD_FILE_DEPENDENCIES("${CMAKE_BINARY_DIR}/lmmsconfig.h") -IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|AppleClang") +IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") IF(WIN32) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-attributes") ELSE(WIN32) From 28a522806bb1a670b460f0bfbf8d6147910dea72 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 27 Jun 2018 08:59:36 +0900 Subject: [PATCH 033/445] Fix hang on exit from specific MIDI devices + WinMM (#4451) --- src/core/midi/MidiWinMM.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/midi/MidiWinMM.cpp b/src/core/midi/MidiWinMM.cpp index a59ebc69e..ef60f3015 100644 --- a/src/core/midi/MidiWinMM.cpp +++ b/src/core/midi/MidiWinMM.cpp @@ -248,9 +248,13 @@ void MidiWinMM::closeDevices() m_outputSubs.clear(); QMapIterator i( m_inputDevices ); + + HMIDIIN hInDev; while( i.hasNext() ) { - midiInClose( i.next().key() ); + hInDev = i.next().key(); + midiInReset( hInDev ); + midiInClose( hInDev ); } QMapIterator o( m_outputDevices ); From e9f2b57107a5e4fed9e61d80dac87747b2adfbdd Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Thu, 28 Jun 2018 20:23:53 +0900 Subject: [PATCH 034/445] Fix project URL for some files They were created before https://github.com/LMMS/lmms/pull/3326 and added after it. --- include/MainApplication.h | 2 +- plugins/ReverbSC/ReverbSC.cpp | 2 +- plugins/ReverbSC/ReverbSC.h | 2 +- plugins/ReverbSC/ReverbSCControlDialog.cpp | 2 +- plugins/ReverbSC/ReverbSCControlDialog.h | 2 +- plugins/ReverbSC/ReverbSCControls.cpp | 2 +- plugins/ReverbSC/ReverbSCControls.h | 2 +- src/gui/MainApplication.cpp | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/MainApplication.h b/include/MainApplication.h index d3acb95ca..4edf55d5e 100644 --- a/include/MainApplication.h +++ b/include/MainApplication.h @@ -3,7 +3,7 @@ * * Copyright (c) 2017-2017 Tres Finocchiaro * - * This file is part of LMMS - http://lmms.io + * 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 diff --git a/plugins/ReverbSC/ReverbSC.cpp b/plugins/ReverbSC/ReverbSC.cpp index 4d938eb95..00c423784 100644 --- a/plugins/ReverbSC/ReverbSC.cpp +++ b/plugins/ReverbSC/ReverbSC.cpp @@ -1,7 +1,7 @@ /* * ReverbSC.cpp - A native reverb based on an algorithm by Sean Costello * - * This file is part of LMMS - http://lmms.io + * 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 diff --git a/plugins/ReverbSC/ReverbSC.h b/plugins/ReverbSC/ReverbSC.h index ba987414b..0e697c197 100644 --- a/plugins/ReverbSC/ReverbSC.h +++ b/plugins/ReverbSC/ReverbSC.h @@ -3,7 +3,7 @@ * * Copyright (c) 2017 Paul Batchelor * - * This file is part of LMMS - http://lmms.io + * 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 diff --git a/plugins/ReverbSC/ReverbSCControlDialog.cpp b/plugins/ReverbSC/ReverbSCControlDialog.cpp index e8c3c571a..71499c34a 100644 --- a/plugins/ReverbSC/ReverbSCControlDialog.cpp +++ b/plugins/ReverbSC/ReverbSCControlDialog.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 2017 Paul Batchelor * - * This file is part of LMMS - http://lmms.io + * 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 diff --git a/plugins/ReverbSC/ReverbSCControlDialog.h b/plugins/ReverbSC/ReverbSCControlDialog.h index 9f262a88f..0d9c1f51a 100644 --- a/plugins/ReverbSC/ReverbSCControlDialog.h +++ b/plugins/ReverbSC/ReverbSCControlDialog.h @@ -3,7 +3,7 @@ * * Copyright (c) 2017 Paul Batchelor * - * This file is part of LMMS - http://lmms.io + * 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 diff --git a/plugins/ReverbSC/ReverbSCControls.cpp b/plugins/ReverbSC/ReverbSCControls.cpp index 5e52d3faf..5d77ce0fc 100644 --- a/plugins/ReverbSC/ReverbSCControls.cpp +++ b/plugins/ReverbSC/ReverbSCControls.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 2017 Paul Batchelor * - * This file is part of LMMS - http://lmms.io + * 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 diff --git a/plugins/ReverbSC/ReverbSCControls.h b/plugins/ReverbSC/ReverbSCControls.h index 638bdade9..36cc16a7e 100644 --- a/plugins/ReverbSC/ReverbSCControls.h +++ b/plugins/ReverbSC/ReverbSCControls.h @@ -3,7 +3,7 @@ * * Copyright (c) 2017 Paul Batchelor * - * This file is part of LMMS - http://lmms.io + * 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 diff --git a/src/gui/MainApplication.cpp b/src/gui/MainApplication.cpp index 5210dd76c..994ae2771 100644 --- a/src/gui/MainApplication.cpp +++ b/src/gui/MainApplication.cpp @@ -3,7 +3,7 @@ * * Copyright (c) 2017-2017 Tres Finocchiaro * - * This file is part of LMMS - http://lmms.io + * 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 From 406bbcc2eeeaba194b8f2b0d1f6da325677088e3 Mon Sep 17 00:00:00 2001 From: Pikamander2 Date: Sun, 1 Jul 2018 22:37:05 -0400 Subject: [PATCH 035/445] Fix grammar on MIDI import dialog (#4457) --- plugins/MidiImport/MidiImport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/MidiImport/MidiImport.cpp b/plugins/MidiImport/MidiImport.cpp index 729c8b200..833994e5e 100644 --- a/plugins/MidiImport/MidiImport.cpp +++ b/plugins/MidiImport/MidiImport.cpp @@ -102,7 +102,7 @@ bool MidiImport::tryImport( TrackContainer* tc ) { QMessageBox::information( gui->mainWindow(), tr( "Setup incomplete" ), - tr( "You do not have set up a default soundfont in " + tr( "You have not 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 " From 792e4786ad4d21d3d118afffc08daad1141b8353 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Mon, 28 May 2018 22:15:39 +0900 Subject: [PATCH 036/445] Fix file name encoding issues with VST on Windows Fix plugin loading and setting loading/saving --- include/IoHelper.h | 72 ++++++++++++++++++++++++++++ plugins/vst_base/RemoteVstPlugin.cpp | 23 ++++----- 2 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 include/IoHelper.h diff --git a/include/IoHelper.h b/include/IoHelper.h new file mode 100644 index 000000000..687e000d1 --- /dev/null +++ b/include/IoHelper.h @@ -0,0 +1,72 @@ +/* + * IoHelper.h - helper functions for file I/O + * + * Copyright (c) 2018 Hyunjin Song + * + * 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 "lmmsconfig.h" + +#include + + +#ifdef _WIN32 +#include + +std::wstring toWString(const std::string& s) +{ + std::wstring ret; + int len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), + s.length(), nullptr, 0); + if (len == 0) + { + return ret; + } + ret.resize(len); + MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s.length(), &ret[0], len); + return ret; +} +#endif + +#ifdef LMMS_BUILD_WIN32 +#include +#define F_OPEN_UTF8(a, b) _wfopen(toWString(a).data(), L##b) +#else +#ifdef LMMS_HAVE_UNISTD_H +#include +#endif +#define F_OPEN_UTF8(a, b) fopen((a).data(), b) +#endif + +int fileToDescriptor(FILE* f, bool closeFile = true) +{ + int fh; + if (f == NULL) {return -1;} + +#ifdef LMMS_BUILD_WIN32 + fh = _dup(_fileno(f)); +#else + fh = dup(fileno(f)); +#endif + + if (closeFile) {fclose(f);} + return fh; +} diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index a51ac9d9a..174a80caa 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -88,6 +88,7 @@ struct ERect #include "lmms_basics.h" #include "Midi.h" #include "communication.h" +#include "IoHelper.h" #include "VstSyncData.h" @@ -678,9 +679,9 @@ void RemoteVstPlugin::init( const std::string & _plugin_file ) -static void close_check( int fd ) +static void close_check( FILE* fp ) { - if( close( fd ) ) + if( fclose( fp ) ) { perror( "close" ); } @@ -790,7 +791,7 @@ void RemoteVstPlugin::destroyEditor() bool RemoteVstPlugin::load( const std::string & _plugin_file ) { - if( ( m_libInst = LoadLibrary( _plugin_file.c_str() ) ) == NULL ) + if( ( m_libInst = LoadLibraryW( toWString(_plugin_file).c_str() ) ) == NULL ) { // give VstPlugin class a chance to start 32 bit version of RemoteVstPlugin if( GetLastError() == ERROR_BAD_EXE_FORMAT ) @@ -1072,13 +1073,13 @@ void RemoteVstPlugin::saveChunkToFile( const std::string & _file ) const int len = pluginDispatch( 23, 0, 0, &chunk ); if( len > 0 ) { - int fd = open( _file.c_str(), O_WRONLY | O_BINARY ); - if ( ::write( fd, chunk, len ) != len ) + FILE* fp = F_OPEN_UTF8( _file, "wb" ); + if ( fwrite( chunk, len, 1, fp ) != len ) { fprintf( stderr, "Error saving chunk to file.\n" ); } - close_check( fd ); + close_check( fp ); } } } @@ -1237,7 +1238,7 @@ void RemoteVstPlugin::savePreset( const std::string & _file ) if (!isPreset &&!chunky) uIntToFile = (unsigned int) m_plugin->numPrograms; pBank->numPrograms = endian_swap( uIntToFile ); - FILE * stream = fopen( _file.c_str(), "w" ); + FILE * stream = F_OPEN_UTF8( _file, "w" ); fwrite ( pBank, 1, 28, stream ); fwrite ( progName, 1, isPreset ? 28 : 128, stream ); if ( chunky ) { @@ -1289,7 +1290,7 @@ void RemoteVstPlugin::loadPresetFile( const std::string & _file ) unsigned int * pLen = new unsigned int[ 1 ]; unsigned int len = 0; sBank * pBank = (sBank*) new char[ sizeof( sBank ) ]; - FILE * stream = fopen( _file.c_str(), "r" ); + FILE * stream = F_OPEN_UTF8( _file, "r" ); if ( fread ( pBank, 1, 56, stream ) != 56 ) { fprintf( stderr, "Error loading preset file.\n" ); @@ -1390,12 +1391,12 @@ void RemoteVstPlugin::loadChunkFromFile( const std::string & _file, int _len ) { char * chunk = new char[_len]; - const int fd = open( _file.c_str(), O_RDONLY | O_BINARY ); - if ( ::read( fd, chunk, _len ) != _len ) + FILE* fp = F_OPEN_UTF8( _file, "rb" ); + if ( fread( chunk, 1, _len, fp ) != _len ) { fprintf( stderr, "Error loading chunk from file.\n" ); } - close_check( fd ); + close_check( fp ); pluginDispatch( effSetChunk, 0, _len, chunk ); From 9d0aae2708aed2fc0a18b16f31fef05f2496fd26 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Mon, 28 May 2018 22:34:19 +0900 Subject: [PATCH 037/445] Fix file name encoding issues with ZynAddSubFX on Windows --- .../zynaddsubfx/src/Misc/QtXmlWrapper.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/plugins/zynaddsubfx/zynaddsubfx/src/Misc/QtXmlWrapper.cpp b/plugins/zynaddsubfx/zynaddsubfx/src/Misc/QtXmlWrapper.cpp index 3ebc2eeec..bab513829 100644 --- a/plugins/zynaddsubfx/zynaddsubfx/src/Misc/QtXmlWrapper.cpp +++ b/plugins/zynaddsubfx/zynaddsubfx/src/Misc/QtXmlWrapper.cpp @@ -55,10 +55,13 @@ #include #include #include -#include "lmmsconfig.h" #include "../globals.h" #include "Util.h" +// Include LMMS headers +#include "lmmsconfig.h" +#include "IoHelper.h" + struct XmlData { @@ -193,11 +196,12 @@ int QtXmlWrapper::dosavefile(const char *filename, int compression, const char *xmldata) const { + FILE *file = F_OPEN_UTF8(std::string(filename), "w"); + if(file == NULL) { + return -1; + } + if(compression == 0) { - FILE *file; - file = fopen(filename, "w"); - if(file == NULL) - return -1; fputs(xmldata, file); fclose(file); } @@ -210,7 +214,7 @@ int QtXmlWrapper::dosavefile(const char *filename, snprintf(options, 10, "wb%d", compression); gzFile gzfile; - gzfile = gzopen(filename, options); + gzfile = gzdopen(fileToDescriptor(file), options); if(gzfile == NULL) return -1; gzputs(gzfile, xmldata); @@ -313,7 +317,8 @@ int QtXmlWrapper::loadXMLfile(const std::string &filename) char *QtXmlWrapper::doloadfile(const std::string &filename) const { char *xmldata = NULL; - gzFile gzfile = gzopen(filename.c_str(), "rb"); + + gzFile gzfile = gzdopen(fileToDescriptor(F_OPEN_UTF8(filename, "rb")), "rb"); if(gzfile != NULL) { //The possibly compressed file opened std::stringstream strBuf; //reading stream From ddcae478d4a85a540f132ed38333776c5b9f95d0 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Tue, 29 May 2018 17:37:22 +0900 Subject: [PATCH 038/445] Fix sample file loading on Windows --- include/DrumSynth.h | 12 +++++++----- include/SampleBuffer.h | 6 +++--- src/core/DrumSynth.cpp | 24 +++++++++++++++--------- src/core/SampleBuffer.cpp | 35 +++++++++++++++++++---------------- 4 files changed, 44 insertions(+), 33 deletions(-) diff --git a/include/DrumSynth.h b/include/DrumSynth.h index 22d7d3071..f7e9b1d4c 100644 --- a/include/DrumSynth.h +++ b/include/DrumSynth.h @@ -30,22 +30,24 @@ #include #include "lmms_basics.h" +class QString; + class DrumSynth { public: DrumSynth() {}; - int GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels, sample_rate_t Fs); + int GetDSFileSamples(QString dsfile, int16_t *&wave, int channels, sample_rate_t Fs); private: float LoudestEnv(void); int LongestEnv(void); void UpdateEnv(int e, long t); - void GetEnv(int env, const char *sec, const char *key, const char *ini); + void GetEnv(int env, const char *sec, const char *key, QString ini); float waveform(float ph, int form); - int GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, const char *file); - int GetPrivateProfileInt(const char *sec, const char *key, int def, const char *file); - float GetPrivateProfileFloat(const char *sec, const char *key, float def, const char *file); + int GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, QString file); + int GetPrivateProfileInt(const char *sec, const char *key, int def, QString file); + float GetPrivateProfileFloat(const char *sec, const char *key, float def, QString file); }; diff --git a/include/SampleBuffer.h b/include/SampleBuffer.h index 66f4ec873..3acf2c10b 100644 --- a/include/SampleBuffer.h +++ b/include/SampleBuffer.h @@ -270,15 +270,15 @@ private: void convertIntToFloat ( int_sample_t * & _ibuf, f_cnt_t _frames, int _channels); void directFloatWrite ( sample_t * & _fbuf, f_cnt_t _frames, int _channels); - f_cnt_t decodeSampleSF( const char * _f, sample_t * & _buf, + f_cnt_t decodeSampleSF( QString _f, sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _sample_rate ); #ifdef LMMS_HAVE_OGGVORBIS - f_cnt_t decodeSampleOGGVorbis( const char * _f, int_sample_t * & _buf, + f_cnt_t decodeSampleOGGVorbis( QString _f, int_sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _sample_rate ); #endif - f_cnt_t decodeSampleDS( const char * _f, int_sample_t * & _buf, + f_cnt_t decodeSampleDS( QString _f, int_sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _sample_rate ); diff --git a/src/core/DrumSynth.cpp b/src/core/DrumSynth.cpp index fd0695557..e1fb77793 100644 --- a/src/core/DrumSynth.cpp +++ b/src/core/DrumSynth.cpp @@ -26,11 +26,13 @@ #include "DrumSynth.h" -#include +#include #include #include //sin(), exp(), etc. +#include + #ifdef LMMS_BUILD_WIN32 #define powf pow #endif @@ -112,7 +114,7 @@ void DrumSynth::UpdateEnv(int e, long t) } -void DrumSynth::GetEnv(int env, const char *sec, const char *key, const char *ini) +void DrumSynth::GetEnv(int env, const char *sec, const char *key, QString ini) { char en[256], s[8]; int i=0, o=0, ep=0; @@ -162,9 +164,9 @@ float DrumSynth::waveform(float ph, int form) } -int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, const char *file) +int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const char *def, char *buffer, int size, QString file) { - ifstream is; + stringstream is; bool inSection = false; char *line; char *k, *b; @@ -172,7 +174,12 @@ int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const c line = (char*)malloc(200); - is.open (file, ifstream::in); + // Use QFile to handle unicode file name on Windows + // Previously we used ifstream directly + QFile f(file); + f.open(QIODevice::ReadOnly); + QByteArray dat = f.readAll().constData(); + is.str(string(dat.constData(), dat.size())); while (is.good()) { if (!inSection) { @@ -218,13 +225,12 @@ int DrumSynth::GetPrivateProfileString(const char *sec, const char *key, const c strncpy(buffer, def, size); } - is.close(); free(line); return len; } -int DrumSynth::GetPrivateProfileInt(const char *sec, const char *key, int def, const char *file) +int DrumSynth::GetPrivateProfileInt(const char *sec, const char *key, int def, QString file) { char tmp[16]; int i=0; @@ -235,7 +241,7 @@ int DrumSynth::GetPrivateProfileInt(const char *sec, const char *key, int def, c return i; } -float DrumSynth::GetPrivateProfileFloat(const char *sec, const char *key, float def, const char *file) +float DrumSynth::GetPrivateProfileFloat(const char *sec, const char *key, float def, QString file) { char tmp[16]; float f=0.f; @@ -252,7 +258,7 @@ float DrumSynth::GetPrivateProfileFloat(const char *sec, const char *key, float // an associative array or something once we have a datastructure to load in to. // llama -int DrumSynth::GetDSFileSamples(const char *dsfile, int16_t *&wave, int channels, sample_rate_t Fs) +int DrumSynth::GetDSFileSamples(QString dsfile, int16_t *&wave, int channels, sample_rate_t Fs) { //input file char sec[32]; diff --git a/src/core/SampleBuffer.cpp b/src/core/SampleBuffer.cpp index 5fc640cb6..86f8fd55c 100644 --- a/src/core/SampleBuffer.cpp +++ b/src/core/SampleBuffer.cpp @@ -187,11 +187,6 @@ void SampleBuffer::update( bool _keep_settings ) else if( !m_audioFile.isEmpty() ) { QString file = tryToMakeAbsolute( m_audioFile ); -#ifdef LMMS_BUILD_WIN32 - char * f = qstrdup( file.toLocal8Bit().constData() ); -#else - char * f = qstrdup( file.toUtf8().constData() ); -#endif int_sample_t * buf = NULL; sample_t * fbuf = NULL; ch_cnt_t channels = DEFAULT_CHANNELS; @@ -205,10 +200,13 @@ void SampleBuffer::update( bool _keep_settings ) } else { + // Use QFile to handle unicode file names on Windows + QFile f(file); + f.open(QIODevice::ReadOnly); SNDFILE * snd_file; SF_INFO sf_info; sf_info.format = 0; - if( ( snd_file = sf_open( f, SFM_READ, &sf_info ) ) != NULL ) + if( ( snd_file = sf_open_fd( f.handle(), SFM_READ, &sf_info, false ) ) != NULL ) { f_cnt_t frames = sf_info.frames; int rate = sf_info.samplerate; @@ -218,6 +216,7 @@ void SampleBuffer::update( bool _keep_settings ) } sf_close( snd_file ); } + f.close(); } if( !fileLoadError ) @@ -228,28 +227,26 @@ void SampleBuffer::update( bool _keep_settings ) // decoder first if filename extension matches "ogg" if( m_frames == 0 && fileInfo.suffix() == "ogg" ) { - m_frames = decodeSampleOGGVorbis( f, buf, channels, samplerate ); + m_frames = decodeSampleOGGVorbis( file, buf, channels, samplerate ); } #endif if( m_frames == 0 ) { - m_frames = decodeSampleSF( f, fbuf, channels, + m_frames = decodeSampleSF( file, fbuf, channels, samplerate ); } #ifdef LMMS_HAVE_OGGVORBIS if( m_frames == 0 ) { - m_frames = decodeSampleOGGVorbis( f, buf, channels, + m_frames = decodeSampleOGGVorbis( file, buf, channels, samplerate ); } #endif if( m_frames == 0 ) { - m_frames = decodeSampleDS( f, buf, channels, + m_frames = decodeSampleDS( file, buf, channels, samplerate ); } - - delete[] f; } if ( m_frames == 0 || fileLoadError ) // if still no frames, bail @@ -405,7 +402,7 @@ void SampleBuffer::normalizeSampleRate( const sample_rate_t _src_sr, -f_cnt_t SampleBuffer::decodeSampleSF( const char * _f, +f_cnt_t SampleBuffer::decodeSampleSF(QString _f, sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _samplerate ) @@ -416,7 +413,11 @@ f_cnt_t SampleBuffer::decodeSampleSF( const char * _f, f_cnt_t frames = 0; bool sf_rr = false; - if( ( snd_file = sf_open( _f, SFM_READ, &sf_info ) ) != NULL ) + + // Use QFile to handle unicode file names on Windows + QFile f(_f); + f.open(QIODevice::ReadOnly); + if( ( snd_file = sf_open_fd( f.handle(), SFM_READ, &sf_info, false ) ) != NULL ) { frames = sf_info.frames; @@ -442,6 +443,8 @@ f_cnt_t SampleBuffer::decodeSampleSF( const char * _f, "sample %s: %s", _f, sf_strerror( NULL ) ); #endif } + f.close(); + //write down either directly or convert i->f depending on file type if ( frames > 0 && _buf != NULL ) @@ -507,7 +510,7 @@ long qfileTellCallback( void * _udata ) -f_cnt_t SampleBuffer::decodeSampleOGGVorbis( const char * _f, +f_cnt_t SampleBuffer::decodeSampleOGGVorbis( QString _f, int_sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _samplerate ) @@ -603,7 +606,7 @@ f_cnt_t SampleBuffer::decodeSampleOGGVorbis( const char * _f, -f_cnt_t SampleBuffer::decodeSampleDS( const char * _f, +f_cnt_t SampleBuffer::decodeSampleDS( QString _f, int_sample_t * & _buf, ch_cnt_t & _channels, sample_rate_t & _samplerate ) From 1af0f083eaad5c024c2b71e60eecabd199778790 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Tue, 29 May 2018 17:49:51 +0900 Subject: [PATCH 039/445] Fix WAV exporting on Windows --- include/AudioFileDevice.h | 4 ++++ src/core/audio/AudioFileWave.cpp | 19 ++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/include/AudioFileDevice.h b/include/AudioFileDevice.h index 7b6b81eab..e7177b30f 100644 --- a/include/AudioFileDevice.h +++ b/include/AudioFileDevice.h @@ -56,6 +56,10 @@ protected: return m_outputFile.isOpen(); } + inline int outputFileHandle() const + { + return m_outputFile.handle(); + } private: QFile m_outputFile; diff --git a/src/core/audio/AudioFileWave.cpp b/src/core/audio/AudioFileWave.cpp index 45e46b838..8a590a8b8 100644 --- a/src/core/audio/AudioFileWave.cpp +++ b/src/core/audio/AudioFileWave.cpp @@ -27,6 +27,9 @@ #include "endian_handling.h" #include "Mixer.h" +#include +#include + AudioFileWave::AudioFileWave( OutputSettings const & outputSettings, const ch_cnt_t channels, bool & successful, @@ -72,13 +75,15 @@ bool AudioFileWave::startEncoding() m_si.format |= SF_FORMAT_PCM_16; break; } - m_sf = sf_open( -#ifdef LMMS_BUILD_WIN32 - outputFile().toLocal8Bit().constData(), -#else - outputFile().toUtf8().constData(), -#endif - SFM_WRITE, &m_si ); + + // Use file handle to handle unicode file name on Windows + m_sf = sf_open_fd( outputFileHandle(), SFM_WRITE, &m_si, false ); + + if (!m_sf) + { + qWarning("Error: AudioFileWave::startEncoding: %s", sf_strerror(nullptr)); + return false; + } // Prevent fold overs when encountering clipped data sf_command(m_sf, SFC_SET_CLIPPING, NULL, SF_TRUE); From 3e538d510c135d6b6504298aa57135506397c708 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Mon, 4 Jun 2018 14:34:51 +0900 Subject: [PATCH 040/445] Fix MIDI import encoding issue on Windows --- include/ImportFilter.h | 5 +++++ plugins/MidiImport/MidiImport.cpp | 11 ++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/include/ImportFilter.h b/include/ImportFilter.h index 304de5fa4..1b6fe2b59 100644 --- a/include/ImportFilter.h +++ b/include/ImportFilter.h @@ -78,6 +78,11 @@ protected: return m_file.read( _data, _len ); } + inline QByteArray readAllData() + { + return m_file.readAll(); + } + inline void ungetChar( char _ch ) { m_file.ungetChar( _ch ); diff --git a/plugins/MidiImport/MidiImport.cpp b/plugins/MidiImport/MidiImport.cpp index 85d244ca5..5fde7acc7 100644 --- a/plugins/MidiImport/MidiImport.cpp +++ b/plugins/MidiImport/MidiImport.cpp @@ -26,9 +26,12 @@ #include #include #include +#include #include #include +#include + #include "MidiImport.h" #include "TrackContainer.h" #include "InstrumentTrack.h" @@ -279,8 +282,6 @@ public: bool MidiImport::readSMF( TrackContainer* tc ) { - QString filename = file().fileName(); - closeFile(); const int preTrackSteps = 2; QProgressDialog pd( TrackContainer::tr( "Importing MIDI-file..." ), @@ -291,7 +292,11 @@ bool MidiImport::readSMF( TrackContainer* tc ) pd.setValue( 0 ); - Alg_seq_ptr seq = new Alg_seq(filename.toLocal8Bit(), true); + std::stringstream stream; + QByteArray arr = readAllData(); + stream.str(std::string(arr.constData(), arr.size())); + + Alg_seq_ptr seq = new Alg_seq(stream, true); seq->convert_to_beats(); pd.setMaximum( seq->tracks() + preTrackSteps ); From 62d505b2e6af03f3f2d63ed7f23c254fa64b9f95 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Mon, 4 Jun 2018 14:41:03 +0900 Subject: [PATCH 041/445] Improve STK rawwave path encoding handling Still incomplete on Windows due to an upstream issue --- plugins/stk/mallets/mallets.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/stk/mallets/mallets.cpp b/plugins/stk/mallets/mallets.cpp index 5e5f35ffc..29b6aeb20 100644 --- a/plugins/stk/mallets/mallets.cpp +++ b/plugins/stk/mallets/mallets.cpp @@ -620,7 +620,7 @@ malletsSynth::malletsSynth( const StkFloat _pitch, { Stk::setSampleRate( _sample_rate ); Stk::setRawwavePath( QDir( ConfigManager::inst()->stkDir() ).absolutePath() - .toLatin1().constData() ); + .toLocal8Bit().constData() ); #ifndef LMMS_DEBUG Stk::showWarnings( false ); #endif @@ -670,7 +670,7 @@ malletsSynth::malletsSynth( const StkFloat _pitch, { Stk::setSampleRate( _sample_rate ); Stk::setRawwavePath( QDir( ConfigManager::inst()->stkDir() ).absolutePath() - .toLatin1().constData() ); + .toLocal8Bit().constData() ); #ifndef LMMS_DEBUG Stk::showWarnings( false ); #endif @@ -718,7 +718,7 @@ malletsSynth::malletsSynth( const StkFloat _pitch, { Stk::setSampleRate( _sample_rate ); Stk::setRawwavePath( QDir( ConfigManager::inst()->stkDir() ).absolutePath() - .toLatin1().constData() ); + .toLocal8Bit().constData() ); #ifndef LMMS_DEBUG Stk::showWarnings( false ); #endif From a7b0c99242cf7ce6b513df89bd3b37ce1408b833 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Wed, 13 Jun 2018 17:11:49 +0200 Subject: [PATCH 042/445] MSYS compilation fixes * Fix MSYS and processor detection when not using the provided toolchain file * Fix creation of import library (ENABLE_EXPORTS not working) --- cmake/modules/DetectMachine.cmake | 7 +++++-- cmake/nsis/CMakeLists.txt | 8 ++++---- cmake/toolchains/common/MSYS.cmake | 3 +-- cmake/toolchains/common/Win32.cmake | 2 ++ src/CMakeLists.txt | 10 +++++++++- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/cmake/modules/DetectMachine.cmake b/cmake/modules/DetectMachine.cmake index 14efad76a..a9cde461e 100644 --- a/cmake/modules/DetectMachine.cmake +++ b/cmake/modules/DetectMachine.cmake @@ -10,13 +10,16 @@ ELSE() SET(LMMS_BUILD_LINUX 1) ENDIF(WIN32) -# See build_winXX.sh for LMMS_BUILD_MSYS +# LMMS_BUILD_MSYS also set in build_winXX.sh +IF(LMMS_BUILD_WIN32 AND CMAKE_COMPILER_IS_GNUCXX AND DEFINED ENV{MSYSCON}) + SET(LMMS_BUILD_MSYS TRUE) +ENDIF() MESSAGE("PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") SET(LMMS_HOST_X86 FALSE) SET(LMMS_HOST_X86_64 FALSE) -IF(MSVC) +IF(NOT DEFINED WIN64) STRING(REGEX MATCH "86_64|amd64|AMD64" WIN64 "${CMAKE_SYSTEM_PROCESSOR}") ENDIF() diff --git a/cmake/nsis/CMakeLists.txt b/cmake/nsis/CMakeLists.txt index b21c920e5..065b20819 100644 --- a/cmake/nsis/CMakeLists.txt +++ b/cmake/nsis/CMakeLists.txt @@ -37,10 +37,10 @@ ENDIF() # Fix windows paths for msys IF(LMMS_BUILD_MSYS) - STRING(REGEX REPLACE "/" "\\\\\\\\" CPACK_PACKAGE_ICON "${CPACK_PACKAGE_ICON}") - STRING(REGEX REPLACE "/" "\\\\\\\\" CPACK_NSIS_MUI_ICON "${CPACK_NSIS_MUI_ICON}") - STRING(REGEX REPLACE "/" "\\\\\\\\" CPACK_NSIS_DEFINES "${CPACK_NSIS_DEFINES}") - STRING(REGEX REPLACE "/" "\\\\\\\\" CMAKE_BINARY_DIR_FIX "${CMAKE_BINARY_DIR}") + STRING(REPLACE "/" "\\\\" CPACK_PACKAGE_ICON "${CPACK_PACKAGE_ICON}") + STRING(REPLACE "/" "\\\\" CPACK_NSIS_MUI_ICON "${CPACK_NSIS_MUI_ICON}") + STRING(REPLACE "/" "\\\\" CPACK_NSIS_DEFINES "${CPACK_NSIS_DEFINES}") + STRING(REPLACE "/" "\\\\" CMAKE_BINARY_DIR_FIX "${CMAKE_BINARY_DIR}") # FIXME: there's no easy way to fix $INST_DIR, so we'll redefine it manually IF(WIN64) diff --git a/cmake/toolchains/common/MSYS.cmake b/cmake/toolchains/common/MSYS.cmake index dc295d670..1b377aeee 100644 --- a/cmake/toolchains/common/MSYS.cmake +++ b/cmake/toolchains/common/MSYS.cmake @@ -2,7 +2,6 @@ SET(CMAKE_FIND_ROOT_PATH ${MINGW_PREFIX}) SET(CMAKE_INSTALL_PREFIX ${MINGW_PREFIX}) - # Windows msys mingw ships with a mostly-suitable preconfigured environment SET(STRIP ${MINGW_PREFIX}/bin/strip) SET(CMAKE_RC_COMPILER ${MINGW_PREFIX}/bin/windres) @@ -34,4 +33,4 @@ IF(LMMS_BUILD_MSYS AND CMAKE_BUILD_TYPE STREQUAL "Debug") SET(QT_LIBRARIES "${QT_OVERRIDE_LIBRARIES}") ENDIF() -SET(LMMS_BUILD_MSYS 1) \ No newline at end of file +SET(LMMS_BUILD_MSYS 1) diff --git a/cmake/toolchains/common/Win32.cmake b/cmake/toolchains/common/Win32.cmake index 5a6fb103c..bc20775d6 100644 --- a/cmake/toolchains/common/Win32.cmake +++ b/cmake/toolchains/common/Win32.cmake @@ -2,3 +2,5 @@ SET(CMAKE_SYSTEM_NAME Windows) SET(CMAKE_SYSTEM_VERSION 1) SET(CMAKE_SYSTEM_PROCESSOR i686) + +SET(WIN64 FALSE) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 23be36820..84ddf4aee 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -178,6 +178,15 @@ IF(LMMS_BUILD_WIN32) LINK_FLAGS "${LINK_FLAGS} -mwindows" ENABLE_EXPORTS ON ) + + IF(LMMS_BUILD_MSYS) + # ENABLE_EXPORTS property has no effect in some MSYS2 configurations. + # Add the linker flag manually to create liblmms.dll.a import library + SET_PROPERTY(TARGET lmms + APPEND_STRING PROPERTY LINK_FLAGS -Wl,--out-implib,liblmms.dll.a + ) + ENDIF() + IF(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") ADD_CUSTOM_COMMAND(TARGET lmms POST_BUILD COMMAND "${STRIP}" "$") ENDIF() @@ -249,7 +258,6 @@ IF(LMMS_BUILD_WIN32) "${MINGW_PREFIX}/lib/libsoundio.dll" DESTINATION .) ENDIF() - ELSE(LMMS_BUILD_WIN32) IF(NOT LMMS_BUILD_APPLE) SET_TARGET_PROPERTIES(lmms PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Wl,-E") From 0f3b41f590ed8d573ce3891f6502f211d1be176a Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Sat, 7 Jul 2018 10:34:08 +0900 Subject: [PATCH 043/445] Fix fwrite parameter ordering --- plugins/vst_base/RemoteVstPlugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 174a80caa..127036cd0 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -1074,7 +1074,7 @@ void RemoteVstPlugin::saveChunkToFile( const std::string & _file ) if( len > 0 ) { FILE* fp = F_OPEN_UTF8( _file, "wb" ); - if ( fwrite( chunk, len, 1, fp ) != len ) + if ( fwrite( chunk, 1, len, fp ) != len ) { fprintf( stderr, "Error saving chunk to file.\n" ); From 966bf1c6de97cbcf67457f16e5dc8ce5d227699a Mon Sep 17 00:00:00 2001 From: Lukas W Date: Fri, 24 Nov 2017 21:00:51 +0100 Subject: [PATCH 044/445] Use CMake GenerateExportHeader --- CMakeLists.txt | 1 + cmake/modules/BuildPlugin.cmake | 15 +++++- include/AutomatableButton.h | 4 +- include/AutomatableModel.h | 10 ++-- include/AutomatableModelView.h | 5 +- include/AutomationPattern.h | 2 +- include/BBTrack.h | 2 +- include/BBTrackContainer.h | 2 +- include/BandLimitedWave.h | 4 +- include/BufferManager.h | 4 +- include/CaptionMenu.h | 4 +- include/ComboBox.h | 2 +- include/ComboBoxModel.h | 2 +- include/ConfigManager.h | 4 +- include/Controller.h | 4 +- include/ControllerConnection.h | 2 +- include/DataFile.h | 6 +-- include/Effect.h | 2 +- include/EffectChain.h | 2 +- include/EffectControlDialog.h | 2 +- include/Engine.h | 4 +- include/EnvelopeAndLfoParameters.h | 2 +- include/ExportFilter.h | 2 +- include/Fader.h | 2 +- include/FileDialog.h | 4 +- include/FxMixer.h | 2 +- include/FxMixerView.h | 2 +- include/Graph.h | 4 +- include/GuiApplication.h | 4 +- include/ImportFilter.h | 2 +- include/Instrument.h | 4 +- include/InstrumentPlayHandle.h | 4 +- include/InstrumentTrack.h | 2 +- include/InstrumentView.h | 2 +- include/JournallingObject.h | 2 +- include/Knob.h | 2 +- include/Ladspa2LMMS.h | 2 +- include/LadspaControl.h | 2 +- include/LadspaControlView.h | 2 +- include/LadspaManager.h | 4 +- include/LcdSpinBox.h | 2 +- include/LcdWidget.h | 4 +- include/LedCheckbox.h | 2 +- include/LmmsPalette.h | 4 +- include/MainWindow.h | 2 +- include/MemoryManager.h | 4 +- include/MidiTime.h | 6 +-- include/Mixer.h | 2 +- include/Model.h | 4 +- include/ModelView.h | 2 +- include/Note.h | 2 +- include/NotePlayHandle.h | 2 +- include/Oscillator.h | 2 +- include/Pattern.h | 2 +- include/PeakController.h | 2 +- include/PixmapButton.h | 2 +- include/PlayHandle.h | 4 +- include/Plugin.h | 4 +- include/PluginFactory.h | 4 +- include/PluginView.h | 2 +- include/PresetPreviewPlayHandle.h | 2 +- include/ProjectNotes.h | 2 +- include/ProjectRenderer.h | 3 +- include/RemotePlugin.h | 10 ++-- include/RingBuffer.h | 2 +- include/SampleBuffer.h | 6 +-- include/SerializingObject.h | 4 +- include/Song.h | 2 +- include/StringPairDrag.h | 4 +- include/SubWindow.h | 4 +- include/TabBar.h | 4 +- include/TempoSyncKnob.h | 2 +- include/TempoSyncKnobModel.h | 2 +- include/TextFloat.h | 4 +- include/ToolPlugin.h | 2 +- include/ToolPluginView.h | 2 +- include/ToolTip.h | 4 +- include/Track.h | 2 +- include/TrackContainer.h | 2 +- include/ValueBuffer.h | 4 +- include/embed.h | 6 +-- include/export.h | 46 ------------------- include/fft_helpers.h | 14 +++--- plugins/Amplifier/Amplifier.cpp | 2 +- plugins/BassBooster/BassBooster.cpp | 2 +- plugins/Bitcrush/Bitcrush.cpp | 1 + plugins/CrossoverEQ/CrossoverEQ.cpp | 1 + plugins/Delay/DelayEffect.cpp | 2 +- plugins/DualFilter/DualFilter.cpp | 2 +- plugins/Eq/EqEffect.cpp | 3 +- plugins/Flanger/FlangerEffect.cpp | 2 + plugins/FreeBoy/FreeBoy.cpp | 2 + plugins/HydrogenImport/HydrogenImport.cpp | 2 + plugins/MidiExport/MidiExport.cpp | 1 + plugins/MidiImport/MidiImport.cpp | 4 +- plugins/MultitapEcho/MultitapEcho.cpp | 2 +- plugins/OpulenZ/OpulenZ.cpp | 2 + plugins/SpectrumAnalyzer/SpectrumAnalyzer.cpp | 2 +- .../audio_file_processor.cpp | 2 +- plugins/bit_invader/bit_invader.cpp | 2 + .../dynamics_processor/dynamics_processor.cpp | 1 + plugins/kicker/kicker.cpp | 2 +- plugins/ladspa_browser/ladspa_browser.cpp | 2 +- plugins/lb302/lb302.cpp | 2 +- plugins/nes/Nes.cpp | 1 + plugins/patman/patman.cpp | 2 +- .../peak_controller_effect.cpp | 1 + plugins/sfxr/sfxr.cpp | 2 + plugins/stereo_enhancer/stereo_enhancer.cpp | 2 +- plugins/stereo_matrix/stereo_matrix.cpp | 2 +- .../triple_oscillator/TripleOscillator.cpp | 2 +- plugins/watsyn/Watsyn.cpp | 1 + plugins/waveshaper/waveshaper.cpp | 1 + src/CMakeLists.txt | 12 +++++ 114 files changed, 196 insertions(+), 195 deletions(-) delete mode 100644 include/export.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a9c4404cb..2dbdf3963 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ INCLUDE(CheckSubmodules) INCLUDE(AddFileDependencies) INCLUDE(CheckIncludeFiles) INCLUDE(FindPkgConfig) +INCLUDE(GenerateExportHeader) STRING(TOUPPER "${CMAKE_PROJECT_NAME}" PROJECT_NAME_UCASE) diff --git a/cmake/modules/BuildPlugin.cmake b/cmake/modules/BuildPlugin.cmake index a527b8472..d0e3fa17a 100644 --- a/cmake/modules/BuildPlugin.cmake +++ b/cmake/modules/BuildPlugin.cmake @@ -6,7 +6,7 @@ INCLUDE(GenQrc) MACRO(BUILD_PLUGIN PLUGIN_NAME) - CMAKE_PARSE_ARGUMENTS(PLUGIN "" "" "MOCFILES;EMBEDDED_RESOURCES;UICFILES;LINK" ${ARGN}) + CMAKE_PARSE_ARGUMENTS(PLUGIN "" "LINK;EXPORT_BASE_NAME" "MOCFILES;EMBEDDED_RESOURCES;UICFILES" ${ARGN}) SET(PLUGIN_SOURCES ${PLUGIN_UNPARSED_ARGUMENTS}) INCLUDE_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/include") @@ -62,7 +62,7 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) TARGET_LINK_LIBRARIES(${PLUGIN_NAME} lmms) ENDIF(LMMS_BUILD_WIN32) - INSTALL(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION "${PLUGIN_DIR}") + INSTALL(TARGETS ${PLUGIN_NAME} DESTINATION "${PLUGIN_DIR}") IF(LMMS_BUILD_APPLE) SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LINK_FLAGS "-bundle_loader \"${CMAKE_BINARY_DIR}/lmms\"") @@ -74,5 +74,16 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) ENDIF() SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${RCC_OUT} ${plugin_MOC_out}") + + IF(NOT PLUGIN_EXPORT_BASE_NAME) + SET(PLUGIN_EXPORT_BASE_NAME "PLUGIN") + ENDIF() + + GENERATE_EXPORT_HEADER(${PLUGIN_NAME} + BASE_NAME ${PLUGIN_EXPORT_BASE_NAME} + ) + TARGET_INCLUDE_DIRECTORIES(${PLUGIN_NAME} + PUBLIC $ + ) ENDMACRO(BUILD_PLUGIN) diff --git a/include/AutomatableButton.h b/include/AutomatableButton.h index 014f1eed8..578063f16 100644 --- a/include/AutomatableButton.h +++ b/include/AutomatableButton.h @@ -34,7 +34,7 @@ class automatableButtonGroup; -class EXPORT AutomatableButton : public QPushButton, public BoolModelView +class LMMS_EXPORT AutomatableButton : public QPushButton, public BoolModelView { Q_OBJECT public: @@ -79,7 +79,7 @@ private: -class EXPORT automatableButtonGroup : public QWidget, public IntModelView +class LMMS_EXPORT automatableButtonGroup : public QWidget, public IntModelView { Q_OBJECT public: diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h index b04f3da9c..8dbe80efd 100644 --- a/include/AutomatableModel.h +++ b/include/AutomatableModel.h @@ -63,7 +63,7 @@ class ControllerConnection; -class EXPORT AutomatableModel : public Model, public JournallingObject +class LMMS_EXPORT AutomatableModel : public Model, public JournallingObject { Q_OBJECT MM_OPERATORS @@ -349,7 +349,7 @@ signals: -template class EXPORT TypedAutomatableModel : public AutomatableModel +template class LMMS_EXPORT TypedAutomatableModel : public AutomatableModel { public: using AutomatableModel::AutomatableModel; @@ -377,7 +377,7 @@ public: // some typed AutomatableModel-definitions -class EXPORT FloatModel : public TypedAutomatableModel +class LMMS_EXPORT FloatModel : public TypedAutomatableModel { Q_OBJECT public: @@ -394,7 +394,7 @@ public: } ; -class EXPORT IntModel : public TypedAutomatableModel +class LMMS_EXPORT IntModel : public TypedAutomatableModel { Q_OBJECT public: @@ -409,7 +409,7 @@ public: } ; -class EXPORT BoolModel : public TypedAutomatableModel +class LMMS_EXPORT BoolModel : public TypedAutomatableModel { Q_OBJECT public: diff --git a/include/AutomatableModelView.h b/include/AutomatableModelView.h index 3b320434f..964ffdc5d 100644 --- a/include/AutomatableModelView.h +++ b/include/AutomatableModelView.h @@ -32,7 +32,7 @@ class QMenu; class QMouseEvent; -class EXPORT AutomatableModelView : public ModelView +class LMMS_EXPORT AutomatableModelView : public ModelView { public: AutomatableModelView( Model* model, QWidget* _this ); @@ -106,7 +106,7 @@ protected: -template class EXPORT TypedModelView : public AutomatableModelView +template class LMMS_EXPORT TypedModelView : public AutomatableModelView { public: TypedModelView( Model* model, QWidget* _this) : @@ -127,6 +127,5 @@ using FloatModelView = TypedModelView; using IntModelView = TypedModelView; using BoolModelView = TypedModelView; - #endif diff --git a/include/AutomationPattern.h b/include/AutomationPattern.h index 89dcfed7c..070b6c669 100644 --- a/include/AutomationPattern.h +++ b/include/AutomationPattern.h @@ -38,7 +38,7 @@ class MidiTime; -class EXPORT AutomationPattern : public TrackContentObject +class LMMS_EXPORT AutomationPattern : public TrackContentObject { Q_OBJECT public: diff --git a/include/BBTrack.h b/include/BBTrack.h index 9e72c4f04..a906b54d2 100644 --- a/include/BBTrack.h +++ b/include/BBTrack.h @@ -125,7 +125,7 @@ private: -class EXPORT BBTrack : public Track +class LMMS_EXPORT BBTrack : public Track { Q_OBJECT public: diff --git a/include/BBTrackContainer.h b/include/BBTrackContainer.h index 0ac84b6d3..236325157 100644 --- a/include/BBTrackContainer.h +++ b/include/BBTrackContainer.h @@ -30,7 +30,7 @@ #include "ComboBoxModel.h" -class EXPORT BBTrackContainer : public TrackContainer +class LMMS_EXPORT BBTrackContainer : public TrackContainer { Q_OBJECT mapPropertyFromModel(int,currentBB,setCurrentBB,m_bbComboBoxModel); diff --git a/include/BandLimitedWave.h b/include/BandLimitedWave.h index 55f6e482c..386713328 100644 --- a/include/BandLimitedWave.h +++ b/include/BandLimitedWave.h @@ -29,7 +29,7 @@ class QDataStream; class QString; -#include "export.h" +#include "lmms_export.h" #include "interpolation.h" #include "lmms_basics.h" #include "lmms_math.h" @@ -82,7 +82,7 @@ QDataStream& operator>> ( QDataStream &in, WaveMipMap &waveMipMap ); -class EXPORT BandLimitedWave +class LMMS_EXPORT BandLimitedWave { public: enum Waveforms diff --git a/include/BufferManager.h b/include/BufferManager.h index 97c553ac9..20390644b 100644 --- a/include/BufferManager.h +++ b/include/BufferManager.h @@ -26,10 +26,10 @@ #ifndef BUFFER_MANAGER_H #define BUFFER_MANAGER_H -#include "export.h" +#include "lmms_export.h" #include "lmms_basics.h" -class EXPORT BufferManager +class LMMS_EXPORT BufferManager { public: static void init( fpp_t framesPerPeriod ); diff --git a/include/CaptionMenu.h b/include/CaptionMenu.h index 01aa3ca5e..e6531fe31 100644 --- a/include/CaptionMenu.h +++ b/include/CaptionMenu.h @@ -28,12 +28,12 @@ #include -#include "export.h" +#include "lmms_export.h" /// /// \brief A context menu with a caption /// -class EXPORT CaptionMenu : public QMenu +class LMMS_EXPORT CaptionMenu : public QMenu { Q_OBJECT public: diff --git a/include/ComboBox.h b/include/ComboBox.h index 99f7f8750..927c87620 100644 --- a/include/ComboBox.h +++ b/include/ComboBox.h @@ -34,7 +34,7 @@ -class EXPORT ComboBox : public QWidget, public IntModelView +class LMMS_EXPORT ComboBox : public QWidget, public IntModelView { Q_OBJECT public: diff --git a/include/ComboBoxModel.h b/include/ComboBoxModel.h index e4088679f..ad3603759 100644 --- a/include/ComboBoxModel.h +++ b/include/ComboBoxModel.h @@ -33,7 +33,7 @@ #include "embed.h" -class EXPORT ComboBoxModel : public IntModel +class LMMS_EXPORT ComboBoxModel : public IntModel { Q_OBJECT public: diff --git a/include/ConfigManager.h b/include/ConfigManager.h index 997d7f24c..dc5b9f485 100644 --- a/include/ConfigManager.h +++ b/include/ConfigManager.h @@ -34,7 +34,7 @@ #include #include -#include "export.h" +#include "lmms_export.h" class LmmsCore; @@ -51,7 +51,7 @@ const QString TRACK_ICON_PATH = "track_icons/"; const QString LOCALE_PATH = "locale/"; -class EXPORT ConfigManager : public QObject +class LMMS_EXPORT ConfigManager : public QObject { Q_OBJECT public: diff --git a/include/Controller.h b/include/Controller.h index 89a5e9371..d4fb94731 100644 --- a/include/Controller.h +++ b/include/Controller.h @@ -27,7 +27,7 @@ #ifndef CONTROLLER_H #define CONTROLLER_H -#include "export.h" +#include "lmms_export.h" #include "Engine.h" #include "Model.h" #include "JournallingObject.h" @@ -41,7 +41,7 @@ class ControllerConnection; typedef QVector ControllerVector; -class EXPORT Controller : public Model, public JournallingObject +class LMMS_EXPORT Controller : public Model, public JournallingObject { Q_OBJECT public: diff --git a/include/ControllerConnection.h b/include/ControllerConnection.h index e9cd543cb..5c4d5f20e 100644 --- a/include/ControllerConnection.h +++ b/include/ControllerConnection.h @@ -42,7 +42,7 @@ class ControllerConnection; typedef QVector ControllerConnectionVector; -class EXPORT ControllerConnection : public QObject, public JournallingObject +class LMMS_EXPORT ControllerConnection : public QObject, public JournallingObject { Q_OBJECT public: diff --git a/include/DataFile.h b/include/DataFile.h index 9e4ca13e3..5c634a6fa 100644 --- a/include/DataFile.h +++ b/include/DataFile.h @@ -29,12 +29,12 @@ #include -#include "export.h" +#include "lmms_export.h" #include "MemoryManager.h" class QTextStream; -class EXPORT DataFile : public QDomDocument +class LMMS_EXPORT DataFile : public QDomDocument { MM_OPERATORS public: @@ -134,7 +134,7 @@ private: void loadData( const QByteArray & _data, const QString & _sourceFile ); - struct EXPORT typeDescStruct + struct LMMS_EXPORT typeDescStruct { Type m_type; QString m_name; diff --git a/include/Effect.h b/include/Effect.h index 2147ab1c5..d6aa04d97 100644 --- a/include/Effect.h +++ b/include/Effect.h @@ -37,7 +37,7 @@ class EffectChain; class EffectControls; -class EXPORT Effect : public Plugin +class LMMS_EXPORT Effect : public Plugin { MM_OPERATORS Q_OBJECT diff --git a/include/EffectChain.h b/include/EffectChain.h index 5397fe81c..bc1e7df8c 100644 --- a/include/EffectChain.h +++ b/include/EffectChain.h @@ -33,7 +33,7 @@ class Effect; -class EXPORT EffectChain : public Model, public SerializingObject +class LMMS_EXPORT EffectChain : public Model, public SerializingObject { Q_OBJECT public: diff --git a/include/EffectControlDialog.h b/include/EffectControlDialog.h index d139de173..712f31217 100644 --- a/include/EffectControlDialog.h +++ b/include/EffectControlDialog.h @@ -33,7 +33,7 @@ class EffectControls; -class EXPORT EffectControlDialog : public QWidget, public ModelView +class LMMS_EXPORT EffectControlDialog : public QWidget, public ModelView { Q_OBJECT public: diff --git a/include/Engine.h b/include/Engine.h index 2f940dfbf..fc2547996 100644 --- a/include/Engine.h +++ b/include/Engine.h @@ -30,7 +30,7 @@ #include -#include "export.h" +#include "lmms_export.h" class BBTrackContainer; class DummyTrackContainer; @@ -53,7 +53,7 @@ class Ladspa2LMMS; class LmmsCore; typedef LmmsCore Engine; -class EXPORT LmmsCore : public QObject +class LMMS_EXPORT LmmsCore : public QObject { Q_OBJECT public: diff --git a/include/EnvelopeAndLfoParameters.h b/include/EnvelopeAndLfoParameters.h index 747bb94c2..4824062f3 100644 --- a/include/EnvelopeAndLfoParameters.h +++ b/include/EnvelopeAndLfoParameters.h @@ -34,7 +34,7 @@ #include "lmms_basics.h" -class EXPORT EnvelopeAndLfoParameters : public Model, public JournallingObject +class LMMS_EXPORT EnvelopeAndLfoParameters : public Model, public JournallingObject { Q_OBJECT public: diff --git a/include/ExportFilter.h b/include/ExportFilter.h index 35416f492..950bacbcd 100644 --- a/include/ExportFilter.h +++ b/include/ExportFilter.h @@ -32,7 +32,7 @@ #include "Plugin.h" -class EXPORT ExportFilter : public Plugin +class LMMS_EXPORT ExportFilter : public Plugin { public: ExportFilter( const Descriptor * _descriptor ) : Plugin( _descriptor, NULL ) {} diff --git a/include/Fader.h b/include/Fader.h index 80359b4c6..018f66e0c 100644 --- a/include/Fader.h +++ b/include/Fader.h @@ -57,7 +57,7 @@ class TextFloat; -class EXPORT Fader : public QWidget, public FloatModelView +class LMMS_EXPORT Fader : public QWidget, public FloatModelView { Q_OBJECT public: diff --git a/include/FileDialog.h b/include/FileDialog.h index 0cade9967..c3db2393d 100644 --- a/include/FileDialog.h +++ b/include/FileDialog.h @@ -28,9 +28,9 @@ #include -#include "export.h" +#include "lmms_export.h" -class EXPORT FileDialog : public QFileDialog +class LMMS_EXPORT FileDialog : public QFileDialog { Q_OBJECT public: diff --git a/include/FxMixer.h b/include/FxMixer.h index 053480a6a..2c7ef3c5a 100644 --- a/include/FxMixer.h +++ b/include/FxMixer.h @@ -121,7 +121,7 @@ class FxRoute : public QObject }; -class EXPORT FxMixer : public Model, public JournallingObject +class LMMS_EXPORT FxMixer : public Model, public JournallingObject { Q_OBJECT public: diff --git a/include/FxMixerView.h b/include/FxMixerView.h index 30c759838..9b07637ed 100644 --- a/include/FxMixerView.h +++ b/include/FxMixerView.h @@ -41,7 +41,7 @@ class QButtonGroup; class FxLine; -class EXPORT FxMixerView : public QWidget, public ModelView, +class LMMS_EXPORT FxMixerView : public QWidget, public ModelView, public SerializingObjectHook { Q_OBJECT diff --git a/include/Graph.h b/include/Graph.h index dc1d1fe16..b6de16371 100644 --- a/include/Graph.h +++ b/include/Graph.h @@ -38,7 +38,7 @@ class graphModel; -class EXPORT Graph : public QWidget, public ModelView +class LMMS_EXPORT Graph : public QWidget, public ModelView { Q_OBJECT public: @@ -111,7 +111,7 @@ private: } ; -class EXPORT graphModel : public Model +class LMMS_EXPORT graphModel : public Model { Q_OBJECT public: diff --git a/include/GuiApplication.h b/include/GuiApplication.h index 999db3009..8b4284c02 100644 --- a/include/GuiApplication.h +++ b/include/GuiApplication.h @@ -27,7 +27,7 @@ #include -#include "export.h" +#include "lmms_export.h" class QLabel; @@ -40,7 +40,7 @@ class PianoRollWindow; class ProjectNotes; class SongEditorWindow; -class EXPORT GuiApplication : public QObject +class LMMS_EXPORT GuiApplication : public QObject { Q_OBJECT; public: diff --git a/include/ImportFilter.h b/include/ImportFilter.h index 1b6fe2b59..1fc141a32 100644 --- a/include/ImportFilter.h +++ b/include/ImportFilter.h @@ -34,7 +34,7 @@ class TrackContainer; -class EXPORT ImportFilter : public Plugin +class LMMS_EXPORT ImportFilter : public Plugin { public: ImportFilter( const QString & _file_name, diff --git a/include/Instrument.h b/include/Instrument.h index ec7245dce..a373ae4ac 100644 --- a/include/Instrument.h +++ b/include/Instrument.h @@ -27,7 +27,7 @@ #define INSTRUMENT_H #include -#include "export.h" +#include "lmms_export.h" #include "lmms_basics.h" #include "MemoryManager.h" #include "MidiTime.h" @@ -41,7 +41,7 @@ class NotePlayHandle; class Track; -class EXPORT Instrument : public Plugin +class LMMS_EXPORT Instrument : public Plugin { MM_OPERATORS public: diff --git a/include/InstrumentPlayHandle.h b/include/InstrumentPlayHandle.h index f027b7d11..3463a128b 100644 --- a/include/InstrumentPlayHandle.h +++ b/include/InstrumentPlayHandle.h @@ -28,9 +28,9 @@ #include "PlayHandle.h" #include "Instrument.h" #include "NotePlayHandle.h" -#include "export.h" +#include "lmms_export.h" -class EXPORT InstrumentPlayHandle : public PlayHandle +class LMMS_EXPORT InstrumentPlayHandle : public PlayHandle { public: InstrumentPlayHandle( Instrument * instrument, InstrumentTrack* instrumentTrack ); diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index 5ef604def..fb12e825a 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -63,7 +63,7 @@ class LedCheckBox; class QLabel; -class EXPORT InstrumentTrack : public Track, public MidiEventProcessor +class LMMS_EXPORT InstrumentTrack : public Track, public MidiEventProcessor { Q_OBJECT MM_OPERATORS diff --git a/include/InstrumentView.h b/include/InstrumentView.h index d4f835708..9c6081a77 100644 --- a/include/InstrumentView.h +++ b/include/InstrumentView.h @@ -32,7 +32,7 @@ class InstrumentTrackWindow; -class EXPORT InstrumentView : public PluginView +class LMMS_EXPORT InstrumentView : public PluginView { public: InstrumentView( Instrument * _instrument, QWidget * _parent ); diff --git a/include/JournallingObject.h b/include/JournallingObject.h index f8e1a5950..6974bef84 100644 --- a/include/JournallingObject.h +++ b/include/JournallingObject.h @@ -31,7 +31,7 @@ #include "SerializingObject.h" -class EXPORT JournallingObject : public SerializingObject +class LMMS_EXPORT JournallingObject : public SerializingObject { public: JournallingObject(); diff --git a/include/Knob.h b/include/Knob.h index f6c9cfa99..319b38184 100644 --- a/include/Knob.h +++ b/include/Knob.h @@ -43,7 +43,7 @@ enum knobTypes -class EXPORT Knob : public QWidget, public FloatModelView +class LMMS_EXPORT Knob : public QWidget, public FloatModelView { Q_OBJECT Q_ENUMS( knobTypes ) diff --git a/include/Ladspa2LMMS.h b/include/Ladspa2LMMS.h index e5d35fbb1..14899487c 100644 --- a/include/Ladspa2LMMS.h +++ b/include/Ladspa2LMMS.h @@ -30,7 +30,7 @@ #include "LadspaManager.h" -class EXPORT Ladspa2LMMS : public LadspaManager +class LMMS_EXPORT Ladspa2LMMS : public LadspaManager { public: diff --git a/include/LadspaControl.h b/include/LadspaControl.h index 1cd8a304e..2ad895b3f 100644 --- a/include/LadspaControl.h +++ b/include/LadspaControl.h @@ -36,7 +36,7 @@ typedef struct PortDescription port_desc_t; -class EXPORT LadspaControl : public Model, public JournallingObject +class LMMS_EXPORT LadspaControl : public Model, public JournallingObject { Q_OBJECT public: diff --git a/include/LadspaControlView.h b/include/LadspaControlView.h index 34689af4e..d2d0ca44d 100644 --- a/include/LadspaControlView.h +++ b/include/LadspaControlView.h @@ -33,7 +33,7 @@ class LadspaControl; -class EXPORT LadspaControlView : public QWidget, public ModelView +class LMMS_EXPORT LadspaControlView : public QWidget, public ModelView { Q_OBJECT public: diff --git a/include/LadspaManager.h b/include/LadspaManager.h index 2338fbd4b..f9ac76eae 100644 --- a/include/LadspaManager.h +++ b/include/LadspaManager.h @@ -36,7 +36,7 @@ #include -#include "export.h" +#include "lmms_export.h" #include "lmms_basics.h" @@ -80,7 +80,7 @@ typedef struct ladspaManagerStorage } ladspaManagerDescription; -class EXPORT LadspaManager +class LMMS_EXPORT LadspaManager { public: diff --git a/include/LcdSpinBox.h b/include/LcdSpinBox.h index d6896f52b..ab04ec574 100644 --- a/include/LcdSpinBox.h +++ b/include/LcdSpinBox.h @@ -30,7 +30,7 @@ #include "AutomatableModelView.h" -class EXPORT LcdSpinBox : public LcdWidget, public IntModelView +class LMMS_EXPORT LcdSpinBox : public LcdWidget, public IntModelView { Q_OBJECT public: diff --git a/include/LcdWidget.h b/include/LcdWidget.h index 89bafd1d1..a9c551704 100644 --- a/include/LcdWidget.h +++ b/include/LcdWidget.h @@ -29,9 +29,9 @@ #include #include -#include "export.h" +#include "lmms_export.h" -class EXPORT LcdWidget : public QWidget +class LMMS_EXPORT LcdWidget : public QWidget { Q_OBJECT diff --git a/include/LedCheckbox.h b/include/LedCheckbox.h index b1c901ed6..00f74ac05 100644 --- a/include/LedCheckbox.h +++ b/include/LedCheckbox.h @@ -32,7 +32,7 @@ class QPixmap; -class EXPORT LedCheckBox : public AutomatableButton +class LMMS_EXPORT LedCheckBox : public AutomatableButton { Q_OBJECT public: diff --git a/include/LmmsPalette.h b/include/LmmsPalette.h index 5016ee978..49b831346 100644 --- a/include/LmmsPalette.h +++ b/include/LmmsPalette.h @@ -24,13 +24,13 @@ */ #include -#include "export.h" +#include "lmms_export.h" #ifndef LMMSPALETTE_H #define LMMSPALETTE_H -class EXPORT LmmsPalette : public QWidget +class LMMS_EXPORT LmmsPalette : public QWidget { Q_OBJECT Q_PROPERTY( QColor background READ background WRITE setBackground ) diff --git a/include/MainWindow.h b/include/MainWindow.h index 0c6addcdb..531cdfd52 100644 --- a/include/MainWindow.h +++ b/include/MainWindow.h @@ -61,7 +61,7 @@ public: void addSpacingToToolBar( int _size ); // wrap the widget with a window decoration and add it to the workspace - EXPORT SubWindow* addWindowedWidget(QWidget *w, Qt::WindowFlags windowFlags=0); + LMMS_EXPORT SubWindow* addWindowedWidget(QWidget *w, Qt::WindowFlags windowFlags=0); /// diff --git a/include/MemoryManager.h b/include/MemoryManager.h index 23561e4c0..4c225e026 100644 --- a/include/MemoryManager.h +++ b/include/MemoryManager.h @@ -30,9 +30,9 @@ #include #include -#include "export.h" +#include "lmms_export.h" -class EXPORT MemoryManager +class LMMS_EXPORT MemoryManager { public: struct ThreadGuard diff --git a/include/MidiTime.h b/include/MidiTime.h index 37fcf6258..7aaacf963 100644 --- a/include/MidiTime.h +++ b/include/MidiTime.h @@ -29,7 +29,7 @@ #include -#include "export.h" +#include "lmms_export.h" #include "lmms_basics.h" // note: 1 "Tact" = 1 Measure @@ -40,7 +40,7 @@ const int DefaultBeatsPerTact = DefaultTicksPerTact / DefaultStepsPerTact; class MeterModel; -class EXPORT TimeSig +class LMMS_EXPORT TimeSig { public: // in a time signature, @@ -57,7 +57,7 @@ private: }; -class EXPORT MidiTime +class LMMS_EXPORT MidiTime { public: MidiTime( const tact_t tact, const tick_t ticks ); diff --git a/include/Mixer.h b/include/Mixer.h index 499205892..bd057753a 100644 --- a/include/Mixer.h +++ b/include/Mixer.h @@ -66,7 +66,7 @@ const Octaves BaseOctave = DefaultOctave; class MixerWorkerThread; -class EXPORT Mixer : public QObject +class LMMS_EXPORT Mixer : public QObject { Q_OBJECT public: diff --git a/include/Model.h b/include/Model.h index 55e735a05..290639cc1 100644 --- a/include/Model.h +++ b/include/Model.h @@ -28,10 +28,10 @@ #include #include -#include "export.h" +#include "lmms_export.h" -class EXPORT Model : public QObject +class LMMS_EXPORT Model : public QObject { Q_OBJECT public: diff --git a/include/ModelView.h b/include/ModelView.h index a1071ddc2..907cd14ef 100644 --- a/include/ModelView.h +++ b/include/ModelView.h @@ -29,7 +29,7 @@ #include "Model.h" -class EXPORT ModelView +class LMMS_EXPORT ModelView { public: ModelView( Model* model, QWidget* widget ); diff --git a/include/Note.h b/include/Note.h index c14f9d931..0eae8f6b0 100644 --- a/include/Note.h +++ b/include/Note.h @@ -78,7 +78,7 @@ const float MaxDetuning = 4 * 12.0f; -class EXPORT Note : public SerializingObject +class LMMS_EXPORT Note : public SerializingObject { public: Note( const MidiTime & length = MidiTime( 0 ), diff --git a/include/NotePlayHandle.h b/include/NotePlayHandle.h index f4b6c9ec4..c94a69c2c 100644 --- a/include/NotePlayHandle.h +++ b/include/NotePlayHandle.h @@ -42,7 +42,7 @@ typedef QList NotePlayHandleList; typedef QList ConstNotePlayHandleList; -class EXPORT NotePlayHandle : public PlayHandle, public Note +class LMMS_EXPORT NotePlayHandle : public PlayHandle, public Note { MM_OPERATORS public: diff --git a/include/Oscillator.h b/include/Oscillator.h index 6e89f9cb1..408e69dbc 100644 --- a/include/Oscillator.h +++ b/include/Oscillator.h @@ -39,7 +39,7 @@ class IntModel; -class EXPORT Oscillator +class LMMS_EXPORT Oscillator { MM_OPERATORS public: diff --git a/include/Pattern.h b/include/Pattern.h index 5924a0862..eddbed313 100644 --- a/include/Pattern.h +++ b/include/Pattern.h @@ -46,7 +46,7 @@ class SampleBuffer; -class EXPORT Pattern : public TrackContentObject +class LMMS_EXPORT Pattern : public TrackContentObject { Q_OBJECT public: diff --git a/include/PeakController.h b/include/PeakController.h index 39d7fded9..b2824f0ac 100644 --- a/include/PeakController.h +++ b/include/PeakController.h @@ -36,7 +36,7 @@ class PeakControllerEffect; typedef QVector PeakControllerEffectVector; -class EXPORT PeakController : public Controller +class LMMS_EXPORT PeakController : public Controller { Q_OBJECT public: diff --git a/include/PixmapButton.h b/include/PixmapButton.h index 9f6ef8071..e44f5d952 100644 --- a/include/PixmapButton.h +++ b/include/PixmapButton.h @@ -31,7 +31,7 @@ #include "AutomatableButton.h" -class EXPORT PixmapButton : public AutomatableButton +class LMMS_EXPORT PixmapButton : public AutomatableButton { Q_OBJECT public: diff --git a/include/PlayHandle.h b/include/PlayHandle.h index a1c8e5c33..1760e1ec7 100644 --- a/include/PlayHandle.h +++ b/include/PlayHandle.h @@ -28,7 +28,7 @@ #include #include -#include "export.h" +#include "lmms_export.h" #include "MemoryManager.h" @@ -40,7 +40,7 @@ class QThread; class Track; class AudioPort; -class EXPORT PlayHandle : public ThreadableJob +class LMMS_EXPORT PlayHandle : public ThreadableJob { public: enum Types diff --git a/include/Plugin.h b/include/Plugin.h index 793997635..a2cc7d696 100644 --- a/include/Plugin.h +++ b/include/Plugin.h @@ -41,7 +41,7 @@ class PluginView; class AutomatableModel; -class EXPORT Plugin : public Model, public JournallingObject +class LMMS_EXPORT Plugin : public Model, public JournallingObject { MM_OPERATORS Q_OBJECT @@ -78,7 +78,7 @@ public: return QString( supportedFileTypes ).split( QChar( ',' ) ).contains( extension ); } - class EXPORT SubPluginFeatures + class LMMS_EXPORT SubPluginFeatures { public: struct Key diff --git a/include/PluginFactory.h b/include/PluginFactory.h index fb3e8ea94..56d32c4e4 100644 --- a/include/PluginFactory.h +++ b/include/PluginFactory.h @@ -31,12 +31,12 @@ #include #include -#include "export.h" +#include "lmms_export.h" #include "Plugin.h" class QLibrary; -class EXPORT PluginFactory +class LMMS_EXPORT PluginFactory { public: struct PluginInfo diff --git a/include/PluginView.h b/include/PluginView.h index 414e2bcae..476d65acf 100644 --- a/include/PluginView.h +++ b/include/PluginView.h @@ -31,7 +31,7 @@ #include "ModelView.h" -class EXPORT PluginView : public QWidget, public ModelView +class LMMS_EXPORT PluginView : public QWidget, public ModelView { public: PluginView( Plugin * _plugin, QWidget * _parent ) : diff --git a/include/PresetPreviewPlayHandle.h b/include/PresetPreviewPlayHandle.h index 313c20897..57996fa17 100644 --- a/include/PresetPreviewPlayHandle.h +++ b/include/PresetPreviewPlayHandle.h @@ -32,7 +32,7 @@ class InstrumentTrack; class PreviewTrackContainer; -class EXPORT PresetPreviewPlayHandle : public PlayHandle +class LMMS_EXPORT PresetPreviewPlayHandle : public PlayHandle { public: PresetPreviewPlayHandle( const QString& presetFile, bool loadByPlugin = false, DataFile *dataFile = 0 ); diff --git a/include/ProjectNotes.h b/include/ProjectNotes.h index 4477b112f..ab82e4eeb 100644 --- a/include/ProjectNotes.h +++ b/include/ProjectNotes.h @@ -37,7 +37,7 @@ class QTextCharFormat; class QTextEdit; -class EXPORT ProjectNotes : public QMainWindow, public SerializingObject +class LMMS_EXPORT ProjectNotes : public QMainWindow, public SerializingObject { Q_OBJECT public: diff --git a/include/ProjectRenderer.h b/include/ProjectRenderer.h index acc512063..4f932ad34 100644 --- a/include/ProjectRenderer.h +++ b/include/ProjectRenderer.h @@ -30,8 +30,9 @@ #include "Mixer.h" #include "OutputSettings.h" +#include "lmms_export.h" -class ProjectRenderer : public QThread +class LMMS_EXPORT ProjectRenderer : public QThread { Q_OBJECT public: diff --git a/include/RemotePlugin.h b/include/RemotePlugin.h index e0df85003..0a14458f6 100644 --- a/include/RemotePlugin.h +++ b/include/RemotePlugin.h @@ -25,7 +25,7 @@ #ifndef REMOTE_PLUGIN_H #define REMOTE_PLUGIN_H -#include "export.h" +#include "lmms_export.h" #include "MidiEvent.h" #include "VstSyncData.h" @@ -79,8 +79,8 @@ typedef int32_t key_t; #ifdef BUILD_REMOTE_PLUGIN_CLIENT -#undef EXPORT -#define EXPORT +#undef LMMS_EXPORT +#define LMMS_EXPORT #define COMPILE_REMOTE_PLUGIN_BASE #ifndef SYNC_WITH_SHM_FIFO @@ -444,7 +444,7 @@ enum RemoteMessageIDs -class EXPORT RemotePluginBase +class LMMS_EXPORT RemotePluginBase { public: struct message @@ -768,7 +768,7 @@ private: } ; -class EXPORT RemotePlugin : public QObject, public RemotePluginBase +class LMMS_EXPORT RemotePlugin : public QObject, public RemotePluginBase { Q_OBJECT public: diff --git a/include/RingBuffer.h b/include/RingBuffer.h index 3386c1175..c761616bd 100644 --- a/include/RingBuffer.h +++ b/include/RingBuffer.h @@ -32,7 +32,7 @@ #include "lmms_math.h" #include "MemoryManager.h" -class EXPORT RingBuffer : public QObject +class LMMS_EXPORT RingBuffer : public QObject { Q_OBJECT MM_OPERATORS diff --git a/include/SampleBuffer.h b/include/SampleBuffer.h index 974da669f..26dda70a9 100644 --- a/include/SampleBuffer.h +++ b/include/SampleBuffer.h @@ -31,7 +31,7 @@ #include -#include "export.h" +#include "lmms_export.h" #include "interpolation.h" #include "lmms_basics.h" #include "lmms_math.h" @@ -48,7 +48,7 @@ class QRect; // may need to be higher - conversely, to optimize, some may work with lower values const f_cnt_t MARGIN[] = { 64, 64, 64, 4, 4 }; -class EXPORT SampleBuffer : public QObject, public sharedObject +class LMMS_EXPORT SampleBuffer : public QObject, public sharedObject { Q_OBJECT MM_OPERATORS @@ -58,7 +58,7 @@ public: LoopOn, LoopPingPong }; - class EXPORT handleState + class LMMS_EXPORT handleState { MM_OPERATORS public: diff --git a/include/SerializingObject.h b/include/SerializingObject.h index e82ac7fcb..b61794d7c 100644 --- a/include/SerializingObject.h +++ b/include/SerializingObject.h @@ -27,7 +27,7 @@ #include -#include "export.h" +#include "lmms_export.h" class QDomDocument; @@ -36,7 +36,7 @@ class QDomElement; class SerializingObjectHook; -class EXPORT SerializingObject +class LMMS_EXPORT SerializingObject { public: SerializingObject(); diff --git a/include/Song.h b/include/Song.h index 8b2c21316..1f012f1be 100644 --- a/include/Song.h +++ b/include/Song.h @@ -48,7 +48,7 @@ const bpm_t MaxTempo = 999; const tick_t MaxSongLength = 9999 * DefaultTicksPerTact; -class EXPORT Song : public TrackContainer +class LMMS_EXPORT Song : public TrackContainer { Q_OBJECT mapPropertyFromModel( int,getTempo,setTempo,m_tempoModel ); diff --git a/include/StringPairDrag.h b/include/StringPairDrag.h index a69d7d143..cebc3089a 100644 --- a/include/StringPairDrag.h +++ b/include/StringPairDrag.h @@ -31,12 +31,12 @@ #include #include -#include "export.h" +#include "lmms_export.h" class QPixmap; -class EXPORT StringPairDrag : public QDrag +class LMMS_EXPORT StringPairDrag : public QDrag { public: StringPairDrag( const QString & _key, const QString & _value, diff --git a/include/SubWindow.h b/include/SubWindow.h index 24485109e..067f9e312 100644 --- a/include/SubWindow.h +++ b/include/SubWindow.h @@ -34,7 +34,7 @@ #include #include -#include "export.h" +#include "lmms_export.h" class QMoveEvent; class QResizeEvent; @@ -48,7 +48,7 @@ class QWidget; * for cusomizing the title bar appearance, lmms implements its own subwindow * class. */ -class EXPORT SubWindow : public QMdiSubWindow +class LMMS_EXPORT SubWindow : public QMdiSubWindow { Q_OBJECT Q_PROPERTY( QBrush activeColor READ activeColor WRITE setActiveColor ) diff --git a/include/TabBar.h b/include/TabBar.h index 4ef0b1ac7..48b429bd5 100644 --- a/include/TabBar.h +++ b/include/TabBar.h @@ -30,13 +30,13 @@ #include #include -#include "export.h" +#include "lmms_export.h" class TabButton; -class EXPORT TabBar : public QWidget +class LMMS_EXPORT TabBar : public QWidget { Q_OBJECT public: diff --git a/include/TempoSyncKnob.h b/include/TempoSyncKnob.h index 343deb067..034e2b8f4 100644 --- a/include/TempoSyncKnob.h +++ b/include/TempoSyncKnob.h @@ -34,7 +34,7 @@ class MeterDialog; -class EXPORT TempoSyncKnob : public Knob +class LMMS_EXPORT TempoSyncKnob : public Knob { Q_OBJECT public: diff --git a/include/TempoSyncKnobModel.h b/include/TempoSyncKnobModel.h index 893e23eb4..9a8ad619c 100644 --- a/include/TempoSyncKnobModel.h +++ b/include/TempoSyncKnobModel.h @@ -30,7 +30,7 @@ class QAction; -class EXPORT TempoSyncKnobModel : public FloatModel +class LMMS_EXPORT TempoSyncKnobModel : public FloatModel { Q_OBJECT public: diff --git a/include/TextFloat.h b/include/TextFloat.h index 673e40e63..ed10516b5 100644 --- a/include/TextFloat.h +++ b/include/TextFloat.h @@ -29,10 +29,10 @@ #include #include -#include "export.h" +#include "lmms_export.h" -class EXPORT TextFloat : public QWidget +class LMMS_EXPORT TextFloat : public QWidget { Q_OBJECT public: diff --git a/include/ToolPlugin.h b/include/ToolPlugin.h index bc8b3cf18..8a65147ac 100644 --- a/include/ToolPlugin.h +++ b/include/ToolPlugin.h @@ -29,7 +29,7 @@ #include "Plugin.h" -class EXPORT ToolPlugin : public Plugin +class LMMS_EXPORT ToolPlugin : public Plugin { public: ToolPlugin( const Descriptor * _descriptor, Model * _parent ); diff --git a/include/ToolPluginView.h b/include/ToolPluginView.h index de0f8bb1e..2b64caaaf 100644 --- a/include/ToolPluginView.h +++ b/include/ToolPluginView.h @@ -30,7 +30,7 @@ class ToolPlugin; -class EXPORT ToolPluginView : public PluginView +class LMMS_EXPORT ToolPluginView : public PluginView { public: ToolPluginView( ToolPlugin * _toolPlugin ); diff --git a/include/ToolTip.h b/include/ToolTip.h index 76b571bca..7f769a05b 100644 --- a/include/ToolTip.h +++ b/include/ToolTip.h @@ -28,14 +28,14 @@ #include -#include "export.h" +#include "lmms_export.h" class QWidget; struct ToolTip { - static void EXPORT add( QWidget * _w, const QString & _txt ); + static void LMMS_EXPORT add( QWidget * _w, const QString & _txt ); } ; diff --git a/include/Track.h b/include/Track.h index 6ac6e390f..302dcb5cc 100644 --- a/include/Track.h +++ b/include/Track.h @@ -463,7 +463,7 @@ signals: // base-class for all tracks -class EXPORT Track : public Model, public JournallingObject +class LMMS_EXPORT Track : public Model, public JournallingObject { Q_OBJECT MM_OPERATORS diff --git a/include/TrackContainer.h b/include/TrackContainer.h index 33569c9d9..1caca922e 100644 --- a/include/TrackContainer.h +++ b/include/TrackContainer.h @@ -37,7 +37,7 @@ class InstrumentTrack; class TrackContainerView; -class EXPORT TrackContainer : public Model, public JournallingObject +class LMMS_EXPORT TrackContainer : public Model, public JournallingObject { Q_OBJECT public: diff --git a/include/ValueBuffer.h b/include/ValueBuffer.h index 1e714d455..f9869de88 100644 --- a/include/ValueBuffer.h +++ b/include/ValueBuffer.h @@ -29,9 +29,9 @@ #include #include "MemoryManager.h" -#include "export.h" +#include "lmms_export.h" -class EXPORT ValueBuffer : public std::vector +class LMMS_EXPORT ValueBuffer : public std::vector { MM_OPERATORS public: diff --git a/include/embed.h b/include/embed.h index 57ca743cd..6348331f7 100644 --- a/include/embed.h +++ b/include/embed.h @@ -28,15 +28,15 @@ #include #include -#include "export.h" +#include "lmms_export.h" #include "lmms_basics.h" namespace embed { -QPixmap EXPORT getIconPixmap( const QString& _name, int _w = -1, int _h = -1 ); -QString EXPORT getText( const char * _name ); +QPixmap LMMS_EXPORT getIconPixmap( const QString& _name, int _w = -1, int _h = -1 ); +QString LMMS_EXPORT getText( const char * _name ); } diff --git a/include/export.h b/include/export.h deleted file mode 100644 index dd3709704..000000000 --- a/include/export.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * export.h - macros for export-declarations - * - * Copyright (c) 2008 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 EXPORT_H -#define EXPORT_H - -#include "lmmsconfig.h" - -#ifdef LMMS_BUILD_WIN32 - -#ifdef PLUGIN_NAME -#define EXPORT __declspec(dllimport) -#define PLUGIN_EXPORT __declspec(dllexport) -#else -#define EXPORT __declspec(dllexport) -#endif - -#else - -#define EXPORT -#define PLUGIN_EXPORT - -#endif - -#endif diff --git a/include/fft_helpers.h b/include/fft_helpers.h index c28af0237..23450d2ca 100644 --- a/include/fft_helpers.h +++ b/include/fft_helpers.h @@ -26,7 +26,7 @@ #ifndef FFT_HELPERS_H #define FFT_HELPERS_H -#include "export.h" +#include "lmms_export.h" #include @@ -44,13 +44,13 @@ enum WINDOWS * * returns -1 on error */ -float EXPORT maximum( float * _abs_spectrum, unsigned int _spec_size ); +float LMMS_EXPORT maximum( float * _abs_spectrum, unsigned int _spec_size ); /* apply hanning or hamming window to channel * * returns -1 on error */ -int EXPORT hanming( float * _timebuffer, int _length, WINDOWS _type ); +int LMMS_EXPORT hanming( float * _timebuffer, int _length, WINDOWS _type ); /* compute absolute values of complex_buffer, save to absspec_buffer * take care that - compl_len is not bigger than complex_buffer! @@ -58,7 +58,7 @@ int EXPORT hanming( float * _timebuffer, int _length, WINDOWS _type ); * * returns 0 on success, else -1 */ -int EXPORT absspec( fftwf_complex * _complex_buffer, float * _absspec_buffer, +int LMMS_EXPORT absspec( fftwf_complex * _complex_buffer, float * _absspec_buffer, int _compl_length ); /* build fewer subbands from many absolute spectrum values @@ -67,11 +67,11 @@ int EXPORT absspec( fftwf_complex * _complex_buffer, float * _absspec_buffer, * * returns 0 on success, else -1 */ -int EXPORT compressbands( float * _absspec_buffer, float * _compressedband, +int LMMS_EXPORT compressbands( float * _absspec_buffer, float * _compressedband, int _num_old, int _num_new, int _bottom, int _top ); -int EXPORT calc13octaveband31( float * _absspec_buffer, float * _subbands, +int LMMS_EXPORT calc13octaveband31( float * _absspec_buffer, float * _subbands, int _num_spec, float _max_frequency ); /* compute power of finite time sequence @@ -79,6 +79,6 @@ int EXPORT calc13octaveband31( float * _absspec_buffer, float * _subbands, * * returns power on success, else -1 */ -float EXPORT signalpower(float *timesignal, int num_values); +float LMMS_EXPORT signalpower(float *timesignal, int num_values); #endif diff --git a/plugins/Amplifier/Amplifier.cpp b/plugins/Amplifier/Amplifier.cpp index c11fa6bcc..d90ea55b3 100644 --- a/plugins/Amplifier/Amplifier.cpp +++ b/plugins/Amplifier/Amplifier.cpp @@ -26,7 +26,7 @@ #include "Amplifier.h" #include "embed.h" - +#include "plugin_export.h" extern "C" { diff --git a/plugins/BassBooster/BassBooster.cpp b/plugins/BassBooster/BassBooster.cpp index f7387b46e..6fdb1671c 100644 --- a/plugins/BassBooster/BassBooster.cpp +++ b/plugins/BassBooster/BassBooster.cpp @@ -25,7 +25,7 @@ #include "BassBooster.h" #include "embed.h" - +#include "plugin_export.h" extern "C" { diff --git a/plugins/Bitcrush/Bitcrush.cpp b/plugins/Bitcrush/Bitcrush.cpp index 918b8efdd..0580d47cd 100644 --- a/plugins/Bitcrush/Bitcrush.cpp +++ b/plugins/Bitcrush/Bitcrush.cpp @@ -25,6 +25,7 @@ #include "Bitcrush.h" #include "embed.h" +#include "plugin_export.h" const int OS_RATE = 5; const float OS_RATIO = 1.0f / OS_RATE; diff --git a/plugins/CrossoverEQ/CrossoverEQ.cpp b/plugins/CrossoverEQ/CrossoverEQ.cpp index 3dc0e8265..e7d3dce7d 100644 --- a/plugins/CrossoverEQ/CrossoverEQ.cpp +++ b/plugins/CrossoverEQ/CrossoverEQ.cpp @@ -27,6 +27,7 @@ #include "CrossoverEQ.h" #include "lmms_math.h" #include "embed.h" +#include "plugin_export.h" extern "C" { diff --git a/plugins/Delay/DelayEffect.cpp b/plugins/Delay/DelayEffect.cpp index 0161178b8..0daad0d9d 100644 --- a/plugins/Delay/DelayEffect.cpp +++ b/plugins/Delay/DelayEffect.cpp @@ -26,7 +26,7 @@ #include "Engine.h" #include "embed.h" #include "interpolation.h" - +#include "plugin_export.h" extern "C" { diff --git a/plugins/DualFilter/DualFilter.cpp b/plugins/DualFilter/DualFilter.cpp index 94450cc6f..5b8b7a622 100644 --- a/plugins/DualFilter/DualFilter.cpp +++ b/plugins/DualFilter/DualFilter.cpp @@ -27,7 +27,7 @@ #include "embed.h" #include "BasicFilters.h" - +#include "plugin_export.h" extern "C" { diff --git a/plugins/Eq/EqEffect.cpp b/plugins/Eq/EqEffect.cpp index 64b43e5a5..6b7c61bcc 100644 --- a/plugins/Eq/EqEffect.cpp +++ b/plugins/Eq/EqEffect.cpp @@ -24,12 +24,13 @@ #include "EqEffect.h" -#include "embed.h" #include "Engine.h" #include "EqFader.h" #include "interpolation.h" #include "lmms_math.h" +#include "embed.h" +#include "plugin_export.h" extern "C" { diff --git a/plugins/Flanger/FlangerEffect.cpp b/plugins/Flanger/FlangerEffect.cpp index 1404c06b0..7e441cf62 100644 --- a/plugins/Flanger/FlangerEffect.cpp +++ b/plugins/Flanger/FlangerEffect.cpp @@ -24,7 +24,9 @@ #include "FlangerEffect.h" #include "Engine.h" + #include "embed.h" +#include "plugin_export.h" extern "C" { diff --git a/plugins/FreeBoy/FreeBoy.cpp b/plugins/FreeBoy/FreeBoy.cpp index 75391e452..1f720b825 100644 --- a/plugins/FreeBoy/FreeBoy.cpp +++ b/plugins/FreeBoy/FreeBoy.cpp @@ -42,6 +42,8 @@ #include "embed.h" +#include "plugin_export.h" + const blip_time_t FRAME_LENGTH = 70224; const long CLOCK_RATE = 4194304; diff --git a/plugins/HydrogenImport/HydrogenImport.cpp b/plugins/HydrogenImport/HydrogenImport.cpp index c7536e87e..9f9f1dd49 100644 --- a/plugins/HydrogenImport/HydrogenImport.cpp +++ b/plugins/HydrogenImport/HydrogenImport.cpp @@ -19,6 +19,8 @@ #include "BBTrackContainer.h" #include "Instrument.h" +#include "plugin_export.h" + #define MAX_LAYERS 4 extern "C" { diff --git a/plugins/MidiExport/MidiExport.cpp b/plugins/MidiExport/MidiExport.cpp index d691c4830..fde08646f 100644 --- a/plugins/MidiExport/MidiExport.cpp +++ b/plugins/MidiExport/MidiExport.cpp @@ -37,6 +37,7 @@ #include "BBTrack.h" #include "InstrumentTrack.h" +#include "plugin_export.h" extern "C" { diff --git a/plugins/MidiImport/MidiImport.cpp b/plugins/MidiImport/MidiImport.cpp index 1200c6f78..46fac9299 100644 --- a/plugins/MidiImport/MidiImport.cpp +++ b/plugins/MidiImport/MidiImport.cpp @@ -44,9 +44,11 @@ #include "MainWindow.h" #include "MidiTime.h" #include "debug.h" -#include "embed.h" #include "Song.h" +#include "embed.h" +#include "plugin_export.h" + #include "portsmf/allegro.h" #define makeID(_c0, _c1, _c2, _c3) \ diff --git a/plugins/MultitapEcho/MultitapEcho.cpp b/plugins/MultitapEcho/MultitapEcho.cpp index be46a50c6..bff032dee 100644 --- a/plugins/MultitapEcho/MultitapEcho.cpp +++ b/plugins/MultitapEcho/MultitapEcho.cpp @@ -25,7 +25,7 @@ #include "MultitapEcho.h" #include "embed.h" - +#include "plugin_export.h" extern "C" { diff --git a/plugins/OpulenZ/OpulenZ.cpp b/plugins/OpulenZ/OpulenZ.cpp index 4b11102c3..d8d5f3e26 100644 --- a/plugins/OpulenZ/OpulenZ.cpp +++ b/plugins/OpulenZ/OpulenZ.cpp @@ -59,6 +59,8 @@ #include "PixmapButton.h" #include "ToolTip.h" +#include "plugin_export.h" + extern "C" { diff --git a/plugins/SpectrumAnalyzer/SpectrumAnalyzer.cpp b/plugins/SpectrumAnalyzer/SpectrumAnalyzer.cpp index f07fa7f45..0b947a3ba 100644 --- a/plugins/SpectrumAnalyzer/SpectrumAnalyzer.cpp +++ b/plugins/SpectrumAnalyzer/SpectrumAnalyzer.cpp @@ -25,7 +25,7 @@ #include "SpectrumAnalyzer.h" #include "embed.h" - +#include "plugin_export.h" extern "C" { diff --git a/plugins/audio_file_processor/audio_file_processor.cpp b/plugins/audio_file_processor/audio_file_processor.cpp index 5f5f19c9d..6c080f7c9 100644 --- a/plugins/audio_file_processor/audio_file_processor.cpp +++ b/plugins/audio_file_processor/audio_file_processor.cpp @@ -45,7 +45,7 @@ #include "DataFile.h" #include "embed.h" - +#include "plugin_export.h" extern "C" { diff --git a/plugins/bit_invader/bit_invader.cpp b/plugins/bit_invader/bit_invader.cpp index 86069a13c..ecc77be0b 100644 --- a/plugins/bit_invader/bit_invader.cpp +++ b/plugins/bit_invader/bit_invader.cpp @@ -43,6 +43,8 @@ #include "embed.h" +#include "plugin_export.h" + extern "C" { diff --git a/plugins/dynamics_processor/dynamics_processor.cpp b/plugins/dynamics_processor/dynamics_processor.cpp index 12ed1fa88..8c02b827d 100644 --- a/plugins/dynamics_processor/dynamics_processor.cpp +++ b/plugins/dynamics_processor/dynamics_processor.cpp @@ -29,6 +29,7 @@ #include "interpolation.h" #include "embed.h" +#include "plugin_export.h" extern "C" { diff --git a/plugins/kicker/kicker.cpp b/plugins/kicker/kicker.cpp index 0318c92d2..2087cf880 100644 --- a/plugins/kicker/kicker.cpp +++ b/plugins/kicker/kicker.cpp @@ -36,7 +36,7 @@ #include "KickerOsc.h" #include "embed.h" - +#include "plugin_export.h" extern "C" { diff --git a/plugins/ladspa_browser/ladspa_browser.cpp b/plugins/ladspa_browser/ladspa_browser.cpp index 0e8275c4d..d265bc0e3 100644 --- a/plugins/ladspa_browser/ladspa_browser.cpp +++ b/plugins/ladspa_browser/ladspa_browser.cpp @@ -39,7 +39,7 @@ #include "TabButton.h" #include "embed.h" - +#include "plugin_export.h" extern "C" diff --git a/plugins/lb302/lb302.cpp b/plugins/lb302/lb302.cpp index 66b77ac35..00d94f52c 100644 --- a/plugins/lb302/lb302.cpp +++ b/plugins/lb302/lb302.cpp @@ -46,7 +46,7 @@ #include "BandLimitedWave.h" #include "embed.h" - +#include "plugin_export.h" // Envelope Recalculation period #define ENVINC 64 diff --git a/plugins/nes/Nes.cpp b/plugins/nes/Nes.cpp index 70251c6cc..5b34dcb1f 100644 --- a/plugins/nes/Nes.cpp +++ b/plugins/nes/Nes.cpp @@ -36,6 +36,7 @@ #include "Oscillator.h" #include "embed.h" +#include "plugin_export.h" extern "C" { diff --git a/plugins/patman/patman.cpp b/plugins/patman/patman.cpp index bf24c6d32..e555886fc 100644 --- a/plugins/patman/patman.cpp +++ b/plugins/patman/patman.cpp @@ -44,7 +44,7 @@ #include "embed.h" - +#include "plugin_export.h" extern "C" diff --git a/plugins/peak_controller_effect/peak_controller_effect.cpp b/plugins/peak_controller_effect/peak_controller_effect.cpp index 2b39352ff..e8b31d6a0 100644 --- a/plugins/peak_controller_effect/peak_controller_effect.cpp +++ b/plugins/peak_controller_effect/peak_controller_effect.cpp @@ -32,6 +32,7 @@ #include "lmms_math.h" #include "embed.h" +#include "plugin_export.h" extern "C" { diff --git a/plugins/sfxr/sfxr.cpp b/plugins/sfxr/sfxr.cpp index 02e7413bb..c99f46f88 100644 --- a/plugins/sfxr/sfxr.cpp +++ b/plugins/sfxr/sfxr.cpp @@ -54,6 +54,8 @@ float frnd(float range) #include "embed.h" +#include "plugin_export.h" + extern "C" { diff --git a/plugins/stereo_enhancer/stereo_enhancer.cpp b/plugins/stereo_enhancer/stereo_enhancer.cpp index cb55213f1..2faa5846d 100644 --- a/plugins/stereo_enhancer/stereo_enhancer.cpp +++ b/plugins/stereo_enhancer/stereo_enhancer.cpp @@ -26,7 +26,7 @@ #include "stereo_enhancer.h" #include "embed.h" - +#include "plugin_export.h" extern "C" { diff --git a/plugins/stereo_matrix/stereo_matrix.cpp b/plugins/stereo_matrix/stereo_matrix.cpp index b2634e95c..a03a615ba 100644 --- a/plugins/stereo_matrix/stereo_matrix.cpp +++ b/plugins/stereo_matrix/stereo_matrix.cpp @@ -26,7 +26,7 @@ #include "stereo_matrix.h" #include "embed.h" - +#include "plugin_export.h" extern "C" { diff --git a/plugins/triple_oscillator/TripleOscillator.cpp b/plugins/triple_oscillator/TripleOscillator.cpp index 55a7ed7ed..6b644fd46 100644 --- a/plugins/triple_oscillator/TripleOscillator.cpp +++ b/plugins/triple_oscillator/TripleOscillator.cpp @@ -40,7 +40,7 @@ #include "ToolTip.h" #include "embed.h" - +#include "plugin_export.h" extern "C" { diff --git a/plugins/watsyn/Watsyn.cpp b/plugins/watsyn/Watsyn.cpp index c0a952fb8..0122b293a 100644 --- a/plugins/watsyn/Watsyn.cpp +++ b/plugins/watsyn/Watsyn.cpp @@ -36,6 +36,7 @@ #include "interpolation.h" #include "embed.h" +#include "plugin_export.h" extern "C" { diff --git a/plugins/waveshaper/waveshaper.cpp b/plugins/waveshaper/waveshaper.cpp index 047cd05d1..3f9d3e19f 100644 --- a/plugins/waveshaper/waveshaper.cpp +++ b/plugins/waveshaper/waveshaper.cpp @@ -29,6 +29,7 @@ #include "embed.h" #include "interpolation.h" +#include "plugin_export.h" extern "C" { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 84ddf4aee..42e667aca 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -101,11 +101,23 @@ ADD_LIBRARY(lmmsobjs OBJECT ${LMMS_UI_OUT} ${LMMS_RCC_OUT} ) + +GENERATE_EXPORT_HEADER(lmmsobjs + BASE_NAME lmms +) +# GENERATE_EXPORT_HEADER doesn't seem to do this automatically +TARGET_COMPILE_DEFINITIONS(lmmsobjs + PRIVATE -Dlmmsobjs_EXPORTS +) + ADD_EXECUTABLE(lmms core/main.cpp $ "${WINRC}" ) +TARGET_INCLUDE_DIRECTORIES(lmms + PUBLIC ${CMAKE_CURRENT_BINARY_DIR} +) # Set Visual Studio startup project to lmms # https://stackoverflow.com/a/37994396/8166701 From 1027386113d34ae64181af2e052b58665939a5ef Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 26 Nov 2017 14:05:35 +0100 Subject: [PATCH 045/445] CMake: Fix MSVC architecture detection --- cmake/modules/DetectMachine.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/DetectMachine.cmake b/cmake/modules/DetectMachine.cmake index a9cde461e..f3458165b 100644 --- a/cmake/modules/DetectMachine.cmake +++ b/cmake/modules/DetectMachine.cmake @@ -19,8 +19,8 @@ MESSAGE("PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") SET(LMMS_HOST_X86 FALSE) SET(LMMS_HOST_X86_64 FALSE) -IF(NOT DEFINED WIN64) - STRING(REGEX MATCH "86_64|amd64|AMD64" WIN64 "${CMAKE_SYSTEM_PROCESSOR}") +IF(NOT DEFINED WIN64 AND CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(WIN64 ON) ENDIF() IF(WIN32) From 87a7b0a2f0d5743220c590a612de651111d6fe3c Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 26 Nov 2017 14:07:08 +0100 Subject: [PATCH 046/445] MSVC: Port RemoteVstPlugin --- plugins/vst_base/RemoteVstPlugin.cpp | 42 +++++----------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 127036cd0..b8c05d528 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -34,10 +34,6 @@ #include "RemotePlugin.h" -#ifdef LMMS_HAVE_PTHREAD_H -#include -#endif - #ifdef LMMS_HAVE_FCNTL_H #include #endif @@ -63,6 +59,7 @@ #define USE_WS_PREFIX #include +#include #include #include #include @@ -243,17 +240,17 @@ public: inline void lockShm() { - pthread_mutex_lock( &m_shmLock ); + m_shmLock.lock(); } inline bool tryLockShm() { - return pthread_mutex_trylock( &m_shmLock ) == 0; + return m_shmLock.try_lock(); } inline void unlockShm() { - pthread_mutex_unlock( &m_shmLock ); + m_shmLock.unlock(); } inline bool isShmValid() @@ -349,7 +346,7 @@ private: float * * m_inputs; float * * m_outputs; - pthread_mutex_t m_shmLock; + std::mutex m_shmLock; bool m_shmValid; typedef std::vector VstMidiEventList; @@ -395,7 +392,6 @@ RemoteVstPlugin::RemoteVstPlugin( const char * socketPath ) : m_shouldGiveIdle( false ), m_inputs( NULL ), m_outputs( NULL ), - m_shmLock(), m_shmValid( false ), m_midiEvents(), m_bpm( 0 ), @@ -405,8 +401,6 @@ RemoteVstPlugin::RemoteVstPlugin( const char * socketPath ) : m_shmID( -1 ), m_vstSyncData( NULL ) { - pthread_mutex_init( &m_shmLock, NULL ); - __plugin = this; #ifndef USE_QT_SHMEM @@ -496,8 +490,6 @@ RemoteVstPlugin::~RemoteVstPlugin() delete[] m_inputs; delete[] m_outputs; - - pthread_mutex_destroy( &m_shmLock ); } @@ -683,7 +675,7 @@ static void close_check( FILE* fp ) { if( fclose( fp ) ) { - perror( "close" ); + perror( "fclose" ); } } @@ -1567,11 +1559,7 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode, _timeInfo.flags |= kVstBarsValid; -#ifdef LMMS_BUILD_WIN64 - return (long long) &_timeInfo; -#else - return (long) &_timeInfo; -#endif + return (intptr_t) &_timeInfo; case audioMasterProcessEvents: SHOW_CALLBACK( "amc: audioMasterProcessEvents\n" ); @@ -1995,14 +1983,6 @@ int main( int _argc, char * * _argv ) return -1; } -#ifdef LMMS_BUILD_WIN32 -#ifndef __WINPTHREADS_VERSION - // (non-portable) initialization of statically linked pthread library - pthread_win32_process_attach_np(); - pthread_win32_thread_attach_np(); -#endif -#endif - #ifdef LMMS_BUILD_LINUX #ifdef LMMS_HAVE_SCHED_H // try to set realtime-priority @@ -2110,14 +2090,6 @@ int main( int _argc, char * * _argv ) delete __plugin; - -#ifdef LMMS_BUILD_WIN32 -#ifndef __WINPTHREADS_VERSION - pthread_win32_thread_detach_np(); - pthread_win32_process_detach_np(); -#endif -#endif - return 0; } From 07a22181da5aa0b41cdbd5b7a599a8d31860197a Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 26 Nov 2017 14:08:15 +0100 Subject: [PATCH 047/445] RemoteVstPlugin: Debug LoadLibrary failure --- plugins/vst_base/RemoteVstPlugin.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index b8c05d528..b95935c2c 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -117,6 +117,25 @@ RemoteVstPlugin * __plugin = NULL; HWND __MessageHwnd = NULL; +//Returns the last Win32 error, in string format. Returns an empty string if there is no error. +std::string GetErrorAsString(DWORD errorMessageID) +{ + //Get the error message, if any. + if(errorMessageID == 0) + return std::string(); //No error message has been recorded + + LPSTR messageBuffer = nullptr; + size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL); + + std::string message(messageBuffer, size); + + //Free the buffer. + LocalFree(messageBuffer); + + return message; +} + class RemoteVstPlugin : public RemotePluginClient { @@ -785,6 +804,8 @@ bool RemoteVstPlugin::load( const std::string & _plugin_file ) { if( ( m_libInst = LoadLibraryW( toWString(_plugin_file).c_str() ) ) == NULL ) { + DWORD error = GetLastError(); + debugMessage( "LoadLibrary failed: " + GetErrorAsString(error) ); // give VstPlugin class a chance to start 32 bit version of RemoteVstPlugin if( GetLastError() == ERROR_BAD_EXE_FORMAT ) { From d756a7ade07d3bca37293dbb8bbde5e04150317c Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 26 Nov 2017 14:15:26 +0100 Subject: [PATCH 048/445] MSVC: Fix VST build --- include/RemotePlugin.h | 3 +- plugins/CMakeLists.txt | 2 - plugins/vestige/CMakeLists.txt | 4 +- plugins/vestige/vestige.cpp | 13 +- plugins/vst_base/CMakeLists.txt | 181 ++++++++++-------- .../vst_base/RemoteVstPlugin/CMakeLists.txt | 33 ++++ plugins/vst_base/VstPlugin.cpp | 8 +- plugins/vst_base/VstPlugin.h | 6 +- plugins/vst_base/Win64/CMakeLists.txt | 15 -- plugins/vst_base/communication.h | 2 - plugins/vst_base/vst_base.cpp | 4 +- plugins/vst_base/vstbase/CMakeLists.txt | 14 ++ src/core/RemotePlugin.cpp | 23 ++- 13 files changed, 189 insertions(+), 119 deletions(-) create mode 100644 plugins/vst_base/RemoteVstPlugin/CMakeLists.txt delete mode 100644 plugins/vst_base/Win64/CMakeLists.txt create mode 100644 plugins/vst_base/vstbase/CMakeLists.txt diff --git a/include/RemotePlugin.h b/include/RemotePlugin.h index 0a14458f6..67f0c3807 100644 --- a/include/RemotePlugin.h +++ b/include/RemotePlugin.h @@ -25,7 +25,6 @@ #ifndef REMOTE_PLUGIN_H #define REMOTE_PLUGIN_H -#include "lmms_export.h" #include "MidiEvent.h" #include "VstSyncData.h" @@ -89,6 +88,7 @@ typedef int32_t key_t; #endif #else +#include "lmms_export.h" #include #include #include @@ -886,6 +886,7 @@ private: private slots: void processFinished( int exitCode, QProcess::ExitStatus exitStatus ); + void processErrored(QProcess::ProcessError err ); } ; #endif diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 392a2ad45..21c174d0b 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -94,9 +94,7 @@ IF(MSVC) organic ReverbSC sid - vestige vibed - vst_base VstEffect Xpressive zynaddsubfx diff --git a/plugins/vestige/CMakeLists.txt b/plugins/vestige/CMakeLists.txt index 21803a924..823c03202 100644 --- a/plugins/vestige/CMakeLists.txt +++ b/plugins/vestige/CMakeLists.txt @@ -1,6 +1,5 @@ IF(LMMS_SUPPORT_VST) INCLUDE(BuildPlugin) - INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/../vst_base") LINK_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}/..") IF(LMMS_BUILD_LINUX) LINK_LIBRARIES(-Wl,--enable-new-dtags) @@ -10,7 +9,6 @@ IF(LMMS_SUPPORT_VST) SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${PLUGIN_DIR}") ENDIF() BUILD_PLUGIN(vestige vestige.cpp vestige.h MOCFILES vestige.h EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png") - TARGET_LINK_LIBRARIES(vestige -lvstbase) - ADD_DEPENDENCIES(vestige vstbase) + TARGET_LINK_LIBRARIES(vestige vstbase) ENDIF(LMMS_SUPPORT_VST) diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index b8204f404..710d9fe55 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -22,6 +22,10 @@ * */ +#include + +#include "VstPlugin.h" + #include "vestige.h" #include @@ -41,7 +45,7 @@ #include "gui_templates.h" #include "InstrumentPlayHandle.h" #include "InstrumentTrack.h" -#include "VstPlugin.h" + #include "MainWindow.h" #include "Mixer.h" #include "GuiApplication.h" @@ -52,6 +56,7 @@ #include "ToolTip.h" #include "FileDialog.h" + #include "embed.h" @@ -59,7 +64,7 @@ extern "C" { -Plugin::Descriptor PLUGIN_EXPORT vestige_plugin_descriptor = +Plugin::Descriptor Q_DECL_EXPORT vestige_plugin_descriptor = { STRINGIFY( PLUGIN_NAME ), "VeSTige", @@ -612,7 +617,7 @@ void VestigeInstrumentView::updateMenu( void ) QMenu * to_menu = m_selPresetButton->menu(); to_menu->clear(); - QAction *presetActions[list1.size()]; + QVector presetActions(list1.size()); for (int i = 0; i < list1.size(); i++) { presetActions[i] = new QAction(this); @@ -1163,7 +1168,7 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +Q_DECL_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) { return new vestigeInstrument( static_cast( _data ) ); } diff --git a/plugins/vst_base/CMakeLists.txt b/plugins/vst_base/CMakeLists.txt index b0a478232..eccfb4246 100644 --- a/plugins/vst_base/CMakeLists.txt +++ b/plugins/vst_base/CMakeLists.txt @@ -1,93 +1,110 @@ -IF(LMMS_SUPPORT_VST) +IF(NOT LMMS_SUPPORT_VST) + RETURN() +ENDIF() INCLUDE(BuildPlugin) -IF(LMMS_BUILD_WIN32) - ADD_DEFINITIONS(-DPTW32_STATIC_LIB) - ADD_EXECUTABLE(RemoteVstPlugin "${CMAKE_CURRENT_SOURCE_DIR}/RemoteVstPlugin.cpp") +SET(LMMS_BINARY_DIR ${CMAKE_BINARY_DIR}) +SET(LMMS_SOURCE_DIR ${CMAKE_SOURCE_DIR}) +SET(EXTERNALPROJECT_ARGS "") - TARGET_LINK_LIBRARIES(RemoteVstPlugin Qt5::Core) - TARGET_LINK_LIBRARIES(RemoteVstPlugin -lpthread -lgdi32 -lws2_32) - SET_TARGET_PROPERTIES(RemoteVstPlugin PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -O0") - ADD_CUSTOM_COMMAND(TARGET RemoteVstPlugin POST_BUILD COMMAND "${STRIP}" "$") - INSTALL(TARGETS RemoteVstPlugin RUNTIME DESTINATION "${PLUGIN_DIR}") +# build 32 bit version of RemoteVstPlugin +IF(LMMS_BUILD_WIN64 AND MSVC) + INCLUDE(ExternalProject) - # FIXME: 32-bit VST fails on MSYS - IF(LMMS_BUILD_WIN64 AND NOT LMMS_BUILD_MSYS) - # build 32 bit version of RemoteVstPlugin for Win64 so we can load - # 32 bit VST plugins - ADD_SUBDIRECTORY(Win64) - ENDIF(LMMS_BUILD_WIN64 AND NOT LMMS_BUILD_MSYS) -ENDIF(LMMS_BUILD_WIN32) + SET(MSVC_VER ${CMAKE_CXX_COMPILER_VERSION}) -SET(REMOTE_VST_PLUGIN_FILEPATH "RemoteVstPlugin" CACHE STRING "Relative file path to RemoteVstPlugin") - -INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/src/3rdparty/qt5-x11embed/src/") -ADD_DEFINITIONS(-DREMOTE_VST_PLUGIN_FILEPATH="${REMOTE_VST_PLUGIN_FILEPATH}") -BUILD_PLUGIN(vstbase vst_base.cpp VstPlugin.cpp VstPlugin.h communication.h MOCFILES VstPlugin.h) - -IF(LMMS_BUILD_LINUX) - TARGET_LINK_LIBRARIES(vstbase qx11embedcontainer) -ENDIF() - -IF(LMMS_BUILD_LINUX AND NOT WANT_VST_NOWINE) - -IF(LMMS_HOST_X86_64) - SET(EXTRA_FLAGS -m32) - IF(WINE_LIBRARY_FIX) - SET(EXTRA_FLAGS ${EXTRA_FLAGS} -nodefaultlibs ${WINE_LIBRARY_FIX}wine/libwinecrt0.a -L${WINE_LIBRARY_FIX}wine/ -luser32 -lkernel32 -lgdi32) - ENDIF() -ENDIF(LMMS_HOST_X86_64) - -SET(WINE_CXX_FLAGS "" CACHE STRING "Extra flags passed to wineg++") - -STRING(REPLACE "include/wine" "include" WINE_INCLUDE_BASE_DIR ${WINE_INCLUDE_DIR}) -STRING(REPLACE "lib/libwine.so" "lib" WINE_LIBRARY_DIR ${WINE_LIBRARY}) -STRING(REPLACE " " ";" WINE_BUILD_FLAGS ${CMAKE_CXX_FLAGS} " " ${CMAKE_EXE_LINKER_FLAGS} " " ${WINE_CXX_FLAGS}) - -SET(WINE_CXX_ARGS - -I${CMAKE_BINARY_DIR} - -I${CMAKE_SOURCE_DIR}/include - -I${WINE_INCLUDE_BASE_DIR} - -I${WINE_INCLUDE_DIR}/windows - -L${WINE_LIBRARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/RemoteVstPlugin.cpp - -std=c++0x - -mwindows -lpthread ${EXTRA_FLAGS} -fno-omit-frame-pointer - ${WINE_BUILD_FLAGS} - -o ../RemoteVstPlugin -) - -# winegcc fails if winebuild is not in path -GET_FILENAME_COMPONENT(WINE_BINDIR ${WINE_CXX} PATH) -FIND_PROGRAM(WINEBUILD winebuild NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) -IF(NOT WINEBUILD) - IF(CMAKE_VERSION VERSION_LESS 3.1) - MESSAGE(WARNING "winebuild is not in PATH. Building RemoteVstPlugin may fail.") + IF(MSVC_VER VERSION_GREATER 19.0 OR MSVC_VER VERSION_EQUAL 19.0) + SET(GENERATOR "Visual Studio 14 2015") + SET(MSVC_YEAR 2015) + ELSEIF(MSVC_VER VERSION_EQUAL 19.10 OR MSVC_VER VERSION_EQUAL 19.10) + SET(GENERATOR "Visual Studio 15 2017") + SET(MSVC_YEAR 2017) ELSE() - SET(WINE_CXX_ARGS -E env PATH=$ENV{PATH}:${WINE_BINDIR} ${WINE_CXX} ${WINE_CXX_ARGS}) - SET(WINE_CXX "${CMAKE_COMMAND}") + MESSAGE(SEND_ERROR "Can't build RemoteVstPlugin32, unknown MSVC version ${MSVC_VER}") ENDIF() + + GET_FILENAME_COMPONENT(QT_BIN_DIR ${QT_QMAKE_EXECUTABLE} DIRECTORY) + SET(QT_32_PREFIX "${QT_BIN_DIR}/../../msvc${MSVC_YEAR}") + IF(NOT (IS_DIRECTORY ${QT_32_PREFIX} AND EXISTS ${QT_32_PREFIX}/bin/qmake.exe)) + MESSAGE(SEND_ERROR "Can't build RemoteVstPlugin32, no Qt 32 bit installation found at ${QT_32_PREFIX}") + ENDIF() + + ExternalProject_Add(RemoteVstPlugin32 + SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin" + INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/../" + CMAKE_GENERATOR ${GENERATOR} + CMAKE_ARGS + -DLMMS_SOURCE_DIR=${CMAKE_SOURCE_DIR} + -DLMMS_BINARY_DIR=${CMAKE_BINARY_DIR} + -DCMAKE_PREFIX_PATH=${QT_32_PREFIX} + -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + INSTALL_COMMAND "" + BUILD_ALWAYS ON + ) +ELSEIF(LMMS_BUILD_WIN32) + ADD_SUBDIRECTORY(RemoteVstPlugin) +ELSEIF(LMMS_BUILD_LINUX AND NOT WANT_VST_NOWINE) + IF(LMMS_HOST_X86_64) + SET(EXTRA_FLAGS -m32) + IF(WINE_LIBRARY_FIX) + SET(EXTRA_FLAGS ${EXTRA_FLAGS} -nodefaultlibs ${WINE_LIBRARY_FIX}wine/libwinecrt0.a -L${WINE_LIBRARY_FIX}wine/ -luser32 -lkernel32 -lgdi32) + ENDIF() + ENDIF(LMMS_HOST_X86_64) + + SET(WINE_CXX_FLAGS "" CACHE STRING "Extra flags passed to wineg++") + + STRING(REPLACE "include/wine" "include" WINE_INCLUDE_BASE_DIR ${WINE_INCLUDE_DIR}) + STRING(REPLACE "lib/libwine.so" "lib" WINE_LIBRARY_DIR ${WINE_LIBRARY}) + STRING(REPLACE " " ";" WINE_BUILD_FLAGS ${CMAKE_CXX_FLAGS} " " ${CMAKE_EXE_LINKER_FLAGS} " " ${WINE_CXX_FLAGS}) + + SET(WINE_CXX_ARGS + -I${CMAKE_BINARY_DIR} + -I${CMAKE_SOURCE_DIR}/include + -I${WINE_INCLUDE_BASE_DIR} + -I${WINE_INCLUDE_DIR}/windows + -L${WINE_LIBRARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/RemoteVstPlugin.cpp + -std=c++0x + -mwindows -lpthread ${EXTRA_FLAGS} -fno-omit-frame-pointer + ${WINE_BUILD_FLAGS} + -o ../RemoteVstPlugin + ) + + # winegcc fails if winebuild is not in path + GET_FILENAME_COMPONENT(WINE_BINDIR ${WINE_CXX} PATH) + FIND_PROGRAM(WINEBUILD winebuild NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) + IF(NOT WINEBUILD) + IF(CMAKE_VERSION VERSION_LESS 3.1) + MESSAGE(WARNING "winebuild is not in PATH. Building RemoteVstPlugin may fail.") + ELSE() + SET(WINE_CXX_ARGS -E env PATH=$ENV{PATH}:${WINE_BINDIR} ${WINE_CXX} ${WINE_CXX_ARGS}) + SET(WINE_CXX "${CMAKE_COMMAND}") + ENDIF() + ENDIF() + + set(ENV{PATH} "$ENV{PATH}:${WINE_BINDIR}") + + ADD_CUSTOM_COMMAND( + SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/RemoteVstPlugin.cpp" + COMMAND export + ARGS "PATH=$PATH:${WINE_BINDIR}" + COMMAND ${WINE_CXX} + ARGS ${WINE_CXX_ARGS} + # Ensure correct file extension + COMMAND sh -c "mv ../RemoteVstPlugin.exe ../RemoteVstPlugin || true" + TARGET vstbase + OUTPUTS ../RemoteVstPlugin + VERBATIM + ) + + SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ../RemoteVstPlugin32.exe.so) + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}") ENDIF() -set(ENV{PATH} "$ENV{PATH}:${WINE_BINDIR}") +# build 64 bit version of RemoteVstPlugin +IF(LMMS_BUILD_WIN64) + ADD_SUBDIRECTORY(RemoteVstPlugin) +ENDIF() -ADD_CUSTOM_COMMAND( - SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/RemoteVstPlugin.cpp" - COMMAND export - ARGS "PATH=$PATH:${WINE_BINDIR}" - COMMAND ${WINE_CXX} - ARGS ${WINE_CXX_ARGS} - # Ensure correct file extension - COMMAND sh -c "mv ../RemoteVstPlugin.exe ../RemoteVstPlugin || true" - TARGET vstbase - OUTPUTS ../RemoteVstPlugin - VERBATIM -) - -SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ../RemoteVstPlugin.exe.so) -INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin.exe.so" DESTINATION "${PLUGIN_DIR}") -ENDIF(LMMS_BUILD_LINUX AND NOT WANT_VST_NOWINE) - - -ENDIF(LMMS_SUPPORT_VST) +ADD_SUBDIRECTORY(vstbase) diff --git a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt new file mode 100644 index 000000000..d077a80c0 --- /dev/null +++ b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.0.0) +project(RemoteVstPlugin + LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 11) + +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(BITNESS 64) +else() + set(BITNESS 32) +endif() + +set(EXE_NAME RemoteVstPlugin${BITNESS}) + +add_executable(${EXE_NAME} + ../RemoteVstPlugin.cpp +) + +target_include_directories(${EXE_NAME} + PRIVATE + "${LMMS_SOURCE_DIR}/plugins/vst_base/common" + "${LMMS_SOURCE_DIR}/include" + "${LMMS_BINARY_DIR}" +) + +if(WIN32) + find_package(Qt5 REQUIRED COMPONENTS Core) + target_link_libraries(${EXE_NAME} Qt5::Core) +endif() + +IF(STRIP) + ADD_CUSTOM_COMMAND(TARGET RemoteVstPlugin32 POST_BUILD COMMAND "${STRIP}" "$") +ENDIF() diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 26c789275..6096a0d49 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -24,6 +24,8 @@ #include "VstPlugin.h" +#include "communication.h" + #include #include #include @@ -79,12 +81,14 @@ VstPlugin::VstPlugin( const QString & _plugin ) : { setSplittedChannels( true ); - tryLoad( REMOTE_VST_PLUGIN_FILEPATH ); #ifdef LMMS_BUILD_WIN64 + tryLoad( "RemoteVstPlugin64" ); if( m_badDllFormat ) { m_badDllFormat = false; - tryLoad( "32/RemoteVstPlugin32" ); +#endif + tryLoad( "RemoteVstPlugin32" ); +#ifdef LMMS_BUILD_WIN64 } #endif diff --git a/plugins/vst_base/VstPlugin.h b/plugins/vst_base/VstPlugin.h index 9e8b39771..6ef325497 100644 --- a/plugins/vst_base/VstPlugin.h +++ b/plugins/vst_base/VstPlugin.h @@ -33,12 +33,14 @@ #include #include "JournallingObject.h" -#include "communication.h" +#include "RemotePlugin.h" + +#include "vstbase_export.h" class vstSubWin; -class PLUGIN_EXPORT VstPlugin : public RemotePlugin, public JournallingObject +class VSTBASE_EXPORT VstPlugin : public RemotePlugin, public JournallingObject { Q_OBJECT public: diff --git a/plugins/vst_base/Win64/CMakeLists.txt b/plugins/vst_base/Win64/CMakeLists.txt deleted file mode 100644 index 39b9b5a9b..000000000 --- a/plugins/vst_base/Win64/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -INCLUDE_DIRECTORIES("${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/include") -SET(CMAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER32}") - -ADD_EXECUTABLE(RemoteVstPlugin32 "${CMAKE_CURRENT_SOURCE_DIR}/../RemoteVstPlugin.cpp") - -SET(QTCORE "Qt5Core") -TARGET_LINK_LIBRARIES(RemoteVstPlugin32 -l${QTCORE} -lpthread -lgdi32 -lws2_32) - -ADD_CUSTOM_COMMAND(TARGET RemoteVstPlugin32 POST_BUILD COMMAND "${STRIP}" "$") -SET_TARGET_PROPERTIES(RemoteVstPlugin32 PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -O0") - -INSTALL(TARGETS RemoteVstPlugin32 RUNTIME DESTINATION "${PLUGIN_DIR}/32") -INSTALL(FILES "${MINGW_PREFIX32}/bin/${QTCORE}.dll" "${MINGW_PREFIX32}/bin/zlib1.dll" "${MINGW_PREFIX32}/${CMAKE_SYSTEM_PROCESSOR32}-w64-mingw32/bin/libwinpthread-1.dll" - DESTINATION "${PLUGIN_DIR}/32") - diff --git a/plugins/vst_base/communication.h b/plugins/vst_base/communication.h index bacf43c1e..cfe136627 100644 --- a/plugins/vst_base/communication.h +++ b/plugins/vst_base/communication.h @@ -27,8 +27,6 @@ #ifndef _COMMUNICATION_H #define _COMMUNICATION_H -#include "RemotePlugin.h" - struct VstParameterDumpItem diff --git a/plugins/vst_base/vst_base.cpp b/plugins/vst_base/vst_base.cpp index 1c1770abe..0ca1159a2 100644 --- a/plugins/vst_base/vst_base.cpp +++ b/plugins/vst_base/vst_base.cpp @@ -26,12 +26,12 @@ #include "Plugin.h" #include "embed.h" - +#include "vstbase_export.h" extern "C" { -Plugin::Descriptor PLUGIN_EXPORT vstbase_plugin_descriptor = +Plugin::Descriptor VSTBASE_EXPORT vstbase_plugin_descriptor = { STRINGIFY( PLUGIN_NAME ), "VST Base", diff --git a/plugins/vst_base/vstbase/CMakeLists.txt b/plugins/vst_base/vstbase/CMakeLists.txt new file mode 100644 index 000000000..28c09edb3 --- /dev/null +++ b/plugins/vst_base/vstbase/CMakeLists.txt @@ -0,0 +1,14 @@ +BUILD_PLUGIN(vstbase + ../vst_base.cpp ../VstPlugin.cpp ../VstPlugin.h ../communication.h + MOCFILES ../VstPlugin.h + EXPORT_BASE_NAME vstbase + LINK SHARED +) + +TARGET_INCLUDE_DIRECTORIES(vstbase + PUBLIC ../ +) + +IF(LMMS_BUILD_LINUX) + TARGET_LINK_LIBRARIES(vstbase qx11embedcontainer) +ENDIF() diff --git a/src/core/RemotePlugin.cpp b/src/core/RemotePlugin.cpp index 64b5e592d..7b10ed50b 100644 --- a/src/core/RemotePlugin.cpp +++ b/src/core/RemotePlugin.cpp @@ -33,6 +33,7 @@ #include "Mixer.h" #include "Engine.h" +#include #include #ifndef SYNC_WITH_SHM_FIFO @@ -78,7 +79,6 @@ RemotePlugin::RemotePlugin() : RemotePluginBase(), #endif m_failed( true ), - m_process(), m_watcher( this ), m_commMutex( QMutex::Recursive ), m_splitChannels( false ), @@ -120,6 +120,11 @@ RemotePlugin::RemotePlugin() : qWarning( "Unable to start the server." ); } #endif + + connect( &m_process, SIGNAL( finished( int, QProcess::ExitStatus ) ), + this, SLOT( processFinished( int, QProcess::ExitStatus ) ) ); + connect( &m_process, SIGNAL( errorOccured( QProcess::ProcessError ) ), + this, SLOT( processErrored( QProcess::ProcessError ) ) ); } @@ -219,9 +224,6 @@ bool RemotePlugin::init(const QString &pluginExecutable, 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; @@ -454,11 +456,24 @@ void RemotePlugin::resizeSharedProcessingMemory() void RemotePlugin::processFinished( int exitCode, QProcess::ExitStatus exitStatus ) { + if ( exitStatus == QProcess::CrashExit ) + { + qCritical() << "Remote plugin crashed"; + } + else if ( exitCode ) + { + qCritical() << "Remote plugin exit code: " << exitCode; + } #ifndef SYNC_WITH_SHM_FIFO invalidate(); #endif } +void RemotePlugin::processErrored( QProcess::ProcessError err ) +{ + qCritical() << "Process error: " << err; +} + From 7feedb4ed9d850b617ee954e164861c5aae60e7e Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 26 Nov 2017 14:16:30 +0100 Subject: [PATCH 049/445] VST: Fix main entry calling convention This will probably break everything, but it was needed to load 32bit VST plugins with MSVC. --- plugins/vst_base/RemoteVstPlugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index b95935c2c..db5c99e8f 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -814,7 +814,7 @@ bool RemoteVstPlugin::load( const std::string & _plugin_file ) return false; } - typedef AEffect * ( __stdcall * mainEntryPointer ) + typedef AEffect * ( __cdecl * mainEntryPointer ) ( audioMasterCallback ); mainEntryPointer mainEntry = (mainEntryPointer) GetProcAddress( m_libInst, "VSTPluginMain" ); From 47a5248d1d34786a47a5b856790041a8f7850f54 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 26 Nov 2017 20:52:18 +0100 Subject: [PATCH 050/445] Linux compile fixes --- cmake/modules/BuildPlugin.cmake | 10 +++++----- plugins/CMakeLists.txt | 3 ++- plugins/GigPlayer/GigPlayer.cpp | 2 +- plugins/LadspaEffect/LadspaEffect.cpp | 1 + plugins/ReverbSC/ReverbSC.cpp | 1 + plugins/VstEffect/CMakeLists.txt | 3 +-- plugins/VstEffect/VstEffect.cpp | 2 +- plugins/Xpressive/Xpressive.cpp | 2 ++ plugins/monstro/Monstro.cpp | 1 + plugins/organic/organic.cpp | 2 +- plugins/sf2_player/sf2_player.cpp | 2 +- plugins/sid/sid_instrument.cpp | 1 + plugins/stk/mallets/mallets.cpp | 2 +- plugins/vibed/vibed.cpp | 2 +- plugins/zynaddsubfx/ZynAddSubFx.cpp | 3 +-- 15 files changed, 21 insertions(+), 16 deletions(-) diff --git a/cmake/modules/BuildPlugin.cmake b/cmake/modules/BuildPlugin.cmake index d0e3fa17a..bcc89222c 100644 --- a/cmake/modules/BuildPlugin.cmake +++ b/cmake/modules/BuildPlugin.cmake @@ -50,11 +50,11 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) SET(QT_LIBRARIES "${QT_OVERRIDE_LIBRARIES}") ENDIF() - IF ("${PLUGIN_LINK}" STREQUAL "SHARED") - ADD_LIBRARY(${PLUGIN_NAME} SHARED ${PLUGIN_SOURCES} ${plugin_MOC_out} ${RCC_OUT}) - ELSE () - ADD_LIBRARY(${PLUGIN_NAME} MODULE ${PLUGIN_SOURCES} ${plugin_MOC_out} ${RCC_OUT}) - ENDIF () + IF (NOT PLUGIN_LINK) + SET(PLUGIN_LINK "MODULE") + ENDIF() + + ADD_LIBRARY(${PLUGIN_NAME} ${PLUGIN_LINK} ${PLUGIN_SOURCES} ${plugin_MOC_out} ${RCC_OUT}) TARGET_LINK_LIBRARIES(${PLUGIN_NAME} Qt5::Widgets Qt5::Xml) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 21c174d0b..0f7e59443 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -11,6 +11,7 @@ ENDIF() INCLUDE_DIRECTORIES( ${SAMPLERATE_INCLUDE_DIRS} + "${CMAKE_BINARY_DIR}/src" ) SET(PLUGIN_LIST "" CACHE STRING "List of plug-ins to build") @@ -75,8 +76,8 @@ IF("${PLUGIN_LIST}" STREQUAL "") stereo_enhancer stereo_matrix stk - vestige vst_base + vestige VstEffect watsyn waveshaper diff --git a/plugins/GigPlayer/GigPlayer.cpp b/plugins/GigPlayer/GigPlayer.cpp index 938cd10b1..66212427c 100644 --- a/plugins/GigPlayer/GigPlayer.cpp +++ b/plugins/GigPlayer/GigPlayer.cpp @@ -53,7 +53,7 @@ #include "LcdSpinBox.h" #include "embed.h" - +#include "plugin_export.h" extern "C" { diff --git a/plugins/LadspaEffect/LadspaEffect.cpp b/plugins/LadspaEffect/LadspaEffect.cpp index aceea2d41..f9959a205 100644 --- a/plugins/LadspaEffect/LadspaEffect.cpp +++ b/plugins/LadspaEffect/LadspaEffect.cpp @@ -44,6 +44,7 @@ #include "embed.h" +#include "plugin_export.h" extern "C" { diff --git a/plugins/ReverbSC/ReverbSC.cpp b/plugins/ReverbSC/ReverbSC.cpp index bae59471c..3d56fd0d0 100644 --- a/plugins/ReverbSC/ReverbSC.cpp +++ b/plugins/ReverbSC/ReverbSC.cpp @@ -24,6 +24,7 @@ #include "ReverbSC.h" #include "embed.h" +#include "plugin_export.h" #define DB2LIN(X) pow(10, X / 20.0f); diff --git a/plugins/VstEffect/CMakeLists.txt b/plugins/VstEffect/CMakeLists.txt index ec05a14ea..78d8e6483 100644 --- a/plugins/VstEffect/CMakeLists.txt +++ b/plugins/VstEffect/CMakeLists.txt @@ -12,8 +12,7 @@ ENDIF() BUILD_PLUGIN(vsteffect VstEffect.cpp VstEffectControls.cpp VstEffectControlDialog.cpp VstSubPluginFeatures.cpp VstEffect.h VstEffectControls.h VstEffectControlDialog.h VstSubPluginFeatures.h MOCFILES VstEffectControlDialog.h VstEffectControls.h EMBEDDED_RESOURCES *.png) SET_TARGET_PROPERTIES(vsteffect PROPERTIES COMPILE_FLAGS "-Wno-attributes") -TARGET_LINK_LIBRARIES(vsteffect -lvstbase) -ADD_DEPENDENCIES(vsteffect vstbase) +TARGET_LINK_LIBRARIES(vsteffect vstbase) ENDIF(LMMS_SUPPORT_VST) diff --git a/plugins/VstEffect/VstEffect.cpp b/plugins/VstEffect/VstEffect.cpp index ed05a82a0..1a22176cd 100644 --- a/plugins/VstEffect/VstEffect.cpp +++ b/plugins/VstEffect/VstEffect.cpp @@ -32,7 +32,7 @@ #include "VstSubPluginFeatures.h" #include "embed.h" - +#include "plugin_export.h" extern "C" { diff --git a/plugins/Xpressive/Xpressive.cpp b/plugins/Xpressive/Xpressive.cpp index 8c9aa1532..5e500a744 100644 --- a/plugins/Xpressive/Xpressive.cpp +++ b/plugins/Xpressive/Xpressive.cpp @@ -48,6 +48,8 @@ #include "ExprSynth.h" +#include "plugin_export.h" + extern "C" { Plugin::Descriptor PLUGIN_EXPORT xpressive_plugin_descriptor = { STRINGIFY( diff --git a/plugins/monstro/Monstro.cpp b/plugins/monstro/Monstro.cpp index 82f365ec1..44a535100 100644 --- a/plugins/monstro/Monstro.cpp +++ b/plugins/monstro/Monstro.cpp @@ -37,6 +37,7 @@ #include "embed.h" +#include "plugin_export.h" extern "C" { diff --git a/plugins/organic/organic.cpp b/plugins/organic/organic.cpp index 2339587b5..8f5ae6b36 100644 --- a/plugins/organic/organic.cpp +++ b/plugins/organic/organic.cpp @@ -42,7 +42,7 @@ #include "embed.h" - +#include "plugin_export.h" extern "C" diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index 93867983d..bef1324f5 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -46,7 +46,7 @@ #include "LcdSpinBox.h" #include "embed.h" - +#include "plugin_export.h" extern "C" { diff --git a/plugins/sid/sid_instrument.cpp b/plugins/sid/sid_instrument.cpp index ce3960832..2eb46be56 100644 --- a/plugins/sid/sid_instrument.cpp +++ b/plugins/sid/sid_instrument.cpp @@ -42,6 +42,7 @@ #include "ToolTip.h" #include "embed.h" +#include "plugin_export.h" #define C64_PAL_CYCLES_PER_SEC 985248 diff --git a/plugins/stk/mallets/mallets.cpp b/plugins/stk/mallets/mallets.cpp index 964e1ddd2..9c138aaa9 100644 --- a/plugins/stk/mallets/mallets.cpp +++ b/plugins/stk/mallets/mallets.cpp @@ -41,7 +41,7 @@ #include "Mixer.h" #include "embed.h" - +#include "plugin_export.h" extern "C" { diff --git a/plugins/vibed/vibed.cpp b/plugins/vibed/vibed.cpp index 95a2c428a..f33a90428 100644 --- a/plugins/vibed/vibed.cpp +++ b/plugins/vibed/vibed.cpp @@ -40,7 +40,7 @@ #include "Song.h" #include "embed.h" - +#include "plugin_export.h" extern "C" { diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index 7ec345ff0..8a5d2fa11 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -47,8 +47,7 @@ #include "ControllerConnection.h" #include "embed.h" - - +#include "plugin_export.h" extern "C" { From ea154694f905087db28119ea1901861cac92a2e2 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 26 Nov 2017 20:54:32 +0100 Subject: [PATCH 051/445] Fix Linux VST compilation --- cmake/modules/CheckCXXPreprocessor.cmake | 33 +++++++ plugins/vst_base/CMakeLists.txt | 96 ++++++------------- .../vst_base/RemoteVstPlugin/CMakeLists.txt | 15 ++- plugins/vst_base/RemoteVstPlugin/winegcc | 49 ++++++++++ plugins/vst_base/VstPlugin.cpp | 4 +- 5 files changed, 126 insertions(+), 71 deletions(-) create mode 100644 cmake/modules/CheckCXXPreprocessor.cmake create mode 100755 plugins/vst_base/RemoteVstPlugin/winegcc diff --git a/cmake/modules/CheckCXXPreprocessor.cmake b/cmake/modules/CheckCXXPreprocessor.cmake new file mode 100644 index 000000000..f841f52d1 --- /dev/null +++ b/cmake/modules/CheckCXXPreprocessor.cmake @@ -0,0 +1,33 @@ + +macro(CHECK_CXX_PREPROCESSOR VAR DIRECTIVE) + string(RANDOM DEFINED_KEY) + string(RANDOM UNDEFINED_KEY) + + set(TMP_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/CxxTmp/src.cpp") + SET(SRC " + #if ${DIRECTIVE} + #error ${DEFINED_KEY} + #else + #error ${UNDEFINED_KEY} + #endif + ") + file(WRITE ${TMP_FILENAME} "${SRC}") + try_compile(RESULT_VAR + ${CMAKE_CURRENT_BINARY_DIR} + ${TMP_FILENAME} + OUTPUT_VARIABLE OUTPUT_VAR + ) + + if(OUTPUT_VAR MATCHES ${DEFINED_KEY}) + set(${VAR} ON) + elseif(OUTPUT_VAR MATCHES ${UNDEFINED_KEY}) + set(${VAR} OFF) + else() + message(FATAL_ERROR "Can't determine if \"${DIRECTIVE}\" is true.") + endif() +endmacro() + + +macro(CHECK_CXX_DEFINE VAR DEFINE) + CHECK_CXX_PREPROCESSOR(${VAR} "defined(${DEFINE})") +endmacro() diff --git a/plugins/vst_base/CMakeLists.txt b/plugins/vst_base/CMakeLists.txt index eccfb4246..a355f87ff 100644 --- a/plugins/vst_base/CMakeLists.txt +++ b/plugins/vst_base/CMakeLists.txt @@ -3,14 +3,28 @@ IF(NOT LMMS_SUPPORT_VST) ENDIF() INCLUDE(BuildPlugin) +INCLUDE(ExternalProject) + +ADD_SUBDIRECTORY(vstbase) SET(LMMS_BINARY_DIR ${CMAKE_BINARY_DIR}) SET(LMMS_SOURCE_DIR ${CMAKE_SOURCE_DIR}) -SET(EXTERNALPROJECT_ARGS "") + +SET(EXTERNALPROJECT_ARGS + SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin" + INSTALL_COMMAND "" + BUILD_ALWAYS ON +) + +SET(EXTERNALPROJECT_CMAKE_ARGS + -DLMMS_SOURCE_DIR=${CMAKE_SOURCE_DIR} + -DLMMS_BINARY_DIR=${CMAKE_BINARY_DIR} + -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + -DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH} +) # build 32 bit version of RemoteVstPlugin IF(LMMS_BUILD_WIN64 AND MSVC) - INCLUDE(ExternalProject) SET(MSVC_VER ${CMAKE_CXX_COMPILER_VERSION}) @@ -31,80 +45,32 @@ IF(LMMS_BUILD_WIN64 AND MSVC) ENDIF() ExternalProject_Add(RemoteVstPlugin32 - SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin" - INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/../" + ${EXTERNALPROJECT_ARGS} CMAKE_GENERATOR ${GENERATOR} CMAKE_ARGS - -DLMMS_SOURCE_DIR=${CMAKE_SOURCE_DIR} - -DLMMS_BINARY_DIR=${CMAKE_BINARY_DIR} + ${EXTERNALPROJECT_CMAKE_ARGS} -DCMAKE_PREFIX_PATH=${QT_32_PREFIX} - -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - INSTALL_COMMAND "" - BUILD_ALWAYS ON ) ELSEIF(LMMS_BUILD_WIN32) ADD_SUBDIRECTORY(RemoteVstPlugin) ELSEIF(LMMS_BUILD_LINUX AND NOT WANT_VST_NOWINE) - IF(LMMS_HOST_X86_64) - SET(EXTRA_FLAGS -m32) - IF(WINE_LIBRARY_FIX) - SET(EXTRA_FLAGS ${EXTRA_FLAGS} -nodefaultlibs ${WINE_LIBRARY_FIX}wine/libwinecrt0.a -L${WINE_LIBRARY_FIX}wine/ -luser32 -lkernel32 -lgdi32) - ENDIF() - ENDIF(LMMS_HOST_X86_64) - - SET(WINE_CXX_FLAGS "" CACHE STRING "Extra flags passed to wineg++") - - STRING(REPLACE "include/wine" "include" WINE_INCLUDE_BASE_DIR ${WINE_INCLUDE_DIR}) - STRING(REPLACE "lib/libwine.so" "lib" WINE_LIBRARY_DIR ${WINE_LIBRARY}) - STRING(REPLACE " " ";" WINE_BUILD_FLAGS ${CMAKE_CXX_FLAGS} " " ${CMAKE_EXE_LINKER_FLAGS} " " ${WINE_CXX_FLAGS}) - - SET(WINE_CXX_ARGS - -I${CMAKE_BINARY_DIR} - -I${CMAKE_SOURCE_DIR}/include - -I${WINE_INCLUDE_BASE_DIR} - -I${WINE_INCLUDE_DIR}/windows - -L${WINE_LIBRARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/RemoteVstPlugin.cpp - -std=c++0x - -mwindows -lpthread ${EXTRA_FLAGS} -fno-omit-frame-pointer - ${WINE_BUILD_FLAGS} - -o ../RemoteVstPlugin + ExternalProject_Add(RemoteVstPlugin32 + ${EXTERNALPROJECT_ARGS} + CMAKE_ARGS + ${EXTERNALPROJECT_CMAKE_ARGS} + -DCMAKE_CXX_COMPILER=${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin/winegcc + -DCMAKE_CXX_FLAGS="-m32" ) - - # winegcc fails if winebuild is not in path - GET_FILENAME_COMPONENT(WINE_BINDIR ${WINE_CXX} PATH) - FIND_PROGRAM(WINEBUILD winebuild NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) - IF(NOT WINEBUILD) - IF(CMAKE_VERSION VERSION_LESS 3.1) - MESSAGE(WARNING "winebuild is not in PATH. Building RemoteVstPlugin may fail.") - ELSE() - SET(WINE_CXX_ARGS -E env PATH=$ENV{PATH}:${WINE_BINDIR} ${WINE_CXX} ${WINE_CXX_ARGS}) - SET(WINE_CXX "${CMAKE_COMMAND}") - ENDIF() - ENDIF() - - set(ENV{PATH} "$ENV{PATH}:${WINE_BINDIR}") - - ADD_CUSTOM_COMMAND( - SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/RemoteVstPlugin.cpp" - COMMAND export - ARGS "PATH=$PATH:${WINE_BINDIR}" - COMMAND ${WINE_CXX} - ARGS ${WINE_CXX_ARGS} - # Ensure correct file extension - COMMAND sh -c "mv ../RemoteVstPlugin.exe ../RemoteVstPlugin || true" - TARGET vstbase - OUTPUTS ../RemoteVstPlugin - VERBATIM - ) - - SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ../RemoteVstPlugin32.exe.so) - INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}") ENDIF() # build 64 bit version of RemoteVstPlugin IF(LMMS_BUILD_WIN64) ADD_SUBDIRECTORY(RemoteVstPlugin) +ELSEIF(LMMS_BUILD_LINUX AND NOT WANT_VST_NOWINE) + ExternalProject_Add(RemoteVstPlugin64 + ${EXTERNALPROJECT_ARGS} + CMAKE_ARGS + ${EXTERNALPROJECT_CMAKE_ARGS} + -DCMAKE_CXX_COMPILER=${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin/winegcc + ) ENDIF() - -ADD_SUBDIRECTORY(vstbase) diff --git a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt index d077a80c0..e5a27313f 100644 --- a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt +++ b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt @@ -1,17 +1,24 @@ cmake_minimum_required(VERSION 3.0.0) project(RemoteVstPlugin LANGUAGES CXX) - set(CMAKE_CXX_STANDARD 11) -if(CMAKE_SIZEOF_VOID_P EQUAL 8) +include(CheckCXXPreprocessor) + +CHECK_CXX_DEFINE(IS_WIN "_WIN32") +CHECK_CXX_DEFINE(IS_WIN64 "_WIN64") + +if(NOT IS_WIN) + message(FATAL_ERROR "Toolchain used does not target windows.") +ENDIF() + +if(IS_WIN64 OR CMAKE_SIZEOF_VOID_P EQUAL 8) set(BITNESS 64) else() set(BITNESS 32) endif() set(EXE_NAME RemoteVstPlugin${BITNESS}) - add_executable(${EXE_NAME} ../RemoteVstPlugin.cpp ) @@ -24,7 +31,7 @@ target_include_directories(${EXE_NAME} ) if(WIN32) - find_package(Qt5 REQUIRED COMPONENTS Core) + find_package(Qt5Core REQUIRED) target_link_libraries(${EXE_NAME} Qt5::Core) endif() diff --git a/plugins/vst_base/RemoteVstPlugin/winegcc b/plugins/vst_base/RemoteVstPlugin/winegcc new file mode 100755 index 000000000..018fb5ff7 --- /dev/null +++ b/plugins/vst_base/RemoteVstPlugin/winegcc @@ -0,0 +1,49 @@ +#!/bin/sh +# Wrapper script for winegcc to remove .exe file ending automatically +# appended by winebuild. +# Usage: winegcc + +set -e + +args="$@" + +# Find output name +POSITIONAL=() +while [ $# -gt 0 ]; do + key="$1" + + case $key in + -o) + output=$2 + shift + ;; + -c) + no_link=true + ;; + *) + + ;; + esac + + shift +done + +if [ -z "$output" ]; then + if [ "$no_link" != true ]; then + output="a.out" + no_move=true + fi +# echo "Fatal error in winegcc wrapper: Can't find output file name in args." +# exit 1 +fi + +wineg++ $args + +if [ -z "$no_link" ] && [ "$no_move" != true ]; then + if [ ! -e "$output.exe" ]; then + echo "Fatal error in winegcc wrapper: No output file \"$output.exe\" found." + exit 1 + fi + + mv $output.exe $output +fi diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 6096a0d49..e5323fb9d 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -81,14 +81,14 @@ VstPlugin::VstPlugin( const QString & _plugin ) : { setSplittedChannels( true ); -#ifdef LMMS_BUILD_WIN64 +#ifdef LMMS_HOST_X86_64 tryLoad( "RemoteVstPlugin64" ); if( m_badDllFormat ) { m_badDllFormat = false; #endif tryLoad( "RemoteVstPlugin32" ); -#ifdef LMMS_BUILD_WIN64 +#ifdef LMMS_HOST_X86_64 } #endif From bba072d54e7d99f544774ad70a03915ee11b48cc Mon Sep 17 00:00:00 2001 From: Lukas W Date: Mon, 27 Nov 2017 21:26:03 +0100 Subject: [PATCH 052/445] VST build fixes --- cmake/linux/winegcc_wrapper.in | 63 +++++++++++++++++++ cmake/modules/FindWine.cmake | 13 +++- plugins/vst_base/CMakeLists.txt | 20 +++--- .../vst_base/RemoteVstPlugin/CMakeLists.txt | 2 +- plugins/vst_base/RemoteVstPlugin/winegcc | 49 --------------- plugins/vst_base/VstPlugin.cpp | 4 +- src/core/RemotePlugin.cpp | 2 +- 7 files changed, 90 insertions(+), 63 deletions(-) create mode 100755 cmake/linux/winegcc_wrapper.in delete mode 100755 plugins/vst_base/RemoteVstPlugin/winegcc diff --git a/cmake/linux/winegcc_wrapper.in b/cmake/linux/winegcc_wrapper.in new file mode 100755 index 000000000..5894c593d --- /dev/null +++ b/cmake/linux/winegcc_wrapper.in @@ -0,0 +1,63 @@ +#!/bin/sh +# Wrapper script for winegcc to remove .exe file ending automatically +# appended by winebuild. +# Usage: winegcc + +set -e + +args="$@" + +# Find output name, link mode and architecture +while [ $# -gt 0 ]; do + key="$1" + + case $key in + -o) + output=$2 + shift + ;; + -c) + no_link=true + ;; + -m32) + win32=true + ;; + *) + + ;; + esac + + shift +done + +if [ -z "$output" ]; then + # If -c is used without specifying an output name, GCC defaults to "a.out". + if [ "$no_link" != true ]; then + output="a.out" + no_move=true + fi +fi + +# Some Wine distributions can't find their own headers. WINE_INCLUDE_DIR provided +# by FindWine.cmake +extra_args="-I@WINE_INCLUDE_DIR@" + +# Apply -m32 library fix if necessary +if [ "$win32" = true ] && [ "$no_link" != true ]; then + extra_args="$extra_args @WINE_32_FLAGS@" +fi + +# Run winegcc +export WINEBUILD=@WINE_BUILD@ +@WINE_CXX@ $extra_args $args + +if [ "$no_move" = true ] || [ "$no_link" = true ]; then + exit 0 +fi + +if [ ! -e "$output.exe" ]; then + echo "Fatal error in winegcc wrapper: No output file \"$output.exe\" found." + exit 1 +fi + +mv $output.exe $output diff --git a/cmake/modules/FindWine.cmake b/cmake/modules/FindWine.cmake index 9967dd9ba..13443b297 100644 --- a/cmake/modules/FindWine.cmake +++ b/cmake/modules/FindWine.cmake @@ -9,11 +9,12 @@ LIST(APPEND CMAKE_PREFIX_PATH /opt/wine-stable /opt/wine-devel /opt/wine-staging /usr/lib/wine/) -FIND_PATH(WINE_INCLUDE_DIR windows/windows.h PATH_SUFFIXES wine wine/wine) +FIND_PATH(WINE_INCLUDE_DIR wine/exception.h PATH_SUFFIXES wine) FIND_LIBRARY(WINE_LIBRARY NAMES wine PATH_SUFFIXES wine i386-linux-gnu/wine) FIND_PROGRAM(WINE_CXX NAMES wineg++ winegcc winegcc64 winegcc32 winegcc-stable PATHS /usr/lib/wine) +FIND_PROGRAM(WINE_BUILD NAMES winebuild) SET(WINE_INCLUDE_DIRS ${WINE_INCLUDE_DIR} ) SET(WINE_LIBRARIES ${WINE_LIBRARY} ) @@ -41,4 +42,12 @@ ENDFOREACH() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Wine DEFAULT_MSG WINE_CXX WINE_LIBRARIES WINE_INCLUDE_DIRS) -mark_as_advanced(WINE_INCLUDE_DIR WINE_LIBRARY) +mark_as_advanced(WINE_INCLUDE_DIR WINE_LIBRARY WINE_CXX WINE_BUILD) + +IF(WINE_LIBRARY_FIX) + SET(WINE_32_FLAGS "-L${WINE_LIBRARY_FIX}wine/ -L${WINE_LIBRARY_FIX}") +ENDIF() + +# Create winegcc wrapper +configure_file(${CMAKE_CURRENT_LIST_DIR}/../linux/winegcc_wrapper.in winegcc_wrapper @ONLY) +SET(WINEGCC "${CMAKE_CURRENT_BINARY_DIR}/winegcc_wrapper") diff --git a/plugins/vst_base/CMakeLists.txt b/plugins/vst_base/CMakeLists.txt index a355f87ff..5091b7cbf 100644 --- a/plugins/vst_base/CMakeLists.txt +++ b/plugins/vst_base/CMakeLists.txt @@ -7,6 +7,10 @@ INCLUDE(ExternalProject) ADD_SUBDIRECTORY(vstbase) +IF(LMMS_BUILD_LINUX AND WANT_VST_NOWINE) + RETURN() +ENDIF() + SET(LMMS_BINARY_DIR ${CMAKE_BINARY_DIR}) SET(LMMS_SOURCE_DIR ${CMAKE_SOURCE_DIR}) @@ -25,7 +29,6 @@ SET(EXTERNALPROJECT_CMAKE_ARGS # build 32 bit version of RemoteVstPlugin IF(LMMS_BUILD_WIN64 AND MSVC) - SET(MSVC_VER ${CMAKE_CXX_COMPILER_VERSION}) IF(MSVC_VER VERSION_GREATER 19.0 OR MSVC_VER VERSION_EQUAL 19.0) @@ -53,24 +56,25 @@ IF(LMMS_BUILD_WIN64 AND MSVC) ) ELSEIF(LMMS_BUILD_WIN32) ADD_SUBDIRECTORY(RemoteVstPlugin) -ELSEIF(LMMS_BUILD_LINUX AND NOT WANT_VST_NOWINE) +ELSEIF(LMMS_BUILD_LINUX) ExternalProject_Add(RemoteVstPlugin32 - ${EXTERNALPROJECT_ARGS} + "${EXTERNALPROJECT_ARGS}" CMAKE_ARGS ${EXTERNALPROJECT_CMAKE_ARGS} - -DCMAKE_CXX_COMPILER=${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin/winegcc - -DCMAKE_CXX_FLAGS="-m32" + -DCMAKE_CXX_COMPILER=${WINEGCC} + "-DCMAKE_CXX_FLAGS=-m32 -mwindows" ) ENDIF() # build 64 bit version of RemoteVstPlugin IF(LMMS_BUILD_WIN64) ADD_SUBDIRECTORY(RemoteVstPlugin) -ELSEIF(LMMS_BUILD_LINUX AND NOT WANT_VST_NOWINE) +ELSEIF(LMMS_BUILD_LINUX) ExternalProject_Add(RemoteVstPlugin64 - ${EXTERNALPROJECT_ARGS} + "${EXTERNALPROJECT_ARGS}" CMAKE_ARGS ${EXTERNALPROJECT_CMAKE_ARGS} - -DCMAKE_CXX_COMPILER=${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin/winegcc + -DCMAKE_CXX_COMPILER=${WINEGCC} + "-DCMAKE_CXX_FLAGS=-m64 -mwindows" ) ENDIF() diff --git a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt index e5a27313f..9c43f436c 100644 --- a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt +++ b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0.0) +cmake_minimum_required(VERSION 3.1) project(RemoteVstPlugin LANGUAGES CXX) set(CMAKE_CXX_STANDARD 11) diff --git a/plugins/vst_base/RemoteVstPlugin/winegcc b/plugins/vst_base/RemoteVstPlugin/winegcc deleted file mode 100755 index 018fb5ff7..000000000 --- a/plugins/vst_base/RemoteVstPlugin/winegcc +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh -# Wrapper script for winegcc to remove .exe file ending automatically -# appended by winebuild. -# Usage: winegcc - -set -e - -args="$@" - -# Find output name -POSITIONAL=() -while [ $# -gt 0 ]; do - key="$1" - - case $key in - -o) - output=$2 - shift - ;; - -c) - no_link=true - ;; - *) - - ;; - esac - - shift -done - -if [ -z "$output" ]; then - if [ "$no_link" != true ]; then - output="a.out" - no_move=true - fi -# echo "Fatal error in winegcc wrapper: Can't find output file name in args." -# exit 1 -fi - -wineg++ $args - -if [ -z "$no_link" ] && [ "$no_move" != true ]; then - if [ ! -e "$output.exe" ]; then - echo "Fatal error in winegcc wrapper: No output file \"$output.exe\" found." - exit 1 - fi - - mv $output.exe $output -fi diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index e5323fb9d..6096a0d49 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -81,14 +81,14 @@ VstPlugin::VstPlugin( const QString & _plugin ) : { setSplittedChannels( true ); -#ifdef LMMS_HOST_X86_64 +#ifdef LMMS_BUILD_WIN64 tryLoad( "RemoteVstPlugin64" ); if( m_badDllFormat ) { m_badDllFormat = false; #endif tryLoad( "RemoteVstPlugin32" ); -#ifdef LMMS_HOST_X86_64 +#ifdef LMMS_BUILD_WIN64 } #endif diff --git a/src/core/RemotePlugin.cpp b/src/core/RemotePlugin.cpp index 7b10ed50b..408b8631f 100644 --- a/src/core/RemotePlugin.cpp +++ b/src/core/RemotePlugin.cpp @@ -123,7 +123,7 @@ RemotePlugin::RemotePlugin() : connect( &m_process, SIGNAL( finished( int, QProcess::ExitStatus ) ), this, SLOT( processFinished( int, QProcess::ExitStatus ) ) ); - connect( &m_process, SIGNAL( errorOccured( QProcess::ProcessError ) ), + connect( &m_process, SIGNAL( errorOccurred( QProcess::ProcessError ) ), this, SLOT( processErrored( QProcess::ProcessError ) ) ); } From ff9622c10efb20006ca7a7beda0fb0b1037f15c1 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Tue, 28 Nov 2017 00:44:57 +0100 Subject: [PATCH 053/445] CMake quoting fixes --- plugins/vst_base/CMakeLists.txt | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/plugins/vst_base/CMakeLists.txt b/plugins/vst_base/CMakeLists.txt index 5091b7cbf..4db8e0796 100644 --- a/plugins/vst_base/CMakeLists.txt +++ b/plugins/vst_base/CMakeLists.txt @@ -21,10 +21,12 @@ SET(EXTERNALPROJECT_ARGS ) SET(EXTERNALPROJECT_CMAKE_ARGS - -DLMMS_SOURCE_DIR=${CMAKE_SOURCE_DIR} - -DLMMS_BINARY_DIR=${CMAKE_BINARY_DIR} - -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} - -DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH} + "-DLMMS_SOURCE_DIR=${CMAKE_SOURCE_DIR}" + "-DLMMS_BINARY_DIR=${CMAKE_BINARY_DIR}" + "-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" + "-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" + "-DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}" + "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" ) # build 32 bit version of RemoteVstPlugin @@ -48,11 +50,11 @@ IF(LMMS_BUILD_WIN64 AND MSVC) ENDIF() ExternalProject_Add(RemoteVstPlugin32 - ${EXTERNALPROJECT_ARGS} + "${EXTERNALPROJECT_ARGS}" CMAKE_GENERATOR ${GENERATOR} CMAKE_ARGS - ${EXTERNALPROJECT_CMAKE_ARGS} - -DCMAKE_PREFIX_PATH=${QT_32_PREFIX} + "${EXTERNALPROJECT_CMAKE_ARGS}" + "-DCMAKE_PREFIX_PATH=${QT_32_PREFIX}" ) ELSEIF(LMMS_BUILD_WIN32) ADD_SUBDIRECTORY(RemoteVstPlugin) @@ -60,8 +62,8 @@ ELSEIF(LMMS_BUILD_LINUX) ExternalProject_Add(RemoteVstPlugin32 "${EXTERNALPROJECT_ARGS}" CMAKE_ARGS - ${EXTERNALPROJECT_CMAKE_ARGS} - -DCMAKE_CXX_COMPILER=${WINEGCC} + "${EXTERNALPROJECT_CMAKE_ARGS}" + "-DCMAKE_CXX_COMPILER=${WINEGCC}" "-DCMAKE_CXX_FLAGS=-m32 -mwindows" ) ENDIF() @@ -73,8 +75,8 @@ ELSEIF(LMMS_BUILD_LINUX) ExternalProject_Add(RemoteVstPlugin64 "${EXTERNALPROJECT_ARGS}" CMAKE_ARGS - ${EXTERNALPROJECT_CMAKE_ARGS} - -DCMAKE_CXX_COMPILER=${WINEGCC} + "${EXTERNALPROJECT_CMAKE_ARGS}" + "-DCMAKE_CXX_COMPILER=${WINEGCC}" "-DCMAKE_CXX_FLAGS=-m64 -mwindows" ) ENDIF() From 48cdce9a790b6ba7384a36d5b4a6ffadc21a89bd Mon Sep 17 00:00:00 2001 From: Lukas W Date: Tue, 28 Nov 2017 11:00:11 +0100 Subject: [PATCH 054/445] Fix compilation with MinGW versions without threads support Older versions of MinGW don't provide std::mutex or std::thread --- .gitmodules | 3 +++ cmake/build_win32.sh | 2 +- plugins/vst_base/RemoteVstPlugin.cpp | 7 ++++++- .../vst_base/RemoteVstPlugin/CMakeLists.txt | 21 +++++++++++++++++++ src/3rdparty/mingw-std-threads | 1 + 5 files changed, 32 insertions(+), 2 deletions(-) create mode 160000 src/3rdparty/mingw-std-threads diff --git a/.gitmodules b/.gitmodules index 94530a197..3f4859b56 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,3 +28,6 @@ [submodule "src/3rdparty/weakjack/weakjack"] path = src/3rdparty/weakjack/weakjack url = https://github.com/x42/weakjack.git +[submodule "src/3rdparty/mingw-std-threads"] + path = src/3rdparty/mingw-std-threads + url = https://github.com/meganz/mingw-std-threads.git diff --git a/cmake/build_win32.sh b/cmake/build_win32.sh index 6fbf5287b..33cd8ecce 100755 --- a/cmake/build_win32.sh +++ b/cmake/build_win32.sh @@ -37,4 +37,4 @@ fi CMAKE_OPTS="-DCMAKE_PREFIX_PATH=$MINGW $CMAKE_OPTS" # shellcheck disable=SC2086 -cmake "$DIR/.." -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN" -DCMAKE_MODULE_PATH="$DIR/../cmake/modules/" $CMAKE_OPTS +cmake "$DIR/.." -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN" $CMAKE_OPTS diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index db5c99e8f..6110cb253 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -59,7 +59,12 @@ #define USE_WS_PREFIX #include -#include +#ifdef USE_MINGW_THREADS_REPLACEMENT +# include +#else +# include +#endif + #include #include #include diff --git a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt index 9c43f436c..59dfd1282 100644 --- a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt +++ b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt @@ -4,9 +4,11 @@ project(RemoteVstPlugin set(CMAKE_CXX_STANDARD 11) include(CheckCXXPreprocessor) +include(CheckCXXSourceCompiles) CHECK_CXX_DEFINE(IS_WIN "_WIN32") CHECK_CXX_DEFINE(IS_WIN64 "_WIN64") +CHECK_CXX_DEFINE(IS_MINGW "__MINGW32__") if(NOT IS_WIN) message(FATAL_ERROR "Toolchain used does not target windows.") @@ -35,6 +37,25 @@ if(WIN32) target_link_libraries(${EXE_NAME} Qt5::Core) endif() +if(IS_MINGW) + SET(CMAKE_REQUIRED_FLAGS "-std=c++11") + + CHECK_CXX_SOURCE_COMPILES(" + #include + int main(int argc, const char* argv[]) { + std::mutex m; + return 0; + } + " HAS_STD_MUTEX) + + if(NOT HAS_STD_MUTEX) + target_include_directories(${EXE_NAME} PRIVATE + "${CMAKE_SOURCE_DIR}/src/3rdparty/mingw-std-threads") + target_compile_definitions(${EXE_NAME} PRIVATE + -DUSE_MINGW_THREADS_REPLACEMENT) + endif() +endif() + IF(STRIP) ADD_CUSTOM_COMMAND(TARGET RemoteVstPlugin32 POST_BUILD COMMAND "${STRIP}" "$") ENDIF() diff --git a/src/3rdparty/mingw-std-threads b/src/3rdparty/mingw-std-threads new file mode 160000 index 000000000..10665829d --- /dev/null +++ b/src/3rdparty/mingw-std-threads @@ -0,0 +1 @@ +Subproject commit 10665829daaedc28629e5e9b014fe498c20d73f2 From 2e6bb7284799974fb35e772f56407effe87bccfd Mon Sep 17 00:00:00 2001 From: Lukas W Date: Tue, 28 Nov 2017 15:47:03 +0100 Subject: [PATCH 055/445] Fix export errors with MinGW --- src/CMakeLists.txt | 12 ++++++++---- tests/CMakeLists.txt | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 42e667aca..29a4c4707 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -105,10 +105,6 @@ ADD_LIBRARY(lmmsobjs OBJECT GENERATE_EXPORT_HEADER(lmmsobjs BASE_NAME lmms ) -# GENERATE_EXPORT_HEADER doesn't seem to do this automatically -TARGET_COMPILE_DEFINITIONS(lmmsobjs - PRIVATE -Dlmmsobjs_EXPORTS -) ADD_EXECUTABLE(lmms core/main.cpp @@ -119,6 +115,14 @@ TARGET_INCLUDE_DIRECTORIES(lmms PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ) +# GENERATE_EXPORT_HEADER doesn't do this automatically for OBJECT libraries +TARGET_COMPILE_DEFINITIONS(lmmsobjs + PRIVATE -Dlmmsobjs_EXPORTS +) +TARGET_COMPILE_DEFINITIONS(lmms + PRIVATE -Dlmmsobjs_EXPORTS +) + # Set Visual Studio startup project to lmms # https://stackoverflow.com/a/37994396/8166701 IF(NOT CMAKE_VERSION VERSION_LESS 3.6) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ca78a5eb4..249e38191 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,6 +2,7 @@ INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}") INCLUDE_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}") INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include") INCLUDE_DIRECTORIES("${CMAKE_BINARY_DIR}") +INCLUDE_DIRECTORIES("${CMAKE_BINARY_DIR}/src") SET(CMAKE_CXX_STANDARD 11) From 90799d91ea5cf5822c81dd95e029cf23437df7d0 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Tue, 28 Nov 2017 18:18:58 +0100 Subject: [PATCH 056/445] Mingw64 compilation fixes --- cmake/toolchains/Ubuntu-MinGW-W64-64.cmake | 2 ++ cmake/toolchains/Ubuntu-MinGW-X-Trusty-64.cmake | 3 +++ plugins/vst_base/CMakeLists.txt | 17 ++++++++++++++--- plugins/vst_base/RemoteVstPlugin/CMakeLists.txt | 4 ++-- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/cmake/toolchains/Ubuntu-MinGW-W64-64.cmake b/cmake/toolchains/Ubuntu-MinGW-W64-64.cmake index e10ae7311..a1b33ec67 100644 --- a/cmake/toolchains/Ubuntu-MinGW-W64-64.cmake +++ b/cmake/toolchains/Ubuntu-MinGW-W64-64.cmake @@ -1,2 +1,4 @@ +SET(CMAKE_TOOLCHAIN_FILE_32 "${CMAKE_CURRENT_LIST_DIR}/Ubuntu-MinGW-W64-32.cmake") + INCLUDE(${CMAKE_CURRENT_LIST_DIR}/common/Win64.cmake) INCLUDE(${CMAKE_CURRENT_LIST_DIR}/common/Ubuntu-MinGW-W64.cmake) diff --git a/cmake/toolchains/Ubuntu-MinGW-X-Trusty-64.cmake b/cmake/toolchains/Ubuntu-MinGW-X-Trusty-64.cmake index 705e41eae..0f448fef5 100644 --- a/cmake/toolchains/Ubuntu-MinGW-X-Trusty-64.cmake +++ b/cmake/toolchains/Ubuntu-MinGW-X-Trusty-64.cmake @@ -3,4 +3,7 @@ SET(MINGW_PREFIX32 /opt/mingw32) SET(WIN64 TRUE) +SET(CMAKE_TOOLCHAIN_FILE_32 "${CMAKE_CURRENT_LIST_DIR}/Ubuntu-MinGW-X-Trusty-32.cmake") +SET(CMAKE_PREFIX_PATH_32 "${MINGW_PREFIX32}") + INCLUDE(${CMAKE_CURRENT_LIST_DIR}/common/Ubuntu-MinGW-X-Trusty.cmake) diff --git a/plugins/vst_base/CMakeLists.txt b/plugins/vst_base/CMakeLists.txt index 4db8e0796..943631b92 100644 --- a/plugins/vst_base/CMakeLists.txt +++ b/plugins/vst_base/CMakeLists.txt @@ -30,7 +30,9 @@ SET(EXTERNALPROJECT_CMAKE_ARGS ) # build 32 bit version of RemoteVstPlugin -IF(LMMS_BUILD_WIN64 AND MSVC) +IF(LMMS_BUILD_WIN32 AND NOT LMMS_BUILD_WIN64) + ADD_SUBDIRECTORY(RemoteVstPlugin) +ELSEIF(LMMS_BUILD_WIN64 AND MSVC) SET(MSVC_VER ${CMAKE_CXX_COMPILER_VERSION}) IF(MSVC_VER VERSION_GREATER 19.0 OR MSVC_VER VERSION_EQUAL 19.0) @@ -56,9 +58,8 @@ IF(LMMS_BUILD_WIN64 AND MSVC) "${EXTERNALPROJECT_CMAKE_ARGS}" "-DCMAKE_PREFIX_PATH=${QT_32_PREFIX}" ) -ELSEIF(LMMS_BUILD_WIN32) - ADD_SUBDIRECTORY(RemoteVstPlugin) ELSEIF(LMMS_BUILD_LINUX) + # Use winegcc ExternalProject_Add(RemoteVstPlugin32 "${EXTERNALPROJECT_ARGS}" CMAKE_ARGS @@ -66,6 +67,16 @@ ELSEIF(LMMS_BUILD_LINUX) "-DCMAKE_CXX_COMPILER=${WINEGCC}" "-DCMAKE_CXX_FLAGS=-m32 -mwindows" ) +ELSEIF(CMAKE_TOOLCHAIN_FILE_32) + ExternalProject_Add(RemoteVstPlugin32 + "${EXTERNALPROJECT_ARGS}" + CMAKE_ARGS + "${EXTERNALPROJECT_CMAKE_ARGS}" + "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH_32}" + "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE_32}" + ) +ELSE() + message(SEND_ERROR "Can't build RemoteVstPlugin32, unknown environment. Please supply CMAKE_TOOLCHAIN_FILE_32 and optionally CMAKE_PREFIX_PATH_32") ENDIF() # build 64 bit version of RemoteVstPlugin diff --git a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt index 59dfd1282..f6b3e9c4e 100644 --- a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt +++ b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt @@ -50,12 +50,12 @@ if(IS_MINGW) if(NOT HAS_STD_MUTEX) target_include_directories(${EXE_NAME} PRIVATE - "${CMAKE_SOURCE_DIR}/src/3rdparty/mingw-std-threads") + "${LMMS_SOURCE_DIR}/src/3rdparty/mingw-std-threads") target_compile_definitions(${EXE_NAME} PRIVATE -DUSE_MINGW_THREADS_REPLACEMENT) endif() endif() IF(STRIP) - ADD_CUSTOM_COMMAND(TARGET RemoteVstPlugin32 POST_BUILD COMMAND "${STRIP}" "$") + ADD_CUSTOM_COMMAND(TARGET ${EXE_NAME} POST_BUILD COMMAND "${STRIP}" "$") ENDIF() From d454ef60e2272f95f9e638721899144b39ba5aa7 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Tue, 28 Nov 2017 18:45:21 +0100 Subject: [PATCH 057/445] More export fixes --- plugins/GigPlayer/GigPlayer.cpp | 2 +- plugins/Xpressive/Xpressive.cpp | 2 +- plugins/carlapatchbay/carlapatchbay.cpp | 2 +- plugins/carlarack/carlarack.cpp | 2 +- plugins/sf2_player/sf2_player.cpp | 2 +- plugins/stk/mallets/mallets.cpp | 2 +- src/3rdparty/CMakeLists.txt | 2 ++ 7 files changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/GigPlayer/GigPlayer.cpp b/plugins/GigPlayer/GigPlayer.cpp index 66212427c..bf5990252 100644 --- a/plugins/GigPlayer/GigPlayer.cpp +++ b/plugins/GigPlayer/GigPlayer.cpp @@ -1390,7 +1390,7 @@ extern "C" { // necessary for getting instance out of shared lib -Plugin * PLUGIN_EXPORT lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) { return new GigInstrument( static_cast( _data ) ); } diff --git a/plugins/Xpressive/Xpressive.cpp b/plugins/Xpressive/Xpressive.cpp index 5e500a744..5822c9567 100644 --- a/plugins/Xpressive/Xpressive.cpp +++ b/plugins/Xpressive/Xpressive.cpp @@ -884,7 +884,7 @@ __attribute__((destructor)) static void module_destroy() extern "C" { // necessary for getting instance out of shared lib -Plugin * PLUGIN_EXPORT lmms_plugin_main(Model *, void * _data) { +PLUGIN_EXPORT Plugin * lmms_plugin_main(Model *, void * _data) { return (new Xpressive(static_cast(_data))); } diff --git a/plugins/carlapatchbay/carlapatchbay.cpp b/plugins/carlapatchbay/carlapatchbay.cpp index d67ffebb8..bfc757070 100644 --- a/plugins/carlapatchbay/carlapatchbay.cpp +++ b/plugins/carlapatchbay/carlapatchbay.cpp @@ -43,7 +43,7 @@ Plugin::Descriptor PLUGIN_EXPORT carlapatchbay_plugin_descriptor = NULL } ; -Plugin* PLUGIN_EXPORT lmms_plugin_main(Model*, void* data) +PLUGIN_EXPORT Plugin* lmms_plugin_main(Model*, void* data) { return new CarlaInstrument(static_cast(data), &carlapatchbay_plugin_descriptor, true); } diff --git a/plugins/carlarack/carlarack.cpp b/plugins/carlarack/carlarack.cpp index 5225f46b9..420bc3029 100644 --- a/plugins/carlarack/carlarack.cpp +++ b/plugins/carlarack/carlarack.cpp @@ -43,7 +43,7 @@ Plugin::Descriptor PLUGIN_EXPORT carlarack_plugin_descriptor = NULL } ; -Plugin* PLUGIN_EXPORT lmms_plugin_main(Model*, void* data) +PLUGIN_EXPORT Plugin* lmms_plugin_main(Model*, void* data) { return new CarlaInstrument(static_cast(data), &carlarack_plugin_descriptor, false); } diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index bef1324f5..292c5750f 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -1123,7 +1123,7 @@ extern "C" { // necessary for getting instance out of shared lib -Plugin * PLUGIN_EXPORT lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) { return new sf2Instrument( static_cast( _data ) ); } diff --git a/plugins/stk/mallets/mallets.cpp b/plugins/stk/mallets/mallets.cpp index 9c138aaa9..7111bcdaa 100644 --- a/plugins/stk/mallets/mallets.cpp +++ b/plugins/stk/mallets/mallets.cpp @@ -756,7 +756,7 @@ extern "C" { // necessary for getting instance out of shared lib -Plugin * PLUGIN_EXPORT lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) { return new malletsInstrument( static_cast( _data ) ); } diff --git a/src/3rdparty/CMakeLists.txt b/src/3rdparty/CMakeLists.txt index 7bc0a8790..b40f7c3cd 100644 --- a/src/3rdparty/CMakeLists.txt +++ b/src/3rdparty/CMakeLists.txt @@ -1,5 +1,7 @@ set(CMAKE_C_FLAGS "") set(CMAKE_CXX_FLAGS "") +set(CMAKE_C_FLAGS_DEBUG "") +set(CMAKE_CXX_FLAGS_DEBUG "") IF(LMMS_BUILD_LINUX) set(BUILD_SHARED_LIBS OFF) From 20a6b96161134d01d28783f938e31a09cd4d01c2 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 14 Jan 2018 23:03:10 +0100 Subject: [PATCH 058/445] Fix 64bit VSTs on Linux by fixing callback calling convention --- include/aeffectx.h | 15 +++++++++------ plugins/vst_base/RemoteVstPlugin.cpp | 4 ++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/include/aeffectx.h b/include/aeffectx.h index b2f8f0c6d..133d925ac 100644 --- a/include/aeffectx.h +++ b/include/aeffectx.h @@ -28,6 +28,9 @@ #include +// Calling convention +#define VST_CALL_CONV __cdecl + #define CCONST(a, b, c, d)( ( ( (int32_t) a ) << 24 ) | \ ( ( (int32_t) b ) << 16 ) | \ ( ( (int32_t) c ) << 8 ) | \ @@ -205,13 +208,13 @@ public: // 00-03 int32_t magic; // dispatcher 04-07 - intptr_t (* dispatcher)( AEffect * , int32_t , int32_t , intptr_t, void * , float ); + intptr_t (VST_CALL_CONV * dispatcher)( AEffect * , int32_t , int32_t , intptr_t, void * , float ); // process, quite sure 08-0b - void (* process)( AEffect * , float * * , float * * , int32_t ); + void (VST_CALL_CONV * process)( AEffect * , float * * , float * * , int32_t ); // setParameter 0c-0f - void (* setParameter)( AEffect * , int32_t , float ); + void (VST_CALL_CONV * setParameter)( AEffect * , int32_t , float ); // getParameter 10-13 - float (* getParameter)( AEffect * , int32_t ); + float (VST_CALL_CONV * getParameter)( AEffect * , int32_t ); // programs 14-17 int32_t numPrograms; // Params 18-1b @@ -238,7 +241,7 @@ public: // Don't know 4c-4f char unknown1[4]; // processReplacing 50-53 - void (* processReplacing)( AEffect * , float * * , float * * , int ); + void (VST_CALL_CONV * processReplacing)( AEffect * , float * * , float * * , int ); } ; @@ -281,7 +284,7 @@ public: -typedef intptr_t (* audioMasterCallback)( AEffect * , int32_t, int32_t, intptr_t, void * , float ); +typedef intptr_t (VST_CALL_CONV * audioMasterCallback)( AEffect * , int32_t, int32_t, intptr_t, void * , float ); #endif diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 6110cb253..ab3812ed4 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -331,7 +331,7 @@ private: } ; // callback used by plugin for being able to communicate with it's host - static intptr_t hostCallback( AEffect * _effect, int32_t _opcode, + static VST_CALL_CONV intptr_t hostCallback( AEffect * _effect, int32_t _opcode, int32_t _index, intptr_t _value, void * _ptr, float _opt ); @@ -819,7 +819,7 @@ bool RemoteVstPlugin::load( const std::string & _plugin_file ) return false; } - typedef AEffect * ( __cdecl * mainEntryPointer ) + typedef AEffect * ( VST_CALL_CONV * mainEntryPointer ) ( audioMasterCallback ); mainEntryPointer mainEntry = (mainEntryPointer) GetProcAddress( m_libInst, "VSTPluginMain" ); From 23e284b189187b81df1d01730d929745d723e844 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Wed, 9 May 2018 22:26:31 +0200 Subject: [PATCH 059/445] CMake: Fix Clang detection --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2dbdf3963..a2f0ecd56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -480,7 +480,7 @@ ENDIF(WANT_DEBUG_FPE) PKG_CHECK_MODULES(SAMPLERATE REQUIRED samplerate>=0.1.8) # set compiler flags -IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|AppleClang") +IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") SET(WERROR_FLAGS "-Wall -Werror=unused-function -Wno-sign-compare -Wno-strict-overflow") OPTION(USE_WERROR "Add -werror to the build flags. Stops the build on warnings" OFF) IF(${USE_WERROR}) From f2a8f56944664b9724dc0370ed5ae0c777506495 Mon Sep 17 00:00:00 2001 From: justnope <39016732+justnope@users.noreply.github.com> Date: Tue, 22 May 2018 15:46:00 +0200 Subject: [PATCH 060/445] MSVC fixes (#4352) * locale: using path instead of individual files to reduce command line size * remotevstplugin: changed order return type & calling convention (compiler error) * lmmsobj: removed single quotes for command line defines * added vcpkg support & std::make_unique for MSVC * carla: include exports header * package_linux: corrected RemoteVstPlugin name * vstbase: toolchain file conditional on MSVC * Added install for remotevstplugin * msvc: installer works with vcpkg Remotevst 64bit install removed due to an ApImage problem --- CMakeLists.txt | 34 ++- cmake/linux/package_linux.sh.in | 4 +- cmake/nsis/CMakeLists.txt | 6 +- data/locale/CMakeLists.txt | 2 +- include/stdshims.h | 4 +- plugins/carlabase/carla.h | 2 +- plugins/vst_base/CMakeLists.txt | 36 +-- plugins/vst_base/RemoteVstPlugin.cpp | 2 +- .../vst_base/RemoteVstPlugin/CMakeLists.txt | 5 + src/CMakeLists.txt | 282 ++++++++++++------ 10 files changed, 261 insertions(+), 116 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a2f0ecd56..492601769 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,9 @@ ENDIF() INCLUDE(VersionInfo) INCLUDE(DetectMachine) +IF(CMAKE_TOOLCHAIN_FILE MATCHES "vcpkg.cmake$") + SET(USING_VCPKG TRUE) +ENDIF() OPTION(WANT_ALSA "Include ALSA (Advanced Linux Sound Architecture) support" ON) OPTION(WANT_CALF "Include CALF LADSPA plugins" ON) @@ -166,10 +169,15 @@ FIND_PACKAGE(Qt5Test) SET(QT_QTTEST_LIBRARY Qt5::Test) # check for libsndfile -PKG_CHECK_MODULES(SNDFILE REQUIRED sndfile>=1.0.18) -IF(NOT SNDFILE_FOUND) - MESSAGE(FATAL_ERROR "LMMS requires libsndfile1 and libsndfile1-dev >= 1.0.18 - please install, remove CMakeCache.txt and try again!") -ENDIF() +IF(USING_VCPKG) + FIND_PACKAGE(LibSndFile 1.0.18 REQUIRED) + SET(SNDFILE_LIBRARIES sndfile-shared) +ELSE(USING_VCPKG) + PKG_CHECK_MODULES(SNDFILE REQUIRED sndfile>=1.0.18) + IF(NOT SNDFILE_FOUND) + MESSAGE(FATAL_ERROR "LMMS requires libsndfile1 and libsndfile1-dev >= 1.0.18 - please install, remove CMakeCache.txt and try again!") + ENDIF() +ENDIF(USING_VCPKG) # check if we can use SF_SET_COMPRESSION_LEVEL IF(NOT SNDFILE_VERSION VERSION_LESS 1.0.26) SET(LMMS_HAVE_SF_COMPLEVEL TRUE) @@ -394,8 +402,13 @@ ENDIF(WANT_JACK) # check for FFTW3F-library -PKG_CHECK_MODULES(FFTW3F REQUIRED fftw3f>=3.0.0) - +IF(USING_VCPKG) + #currently find_package for fftw is broken in vcpkg. Replace this when fixed + FIND_PATH(FFTW3F_INCLUDE_DIRS fftw3.h) + FIND_LIBRARY(FFTW3F_LIBRARIES fftw3f) +ELSE(USING_VCPKG) + PKG_CHECK_MODULES(FFTW3F REQUIRED fftw3f>=3.0.0) +ENDIF(USING_VCPKG) # check for FLTK FIND_PACKAGE(FLTK) @@ -477,7 +490,13 @@ ELSE() ENDIF(WANT_DEBUG_FPE) # check for libsamplerate -PKG_CHECK_MODULES(SAMPLERATE REQUIRED samplerate>=0.1.8) +IF(USING_VCPKG) + #TODO no cmake config support. Can we check the version some other way? + FIND_FILE(SAMPLERATE_INCLUDE_DIRS samplerate.h) + FIND_LIBRARY(SAMPLERATE_LIBRARIES libsamplerate-0) +ELSE(USING_VCPKG) + PKG_CHECK_MODULES(SAMPLERATE REQUIRED samplerate>=0.1.8) +ENDIF(USING_VCPKG) # set compiler flags IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") @@ -700,4 +719,5 @@ MESSAGE( "-----------------------------------------------------------------\n" "\n\n") +SET(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION "${BIN_DIR}") INCLUDE(InstallRequiredSystemLibraries) diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index ec6224e35..16866e4d4 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -139,10 +139,10 @@ fi # Move executables so linuxdeployqt can find them ZYNLIB="${APPDIR}usr/lib/lmms/RemoteZynAddSubFx" -VSTLIB="${APPDIR}usr/lib/lmms/RemoteVstPlugin.exe.so" +VSTLIB="${APPDIR}usr/lib/lmms/RemoteVstPlugin32.exe.so" ZYNBIN="${APPDIR}usr/bin/RemoteZynAddSubFx" -VSTBIN="${APPDIR}usr/bin/RemoteVstPlugin.exe.so" +VSTBIN="${APPDIR}usr/bin/RemoteVstPlugin32.exe.so" mv "$ZYNLIB" "$ZYNBIN" mv "$VSTLIB" "$VSTBIN" diff --git a/cmake/nsis/CMakeLists.txt b/cmake/nsis/CMakeLists.txt index 065b20819..a19555a19 100644 --- a/cmake/nsis/CMakeLists.txt +++ b/cmake/nsis/CMakeLists.txt @@ -1,4 +1,7 @@ SET(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis/nsis_branding.bmp") +IF(MSVC) + STRING(REPLACE "/" "\\\\" CPACK_PACKAGE_ICON ${CPACK_PACKAGE_ICON}) +ENDIF(MSVC) SET(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis/lmms.ico") SET(CPACK_NSIS_INSTALLED_ICON_NAME "${CMAKE_PROJECT_NAME}.exe" PARENT_SCOPE) SET(CPACK_NSIS_DISPLAY_NAME "${PROJECT_NAME_UCASE} ${VERSION}" PARENT_SCOPE) @@ -8,7 +11,8 @@ SET(CPACK_NSIS_CONTACT "${PROJECT_EMAIL}" PARENT_SCOPE) SET(CPACK_PACKAGE_EXECUTABLES "${CMAKE_PROJECT_NAME}.exe;${PROJECT_NAME_UCASE}" PARENT_SCOPE) SET(CPACK_NSIS_MENU_LINKS "${CMAKE_PROJECT_NAME}.exe;${PROJECT_NAME_UCASE}" PARENT_SCOPE) SET(CPACK_NSIS_DEFINES " - !include ${CMAKE_SOURCE_DIR}/cmake/nsis/FileAssociation.nsh + !addincludedir ${CMAKE_SOURCE_DIR}/cmake/nsis + !include FileAssociation.nsh !include LogicLib.nsh !include WinVer.nsh") SET(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${VERSION}-win32") diff --git a/data/locale/CMakeLists.txt b/data/locale/CMakeLists.txt index 3c72e7d78..9a7726406 100644 --- a/data/locale/CMakeLists.txt +++ b/data/locale/CMakeLists.txt @@ -26,7 +26,7 @@ FOREACH(_ts_file ${lmms_LOCALES}) STRING(REPLACE ".ts" ".qm" _qm_file "${_ts_file}") STRING(REPLACE ".ts" ".qm" _qm_target "${_ts_target}") ADD_CUSTOM_TARGET(${_ts_target} - COMMAND "${QT_LUPDATE_EXECUTABLE}" -locations none -no-obsolete -I ${CMAKE_SOURCE_DIR}/include/ ${LMMS_SRCS} ${LMMS_INCLUDES} ${LMMS_UIS} `find "\"${CMAKE_SOURCE_DIR}/plugins/\"" -type f -name '*.cpp' -or -name '*.h'` -ts "\"${_ts_file}\"" + COMMAND "${QT_LUPDATE_EXECUTABLE}" -locations none -no-obsolete -I ${CMAKE_SOURCE_DIR}/include/ ${LMMS_SRCS} ${LMMS_UIS} ${CMAKE_SOURCE_DIR}/plugins -ts "\"${_ts_file}\"" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) ADD_CUSTOM_TARGET(${_qm_target} COMMAND "${QT_LRELEASE_EXECUTABLE}" "${_ts_file}" -qm "${_qm_file}" diff --git a/include/stdshims.h b/include/stdshims.h index 456d31607..85c4f457a 100644 --- a/include/stdshims.h +++ b/include/stdshims.h @@ -7,8 +7,10 @@ #include #include -#if (__cplusplus >= 201402L) +#if (__cplusplus >= 201402L || _MSC_VER) +#ifndef _MSC_VER #warning "This file should now be removed! The functions it provides are part of the C++14 standard." +#endif using std::make_unique; #else diff --git a/plugins/carlabase/carla.h b/plugins/carlabase/carla.h index 6431e5300..175a570d6 100644 --- a/plugins/carlabase/carla.h +++ b/plugins/carlabase/carla.h @@ -26,9 +26,9 @@ #define CARLA_H #include +#include "plugin_export.h" #include "CarlaNative.h" - #include "Instrument.h" #include "InstrumentView.h" diff --git a/plugins/vst_base/CMakeLists.txt b/plugins/vst_base/CMakeLists.txt index 943631b92..42b5930b7 100644 --- a/plugins/vst_base/CMakeLists.txt +++ b/plugins/vst_base/CMakeLists.txt @@ -24,7 +24,6 @@ SET(EXTERNALPROJECT_CMAKE_ARGS "-DLMMS_SOURCE_DIR=${CMAKE_SOURCE_DIR}" "-DLMMS_BINARY_DIR=${CMAKE_BINARY_DIR}" "-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" - "-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" "-DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}" "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" ) @@ -33,29 +32,23 @@ SET(EXTERNALPROJECT_CMAKE_ARGS IF(LMMS_BUILD_WIN32 AND NOT LMMS_BUILD_WIN64) ADD_SUBDIRECTORY(RemoteVstPlugin) ELSEIF(LMMS_BUILD_WIN64 AND MSVC) - SET(MSVC_VER ${CMAKE_CXX_COMPILER_VERSION}) + STRING(REPLACE " Win64" "" GENERATOR ${CMAKE_GENERATOR}) - IF(MSVC_VER VERSION_GREATER 19.0 OR MSVC_VER VERSION_EQUAL 19.0) - SET(GENERATOR "Visual Studio 14 2015") - SET(MSVC_YEAR 2015) - ELSEIF(MSVC_VER VERSION_EQUAL 19.10 OR MSVC_VER VERSION_EQUAL 19.10) - SET(GENERATOR "Visual Studio 15 2017") - SET(MSVC_YEAR 2017) - ELSE() - MESSAGE(SEND_ERROR "Can't build RemoteVstPlugin32, unknown MSVC version ${MSVC_VER}") - ENDIF() - - GET_FILENAME_COMPONENT(QT_BIN_DIR ${QT_QMAKE_EXECUTABLE} DIRECTORY) - SET(QT_32_PREFIX "${QT_BIN_DIR}/../../msvc${MSVC_YEAR}") - IF(NOT (IS_DIRECTORY ${QT_32_PREFIX} AND EXISTS ${QT_32_PREFIX}/bin/qmake.exe)) - MESSAGE(SEND_ERROR "Can't build RemoteVstPlugin32, no Qt 32 bit installation found at ${QT_32_PREFIX}") - ENDIF() + IF(NOT USING_VCPKG) + GET_FILENAME_COMPONENT(QT_BIN_DIR ${QT_QMAKE_EXECUTABLE} DIRECTORY) + SET(QT_32_PREFIX "${QT_BIN_DIR}/../../msvc${MSVC_YEAR}") + IF(NOT (IS_DIRECTORY ${QT_32_PREFIX} AND EXISTS ${QT_32_PREFIX}/bin/qmake.exe)) + MESSAGE(SEND_ERROR "Can't build RemoteVstPlugin32, no Qt 32 bit installation found at ${QT_32_PREFIX}") + ENDIF() + ENDIF(NOT USING_VCPKG) ExternalProject_Add(RemoteVstPlugin32 "${EXTERNALPROJECT_ARGS}" CMAKE_GENERATOR ${GENERATOR} + CMAKE_GENERATOR_TOOLSET ${CMAKE_GENERATOR_TOOLSET} CMAKE_ARGS "${EXTERNALPROJECT_CMAKE_ARGS}" + "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" "-DCMAKE_PREFIX_PATH=${QT_32_PREFIX}" ) ELSEIF(LMMS_BUILD_LINUX) @@ -82,6 +75,7 @@ ENDIF() # build 64 bit version of RemoteVstPlugin IF(LMMS_BUILD_WIN64) ADD_SUBDIRECTORY(RemoteVstPlugin) + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin64.exe" DESTINATION "${PLUGIN_DIR}") ELSEIF(LMMS_BUILD_LINUX) ExternalProject_Add(RemoteVstPlugin64 "${EXTERNALPROJECT_ARGS}" @@ -91,3 +85,11 @@ ELSEIF(LMMS_BUILD_LINUX) "-DCMAKE_CXX_FLAGS=-m64 -mwindows" ) ENDIF() + +IF(TARGET RemoteVstPlugin32) + 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() +ENDIF() \ No newline at end of file diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index ab3812ed4..d28661357 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -331,7 +331,7 @@ private: } ; // callback used by plugin for being able to communicate with it's host - static VST_CALL_CONV intptr_t hostCallback( AEffect * _effect, int32_t _opcode, + static intptr_t VST_CALL_CONV hostCallback( AEffect * _effect, int32_t _opcode, int32_t _index, intptr_t _value, void * _ptr, float _opt ); diff --git a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt index f6b3e9c4e..1baf94064 100644 --- a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt +++ b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt @@ -20,6 +20,11 @@ else() set(BITNESS 32) endif() +FOREACH( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} ) + STRING(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG) + SET("CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") +ENDFOREACH() + set(EXE_NAME RemoteVstPlugin${BITNESS}) add_executable(${EXE_NAME} ../RemoteVstPlugin.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 29a4c4707..f798881c7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -51,12 +51,13 @@ ADD_GEN_QRC(LMMS_RCC_OUT lmms.qrc # Paths relative to lmms executable FILE(RELATIVE_PATH LIB_DIR_RELATIVE "/${BIN_DIR}" "/${LIB_DIR}") FILE(RELATIVE_PATH PLUGIN_DIR_RELATIVE "/${BIN_DIR}" "/${PLUGIN_DIR}") -ADD_DEFINITIONS(-D'LIB_DIR="${LIB_DIR_RELATIVE}/"' -D'PLUGIN_DIR="${PLUGIN_DIR_RELATIVE}/"' ${PULSEAUDIO_DEFINITIONS} ${PORTAUDIO_DEFINITIONS}) +ADD_DEFINITIONS(-DLIB_DIR="${LIB_DIR_RELATIVE}" -DPLUGIN_DIR="${PLUGIN_DIR_RELATIVE}" ${PULSEAUDIO_DEFINITIONS} ${PORTAUDIO_DEFINITIONS}) INCLUDE_DIRECTORIES( ${JACK_INCLUDE_DIRS} ${SAMPLERATE_INCLUDE_DIRS} ${SNDFILE_INCLUDE_DIRS} ${SNDIO_INCLUDE_DIRS} + ${FFTW3F_INCLUDE_DIRS} ) IF(NOT ("${SDL2_INCLUDE_DIR}" STREQUAL "")) @@ -189,97 +190,208 @@ IF(LMMS_BUILD_MSYS AND CMAKE_BUILD_TYPE STREQUAL "Debug") ENDIF() # Install -IF(LMMS_BUILD_WIN32) - SET_TARGET_PROPERTIES(lmms PROPERTIES - LINK_FLAGS "${LINK_FLAGS} -mwindows" - ENABLE_EXPORTS ON - ) - - IF(LMMS_BUILD_MSYS) - # ENABLE_EXPORTS property has no effect in some MSYS2 configurations. - # Add the linker flag manually to create liblmms.dll.a import library - SET_PROPERTY(TARGET lmms - APPEND_STRING PROPERTY LINK_FLAGS -Wl,--out-implib,liblmms.dll.a +IF(NOT MSVC) + IF(LMMS_BUILD_WIN32) + SET_TARGET_PROPERTIES(lmms PROPERTIES + LINK_FLAGS "${LINK_FLAGS} -mwindows" + ENABLE_EXPORTS ON ) - ENDIF() - IF(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") - ADD_CUSTOM_COMMAND(TARGET lmms POST_BUILD COMMAND "${STRIP}" "$") - ENDIF() + IF(LMMS_BUILD_MSYS) + # ENABLE_EXPORTS property has no effect in some MSYS2 configurations. + # Add the linker flag manually to create liblmms.dll.a import library + SET_PROPERTY(TARGET lmms + APPEND_STRING PROPERTY LINK_FLAGS -Wl,--out-implib,liblmms.dll.a + ) + ENDIF() - INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") + IF(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + ADD_CUSTOM_COMMAND(TARGET lmms POST_BUILD COMMAND "${STRIP}" "$") + ENDIF() - INSTALL(FILES - "${MINGW_PREFIX}/bin/Qt5Core.dll" - "${MINGW_PREFIX}/bin/Qt5Gui.dll" - "${MINGW_PREFIX}/bin/Qt5Widgets.dll" - "${MINGW_PREFIX}/bin/Qt5Xml.dll" - DESTINATION .) - INSTALL(FILES - "${MINGW_PREFIX}/lib/qt5/plugins/platforms/qwindows.dll" - DESTINATION ./platforms) - INSTALL(FILES - "${MINGW_PREFIX}/bin/libsamplerate-0.dll" - "${MINGW_PREFIX}/bin/libsndfile-1.dll" - "${MINGW_PREFIX}/bin/libvorbis-0.dll" - "${MINGW_PREFIX}/bin/libvorbisenc-2.dll" - "${MINGW_PREFIX}/bin/libvorbisfile-3.dll" - "${MINGW_PREFIX}/bin/libjpeg-9.dll" - "${MINGW_PREFIX}/bin/libogg-0.dll" - "${MINGW_PREFIX}/bin/libmp3lame-0.dll" - "${MINGW_PREFIX}/bin/libfftw3f-3.dll" - "${MINGW_PREFIX}/bin/libFLAC-8.dll" - "${MINGW_PREFIX}/bin/libpng16-16.dll" - "${MINGW_PREFIX}/bin/SDL.dll" - "${MINGW_PREFIX}/bin/libglib-2.0-0.dll" - "${MINGW_PREFIX}/bin/libgthread-2.0-0.dll" - "${MINGW_PREFIX}/bin/zlib1.dll" - "${MINGW_PREFIX}/${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32/bin/libwinpthread-1.dll" - DESTINATION .) - IF(LMMS_BUILD_MSYS) + INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") INSTALL(FILES - "${MINGW_PREFIX}/bin/libwinpthread-1.dll" - "${MINGW_PREFIX}/bin/libgcc_s_seh-1.dll" - "${MINGW_PREFIX}/bin/libstdc++-6.dll" + "${MINGW_PREFIX}/bin/Qt5Core.dll" + "${MINGW_PREFIX}/bin/Qt5Gui.dll" + "${MINGW_PREFIX}/bin/Qt5Widgets.dll" + "${MINGW_PREFIX}/bin/Qt5Xml.dll" DESTINATION .) - ELSE() INSTALL(FILES - "${MINGW_PREFIX}/${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32/bin/libwinpthread-1.dll" - DESTINATION .) - ENDIF() - IF(FLTK_FOUND) + "${MINGW_PREFIX}/lib/qt5/plugins/platforms/qwindows.dll" + DESTINATION ./platforms) INSTALL(FILES - "${MINGW_PREFIX}/bin/libfltk.dll" - DESTINATION .) - ENDIF() - IF(FLUIDSYNTH_FOUND) - INSTALL(FILES - "${MINGW_PREFIX}/bin/libfluidsynth.dll" - DESTINATION .) - ENDIF() - IF(GIG_FOUND) - # Handle libgig-*.dll - FILE(GLOB GIG_LIBRARY "${MINGW_PREFIX}/bin/libgig-*.dll") - INSTALL(FILES - ${GIG_LIBRARY} - DESTINATION .) - ENDIF() - IF(PORTAUDIO_FOUND) - INSTALL(FILES - "${MINGW_PREFIX}/bin/libportaudio-2.dll" - DESTINATION .) - ENDIF() - IF(SOUNDIO_FOUND) - INSTALL(FILES - "${MINGW_PREFIX}/lib/libsoundio.dll" - DESTINATION .) - ENDIF() -ELSE(LMMS_BUILD_WIN32) - IF(NOT LMMS_BUILD_APPLE) - SET_TARGET_PROPERTIES(lmms PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Wl,-E") - ENDIF(NOT LMMS_BUILD_APPLE) + "${MINGW_PREFIX}/bin/libsamplerate-0.dll" + "${MINGW_PREFIX}/bin/libsndfile-1.dll" + "${MINGW_PREFIX}/bin/libvorbis-0.dll" + "${MINGW_PREFIX}/bin/libvorbisenc-2.dll" + "${MINGW_PREFIX}/bin/libvorbisfile-3.dll" + "${MINGW_PREFIX}/bin/libjpeg-9.dll" + "${MINGW_PREFIX}/bin/libogg-0.dll" + "${MINGW_PREFIX}/bin/libmp3lame-0.dll" + "${MINGW_PREFIX}/bin/libfftw3f-3.dll" + "${MINGW_PREFIX}/bin/libFLAC-8.dll" + "${MINGW_PREFIX}/bin/libpng16-16.dll" + "${MINGW_PREFIX}/bin/SDL.dll" + "${MINGW_PREFIX}/bin/libglib-2.0-0.dll" + "${MINGW_PREFIX}/bin/libgthread-2.0-0.dll" + "${MINGW_PREFIX}/bin/zlib1.dll" + "${MINGW_PREFIX}/${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32/bin/libwinpthread-1.dll" + DESTINATION .) + IF(LMMS_BUILD_MSYS) + INSTALL(FILES + "${MINGW_PREFIX}/bin/libwinpthread-1.dll" + "${MINGW_PREFIX}/bin/libgcc_s_seh-1.dll" + "${MINGW_PREFIX}/bin/libstdc++-6.dll" + DESTINATION .) + ELSE() + INSTALL(FILES + "${MINGW_PREFIX}/${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32/bin/libwinpthread-1.dll" + DESTINATION .) + ENDIF() + IF(FLTK_FOUND) + INSTALL(FILES + "${MINGW_PREFIX}/bin/libfltk.dll" + DESTINATION .) + ENDIF() + IF(FLUIDSYNTH_FOUND) + INSTALL(FILES + "${MINGW_PREFIX}/bin/libfluidsynth.dll" + DESTINATION .) + ENDIF() + IF(GIG_FOUND) + # Handle libgig-*.dll + FILE(GLOB GIG_LIBRARY "${MINGW_PREFIX}/bin/libgig-*.dll") + INSTALL(FILES + ${GIG_LIBRARY} + DESTINATION .) + ENDIF() + IF(PORTAUDIO_FOUND) + INSTALL(FILES + "${MINGW_PREFIX}/bin/libportaudio-2.dll" + DESTINATION .) + ENDIF() + IF(SOUNDIO_FOUND) + INSTALL(FILES + "${MINGW_PREFIX}/lib/libsoundio.dll" + DESTINATION .) + ENDIF() - INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") - INSTALL(FILES "${CMAKE_BINARY_DIR}/lmms.1.gz" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/man/man1/" PERMISSIONS OWNER_READ GROUP_READ WORLD_READ) + ELSE(LMMS_BUILD_WIN32) + IF(NOT LMMS_BUILD_APPLE) + SET_TARGET_PROPERTIES(lmms PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Wl,-E") + ENDIF(NOT LMMS_BUILD_APPLE) -ENDIF(LMMS_BUILD_WIN32) + INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") + INSTALL(FILES "${CMAKE_BINARY_DIR}/lmms.1.gz" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/man/man1/" PERMISSIONS OWNER_READ GROUP_READ WORLD_READ) + + ENDIF(LMMS_BUILD_WIN32) +ELSE(NOT MSVC) + SET_TARGET_PROPERTIES(lmms PROPERTIES + ENABLE_EXPORTS ON + ) + INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") + + SET_TARGET_PROPERTIES(lmms PROPERTIES + LINK_FLAGS "${LINK_FLAGS} -mwindows" + ENABLE_EXPORTS ON + ) + + #CMAKE_FIND_ROOT_PATH + SET(VCPKG_ROOT ${CMAKE_FIND_ROOT_PATH}) + + INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") + + INSTALL(FILES + "${VCPKG_ROOT}/bin/Qt5Core.dll" + "${VCPKG_ROOT}/bin/Qt5Gui.dll" + "${VCPKG_ROOT}/bin/Qt5Widgets.dll" + "${VCPKG_ROOT}/bin/Qt5Xml.dll" + + "${VCPKG_ROOT}/bin/zlib1.dll" + "${VCPKG_ROOT}/bin/jpeg62.dll" + "${VCPKG_ROOT}/bin/libpng16.dll" + "${VCPKG_ROOT}/bin/gthread-2.dll" + "${VCPKG_ROOT}/bin/glib-2.dll" + "${VCPKG_ROOT}/bin/harfbuzz.dll" + "${VCPKG_ROOT}/bin/pcre2-16.dll" + "${VCPKG_ROOT}/bin/double-conversion.dll" + "${VCPKG_ROOT}/bin/freetype.dll" + "${VCPKG_ROOT}/bin/libbz2.dll" + "${VCPKG_ROOT}/bin/pcre.dll" + "${VCPKG_ROOT}/bin/libiconv.dll" + "${VCPKG_ROOT}/bin/libcharset.dll" + "${VCPKG_ROOT}/bin/libintl.dll" + DESTINATION .) + + INSTALL(FILES + "${VCPKG_ROOT}/plugins/platforms/qwindows.dll" + DESTINATION ./platforms) + + INSTALL(FILES + "${VCPKG_ROOT}/bin/libsndfile-1.dll" + "${VCPKG_ROOT}/bin/ogg.dll" + "${VCPKG_ROOT}/bin/vorbis.dll" + "${VCPKG_ROOT}/bin/vorbisenc.dll" + "${VCPKG_ROOT}/bin/FLAC.dll" + "${VCPKG_ROOT}/bin/vorbisfile.dll" + + "${VCPKG_ROOT}/bin/libsamplerate-0.dll" + "${VCPKG_ROOT}/bin/SDL2.dll" + "${VCPKG_ROOT}/bin/fftw3f.dll" + DESTINATION .) + + #not yet in vcpkg + #IF(LAME_FOUND) + # INSTALL(FILES + # "${VCPKG_ROOT}/bin/libmp3lame-0.dll" + # DESTINATION .) + #ENDIF(LAME_FOUND) + + IF(FLTK_FOUND) + INSTALL(FILES + "${VCPKG_ROOT}/bin/libfltk_SHARED.dll" + + "${VCPKG_ROOT}/bin/zlib1.dll" + "${VCPKG_ROOT}/bin/jpeg62.dll" + DESTINATION .) + ENDIF() + + IF(FLUIDSYNTH_FOUND) + INSTALL(FILES + "${VCPKG_ROOT}/bin/libfluidsynth-1.dll" + "${VCPKG_ROOT}/bin/glib-2.dll" + "${VCPKG_ROOT}/bin/pcre.dll" + "${VCPKG_ROOT}/bin/libiconv.dll" + "${VCPKG_ROOT}/bin/libcharset.dll" + "${VCPKG_ROOT}/bin/libintl.dll" + DESTINATION .) + ENDIF() + + #not yet included in vcpkg + #IF(GIG_FOUND) + # # Handle libgig-*.dll + # FILE(GLOB GIG_LIBRARY "${VCPKG_ROOT}/bin/libgig-*.dll") + # INSTALL(FILES + # ${GIG_LIBRARY} + # DESTINATION .) + #ENDIF() + + IF(PORTAUDIO_FOUND) + IF(LMMS_BUILD_WIN64) + INSTALL(FILES + "${VCPKG_ROOT}/bin/portaudio-x64.dll" + DESTINATION .) + ELSE(LMMS_BUILD_WIN64) + INSTALL(FILES + "${VCPKG_ROOT}/bin/portaudio-x86.dll" + DESTINATION .) + ENDIF(LMMS_BUILD_WIN64) + ENDIF() + + #not yet in vcpkg + #IF(SOUNDIO_FOUND) + # INSTALL(FILES + # "${VCPKG_ROOT}/bin/libsoundio.dll" + # DESTINATION .) + #ENDIF() +ENDIF(NOT MSVC) \ No newline at end of file From fe2483e309d550d6bbd1b935734965e1025bf6ad Mon Sep 17 00:00:00 2001 From: Lukas W Date: Thu, 7 Jun 2018 11:07:40 +0200 Subject: [PATCH 061/445] Enable 64bit VSTs on Linux * Remove trial-and-error approach of detecting VST's machine types. Read PE headers instead. * Add RemoteVstPlugin64 to AppImage --- cmake/linux/package_linux.sh.in | 14 +++-- include/RemotePlugin.h | 3 +- plugins/vst_base/RemoteVstPlugin.cpp | 5 -- plugins/vst_base/VstPlugin.cpp | 83 +++++++++++++++++++++++----- plugins/vst_base/VstPlugin.h | 2 - plugins/vst_base/communication.h | 1 - src/core/RemotePlugin.cpp | 6 +- 7 files changed, 82 insertions(+), 32 deletions(-) diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index 16866e4d4..907c7a999 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -126,7 +126,7 @@ EOL chmod +x "${APPDIR}usr/bin/lmms" -# Per https://github.com/probonopd/linuxdeployqt/issues/129 +# Per https://github.com/probonopd/linuxdeployqt/issues/129 unset LD_LIBRARY_PATH # Ensure linuxdeployqt can find shared objects @@ -139,13 +139,16 @@ fi # Move executables so linuxdeployqt can find them ZYNLIB="${APPDIR}usr/lib/lmms/RemoteZynAddSubFx" -VSTLIB="${APPDIR}usr/lib/lmms/RemoteVstPlugin32.exe.so" +VSTLIB32="${APPDIR}usr/lib/lmms/RemoteVstPlugin32.exe.so" +VSTLIB64="${APPDIR}usr/lib/lmms/RemoteVstPlugin64.exe.so" ZYNBIN="${APPDIR}usr/bin/RemoteZynAddSubFx" -VSTBIN="${APPDIR}usr/bin/RemoteVstPlugin32.exe.so" +VSTBIN32="${APPDIR}usr/bin/RemoteVstPlugin32.exe.so" +VSTBIN64="${APPDIR}usr/bin/RemoteVstPlugin64.exe.so" mv "$ZYNLIB" "$ZYNBIN" -mv "$VSTLIB" "$VSTBIN" +mv "$VSTLIB32" "$VSTBIN32" +mv "$VSTLIB64" "$VSTBIN64" # Patch the desktop file sed -i 's/.*Exec=.*/Exec=lmms.real/' "$DESKTOPFILE" @@ -171,7 +174,8 @@ success "Bundled and relinked dependencies" # Link to original location so lmms can find them ln -sr "$ZYNBIN" "$ZYNLIB" -ln -sr "$VSTBIN" "$VSTLIB" +ln -sr "$VSTBIN32" "$VSTLIB32" +ln -sr "$VSTBIN64" "$VSTLIB64" # Remove wine library conflict rm -f "${APPDIR}/usr/lib/libwine.so.1" diff --git a/include/RemotePlugin.h b/include/RemotePlugin.h index 67f0c3807..57f6b379b 100644 --- a/include/RemotePlugin.h +++ b/include/RemotePlugin.h @@ -854,12 +854,11 @@ protected: } + bool m_failed; private: void resizeSharedProcessingMemory(); - bool m_failed; - QProcess m_process; ProcessWatcher m_watcher; diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index d28661357..dffc897cb 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -811,11 +811,6 @@ bool RemoteVstPlugin::load( const std::string & _plugin_file ) { DWORD error = GetLastError(); debugMessage( "LoadLibrary failed: " + GetErrorAsString(error) ); - // give VstPlugin class a chance to start 32 bit version of RemoteVstPlugin - if( GetLastError() == ERROR_BAD_EXE_FORMAT ) - { - sendMessage( IdVstBadDllFormat ); - } return false; } diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 6096a0d49..95fcfced1 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -26,6 +26,7 @@ #include "communication.h" +#include #include #include #include @@ -68,6 +69,54 @@ # include #endif +namespace PE +{ +// Utilities for reading PE file machine type +// See specification at https://msdn.microsoft.com/library/windows/desktop/ms680547(v=vs.85).aspx + +enum MachineType : uint16_t +{ + IMAGE_FILE_MACHINE_UNKNOWN = 0x0, + IMAGE_FILE_MACHINE_AMD64 = 0x8664, + IMAGE_FILE_MACHINE_I386 = 0x14c, +}; + +class FileInfo +{ +public: + FileInfo(QString filePath) + : m_file(filePath) + { + m_file.open(QFile::ReadOnly); + m_map = m_file.map(0, m_file.size()); + if (m_map == nullptr) { + throw std::runtime_error("Cannot map file"); + } + } + ~FileInfo() + { + m_file.unmap(m_map); + } + + MachineType machineType() + { + int32_t peOffset = qFromLittleEndian(* reinterpret_cast(m_map + 0x3C)); + uchar* peSignature = m_map + peOffset; + if (memcmp(peSignature, "PE\0\0", 4)) { + throw std::runtime_error("Invalid PE file"); + } + uchar * coffHeader = peSignature + 4; + uint16_t machineType = qFromLittleEndian(* reinterpret_cast(coffHeader)); + return static_cast(machineType); + } + +private: + QFile m_file; + uchar* m_map; +}; + +} + VstPlugin::VstPlugin( const QString & _plugin ) : m_plugin( _plugin ), @@ -75,22 +124,32 @@ VstPlugin::VstPlugin( const QString & _plugin ) : m_embedMethod( gui ? ConfigManager::inst()->vstEmbedMethod() : "headless" ), - m_badDllFormat( false ), m_version( 0 ), m_currentProgram() { setSplittedChannels( true ); -#ifdef LMMS_BUILD_WIN64 - tryLoad( "RemoteVstPlugin64" ); - if( m_badDllFormat ) - { - m_badDllFormat = false; -#endif - tryLoad( "RemoteVstPlugin32" ); -#ifdef LMMS_BUILD_WIN64 + PE::MachineType machineType; + try { + PE::FileInfo peInfo(_plugin); + machineType = peInfo.machineType(); + } catch (std::runtime_error& e) { + qCritical() << "Error while determining PE file's machine type: " << e.what(); + machineType = PE::IMAGE_FILE_MACHINE_UNKNOWN; + } + + switch(machineType) + { + case PE::IMAGE_FILE_MACHINE_AMD64: + tryLoad( "RemoteVstPlugin64" ); + break; + case PE::IMAGE_FILE_MACHINE_I386: + tryLoad( "RemoteVstPlugin32" ); + break; + default: + m_failed = true; + return; } -#endif setTempo( Engine::getSong()->getTempo() ); @@ -326,10 +385,6 @@ bool VstPlugin::processMessage( const message & _m ) { switch( _m.id ) { - case IdVstBadDllFormat: - m_badDllFormat = true; - break; - case IdVstPluginWindowID: m_pluginWindowID = _m.getInt(); if( m_embedMethod == "none" ) diff --git a/plugins/vst_base/VstPlugin.h b/plugins/vst_base/VstPlugin.h index 6ef325497..5b459d40d 100644 --- a/plugins/vst_base/VstPlugin.h +++ b/plugins/vst_base/VstPlugin.h @@ -142,8 +142,6 @@ private: QSize m_pluginGeometry; const QString m_embedMethod; - bool m_badDllFormat; - QString m_name; int m_version; QString m_vendorString; diff --git a/plugins/vst_base/communication.h b/plugins/vst_base/communication.h index cfe136627..756fd7557 100644 --- a/plugins/vst_base/communication.h +++ b/plugins/vst_base/communication.h @@ -70,7 +70,6 @@ enum VstRemoteMessageIDs // remoteVstPlugin -> vstPlugin IdVstFailedLoadingPlugin, - IdVstBadDllFormat, IdVstPluginWindowID, IdVstPluginEditorGeometry, IdVstPluginName, diff --git a/src/core/RemotePlugin.cpp b/src/core/RemotePlugin.cpp index 408b8631f..c00d26be9 100644 --- a/src/core/RemotePlugin.cpp +++ b/src/core/RemotePlugin.cpp @@ -63,7 +63,10 @@ void ProcessWatcher::run() { fprintf( stderr, "remote plugin died! invalidating now.\n" ); + +#ifndef SYNC_WITH_SHM_FIFO m_plugin->invalidate(); +#endif } } @@ -464,9 +467,6 @@ void RemotePlugin::processFinished( int exitCode, { qCritical() << "Remote plugin exit code: " << exitCode; } -#ifndef SYNC_WITH_SHM_FIFO - invalidate(); -#endif } void RemotePlugin::processErrored( QProcess::ProcessError err ) From 81651525524c2532123295d07bbaf62047c10828 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Mon, 11 Jun 2018 14:15:07 +0200 Subject: [PATCH 062/445] MSVC VST compilation fixes --- CMakeLists.txt | 30 +++++------ plugins/vst_base/CMakeLists.txt | 65 +---------------------- plugins/vst_base/RemoteVstPlugin32.cmake | 67 ++++++++++++++++++++++++ plugins/vst_base/RemoteVstPlugin64.cmake | 13 +++++ plugins/vst_base/VstPlugin.cpp | 14 ++--- 5 files changed, 102 insertions(+), 87 deletions(-) create mode 100644 plugins/vst_base/RemoteVstPlugin32.cmake create mode 100644 plugins/vst_base/RemoteVstPlugin64.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 492601769..026b034ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,10 +47,6 @@ ENDIF() INCLUDE(VersionInfo) INCLUDE(DetectMachine) -IF(CMAKE_TOOLCHAIN_FILE MATCHES "vcpkg.cmake$") - SET(USING_VCPKG TRUE) -ENDIF() - OPTION(WANT_ALSA "Include ALSA (Advanced Linux Sound Architecture) support" ON) OPTION(WANT_CALF "Include CALF LADSPA plugins" ON) OPTION(WANT_CAPS "Include C* Audio Plugin Suite (LADSPA plugins)" ON) @@ -169,15 +165,15 @@ FIND_PACKAGE(Qt5Test) SET(QT_QTTEST_LIBRARY Qt5::Test) # check for libsndfile -IF(USING_VCPKG) - FIND_PACKAGE(LibSndFile 1.0.18 REQUIRED) - SET(SNDFILE_LIBRARIES sndfile-shared) -ELSE(USING_VCPKG) +IF(PKG_CONFIG_FOUND) PKG_CHECK_MODULES(SNDFILE REQUIRED sndfile>=1.0.18) IF(NOT SNDFILE_FOUND) MESSAGE(FATAL_ERROR "LMMS requires libsndfile1 and libsndfile1-dev >= 1.0.18 - please install, remove CMakeCache.txt and try again!") ENDIF() -ENDIF(USING_VCPKG) +ELSE() + FIND_PACKAGE(LibSndFile 1.0.18 REQUIRED) + SET(SNDFILE_LIBRARIES sndfile-shared) +ENDIF() # check if we can use SF_SET_COMPRESSION_LEVEL IF(NOT SNDFILE_VERSION VERSION_LESS 1.0.26) SET(LMMS_HAVE_SF_COMPLEVEL TRUE) @@ -402,13 +398,13 @@ ENDIF(WANT_JACK) # check for FFTW3F-library -IF(USING_VCPKG) +IF(PKG_CONFIG_FOUND) + PKG_CHECK_MODULES(FFTW3F REQUIRED fftw3f>=3.0.0) +ELSE() #currently find_package for fftw is broken in vcpkg. Replace this when fixed FIND_PATH(FFTW3F_INCLUDE_DIRS fftw3.h) FIND_LIBRARY(FFTW3F_LIBRARIES fftw3f) -ELSE(USING_VCPKG) - PKG_CHECK_MODULES(FFTW3F REQUIRED fftw3f>=3.0.0) -ENDIF(USING_VCPKG) +ENDIF() # check for FLTK FIND_PACKAGE(FLTK) @@ -490,13 +486,13 @@ ELSE() ENDIF(WANT_DEBUG_FPE) # check for libsamplerate -IF(USING_VCPKG) +IF(PKG_CONFIG_FOUND) + PKG_CHECK_MODULES(SAMPLERATE REQUIRED samplerate>=0.1.8) +ELSE() #TODO no cmake config support. Can we check the version some other way? FIND_FILE(SAMPLERATE_INCLUDE_DIRS samplerate.h) FIND_LIBRARY(SAMPLERATE_LIBRARIES libsamplerate-0) -ELSE(USING_VCPKG) - PKG_CHECK_MODULES(SAMPLERATE REQUIRED samplerate>=0.1.8) -ENDIF(USING_VCPKG) +ENDIF() # set compiler flags IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") diff --git a/plugins/vst_base/CMakeLists.txt b/plugins/vst_base/CMakeLists.txt index 42b5930b7..314d5fc18 100644 --- a/plugins/vst_base/CMakeLists.txt +++ b/plugins/vst_base/CMakeLists.txt @@ -29,67 +29,6 @@ SET(EXTERNALPROJECT_CMAKE_ARGS ) # build 32 bit version of RemoteVstPlugin -IF(LMMS_BUILD_WIN32 AND NOT LMMS_BUILD_WIN64) - ADD_SUBDIRECTORY(RemoteVstPlugin) -ELSEIF(LMMS_BUILD_WIN64 AND MSVC) - STRING(REPLACE " Win64" "" GENERATOR ${CMAKE_GENERATOR}) - - IF(NOT USING_VCPKG) - GET_FILENAME_COMPONENT(QT_BIN_DIR ${QT_QMAKE_EXECUTABLE} DIRECTORY) - SET(QT_32_PREFIX "${QT_BIN_DIR}/../../msvc${MSVC_YEAR}") - IF(NOT (IS_DIRECTORY ${QT_32_PREFIX} AND EXISTS ${QT_32_PREFIX}/bin/qmake.exe)) - MESSAGE(SEND_ERROR "Can't build RemoteVstPlugin32, no Qt 32 bit installation found at ${QT_32_PREFIX}") - ENDIF() - ENDIF(NOT USING_VCPKG) - - ExternalProject_Add(RemoteVstPlugin32 - "${EXTERNALPROJECT_ARGS}" - CMAKE_GENERATOR ${GENERATOR} - CMAKE_GENERATOR_TOOLSET ${CMAKE_GENERATOR_TOOLSET} - CMAKE_ARGS - "${EXTERNALPROJECT_CMAKE_ARGS}" - "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" - "-DCMAKE_PREFIX_PATH=${QT_32_PREFIX}" - ) -ELSEIF(LMMS_BUILD_LINUX) - # Use winegcc - ExternalProject_Add(RemoteVstPlugin32 - "${EXTERNALPROJECT_ARGS}" - CMAKE_ARGS - "${EXTERNALPROJECT_CMAKE_ARGS}" - "-DCMAKE_CXX_COMPILER=${WINEGCC}" - "-DCMAKE_CXX_FLAGS=-m32 -mwindows" - ) -ELSEIF(CMAKE_TOOLCHAIN_FILE_32) - ExternalProject_Add(RemoteVstPlugin32 - "${EXTERNALPROJECT_ARGS}" - CMAKE_ARGS - "${EXTERNALPROJECT_CMAKE_ARGS}" - "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH_32}" - "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE_32}" - ) -ELSE() - message(SEND_ERROR "Can't build RemoteVstPlugin32, unknown environment. Please supply CMAKE_TOOLCHAIN_FILE_32 and optionally CMAKE_PREFIX_PATH_32") -ENDIF() - +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin32.cmake") # build 64 bit version of RemoteVstPlugin -IF(LMMS_BUILD_WIN64) - ADD_SUBDIRECTORY(RemoteVstPlugin) - INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin64.exe" DESTINATION "${PLUGIN_DIR}") -ELSEIF(LMMS_BUILD_LINUX) - ExternalProject_Add(RemoteVstPlugin64 - "${EXTERNALPROJECT_ARGS}" - CMAKE_ARGS - "${EXTERNALPROJECT_CMAKE_ARGS}" - "-DCMAKE_CXX_COMPILER=${WINEGCC}" - "-DCMAKE_CXX_FLAGS=-m64 -mwindows" - ) -ENDIF() - -IF(TARGET RemoteVstPlugin32) - 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() -ENDIF() \ No newline at end of file +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin64.cmake") diff --git a/plugins/vst_base/RemoteVstPlugin32.cmake b/plugins/vst_base/RemoteVstPlugin32.cmake new file mode 100644 index 000000000..a74c5b1f8 --- /dev/null +++ b/plugins/vst_base/RemoteVstPlugin32.cmake @@ -0,0 +1,67 @@ +IF(LMMS_BUILD_WIN32 AND NOT LMMS_BUILD_WIN64) + ADD_SUBDIRECTORY(RemoteVstPlugin) +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) + SET(CMAKE_GENERATOR_32 "Visual Studio 15 2017") + SET(MSVC_YEAR 2017) + 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) + 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() + ENDIF() + + ExternalProject_Add(RemoteVstPlugin32 + "${EXTERNALPROJECT_ARGS}" + CMAKE_GENERATOR "${CMAKE_GENERATOR_32}" + #CMAKE_GENERATOR_TOOLSET "${CMAKE_GENERATOR_TOOLSET}" + CMAKE_ARGS + "${EXTERNALPROJECT_CMAKE_ARGS}" + "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" + "-DCMAKE_PREFIX_PATH=${QT_32_PREFIX}" + ) +ELSEIF(LMMS_BUILD_LINUX) + # Use winegcc + ExternalProject_Add(RemoteVstPlugin32 + "${EXTERNALPROJECT_ARGS}" + CMAKE_ARGS + "${EXTERNALPROJECT_CMAKE_ARGS}" + "-DCMAKE_CXX_COMPILER=${WINEGCC}" + "-DCMAKE_CXX_FLAGS=-m32 -mwindows" + ) +ELSEIF(CMAKE_TOOLCHAIN_FILE_32) + ExternalProject_Add(RemoteVstPlugin32 + "${EXTERNALPROJECT_ARGS}" + CMAKE_ARGS + "${EXTERNALPROJECT_CMAKE_ARGS}" + "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH_32}" + "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE_32}" + ) +ELSE() + 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/RemoteVstPlugin64.cmake b/plugins/vst_base/RemoteVstPlugin64.cmake new file mode 100644 index 000000000..3922ce171 --- /dev/null +++ b/plugins/vst_base/RemoteVstPlugin64.cmake @@ -0,0 +1,13 @@ +IF(LMMS_BUILD_WIN64) + ADD_SUBDIRECTORY(RemoteVstPlugin) + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin64.exe" DESTINATION "${PLUGIN_DIR}") +ELSEIF(LMMS_BUILD_LINUX) + ExternalProject_Add(RemoteVstPlugin64 + "${EXTERNALPROJECT_ARGS}" + CMAKE_ARGS + "${EXTERNALPROJECT_CMAKE_ARGS}" + "-DCMAKE_CXX_COMPILER=${WINEGCC}" + "-DCMAKE_CXX_FLAGS=-m64 -mwindows" + ) + INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin64" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin64.exe.so" DESTINATION "${PLUGIN_DIR}") +ENDIF() diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 95fcfced1..b14efcb5e 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -74,11 +74,11 @@ namespace PE // Utilities for reading PE file machine type // See specification at https://msdn.microsoft.com/library/windows/desktop/ms680547(v=vs.85).aspx -enum MachineType : uint16_t +enum class MachineType : uint16_t { - IMAGE_FILE_MACHINE_UNKNOWN = 0x0, - IMAGE_FILE_MACHINE_AMD64 = 0x8664, - IMAGE_FILE_MACHINE_I386 = 0x14c, + unknown = 0x0, + amd64 = 0x8664, + i386 = 0x14c, }; class FileInfo @@ -135,15 +135,15 @@ VstPlugin::VstPlugin( const QString & _plugin ) : machineType = peInfo.machineType(); } catch (std::runtime_error& e) { qCritical() << "Error while determining PE file's machine type: " << e.what(); - machineType = PE::IMAGE_FILE_MACHINE_UNKNOWN; + machineType = PE::MachineType::unknown; } switch(machineType) { - case PE::IMAGE_FILE_MACHINE_AMD64: + case PE::MachineType::amd64: tryLoad( "RemoteVstPlugin64" ); break; - case PE::IMAGE_FILE_MACHINE_I386: + case PE::MachineType::i386: tryLoad( "RemoteVstPlugin32" ); break; default: From ec28a65c890b995c66e3f1f591bc4a9a66774f57 Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Tue, 7 Nov 2017 12:59:49 +0200 Subject: [PATCH 063/445] AudioSdl: Add support for full SDL2 with float samples and recording (with backward compatibility for SDL1). Cherry-picked from dcc442411fd66328a971969f37cadcc142206865 --- include/AudioSdl.h | 20 +++++- src/core/audio/AudioSdl.cpp | 137 +++++++++++++++++++++++++++++++++--- 2 files changed, 148 insertions(+), 9 deletions(-) diff --git a/include/AudioSdl.h b/include/AudioSdl.h index 11942efda..19d9606eb 100644 --- a/include/AudioSdl.h +++ b/include/AudioSdl.h @@ -78,17 +78,35 @@ private: static void sdlAudioCallback( void * _udata, Uint8 * _buf, int _len ); void sdlAudioCallback( Uint8 * _buf, int _len ); +#ifdef LMMS_HAVE_SDL2 + static void sdlInputAudioCallback( void * _udata, Uint8 * _buf, int _len ); + void sdlInputAudioCallback( Uint8 * _buf, int _len ); +#endif + SDL_AudioSpec m_audioHandle; surroundSampleFrame * m_outBuf; + +#ifdef LMMS_HAVE_SDL2 + uint64_t m_currentBufferFramePos; + uint64_t m_currentBufferFramesCount; +#else Uint8 * m_convertedBuf; int m_convertedBufPos; int m_convertedBufSize; + bool m_outConvertEndian; +#endif - bool m_convertEndian; bool m_stopped; +#ifdef LMMS_HAVE_SDL2 + SDL_AudioDeviceID m_outputDevice; + + SDL_AudioSpec m_inputAudioHandle; + SDL_AudioDeviceID m_inputDevice; +#endif + } ; #endif diff --git a/src/core/audio/AudioSdl.cpp b/src/core/audio/AudioSdl.cpp index 2b810e913..41a8249ee 100644 --- a/src/core/audio/AudioSdl.cpp +++ b/src/core/audio/AudioSdl.cpp @@ -34,19 +34,21 @@ #include "gui_templates.h" #include "Mixer.h" - AudioSdl::AudioSdl( bool & _success_ful, Mixer* _mixer ) : AudioDevice( DEFAULT_CHANNELS, _mixer ), - m_outBuf( new surroundSampleFrame[mixer()->framesPerPeriod()] ), - m_convertedBufPos( 0 ), - m_convertEndian( false ) + m_outBuf( new surroundSampleFrame[mixer()->framesPerPeriod()] ) { _success_ful = false; +#ifdef LMMS_HAVE_SDL2 + m_currentBufferFramesCount = 0; + m_currentBufferFramePos = 0; +#else m_convertedBufSize = mixer()->framesPerPeriod() * channels() * sizeof( int_sample_t ); + m_convertedBufPos = 0; m_convertedBuf = new Uint8[m_convertedBufSize]; - +#endif if( SDL_Init( SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE ) < 0 ) { @@ -55,9 +57,15 @@ AudioSdl::AudioSdl( bool & _success_ful, Mixer* _mixer ) : } m_audioHandle.freq = sampleRate(); +#ifdef LMMS_HAVE_SDL2 + m_audioHandle.format = AUDIO_F32SYS; // we want it in byte-order + // of system, so we don't have + // to convert the buffers +#else m_audioHandle.format = AUDIO_S16SYS; // we want it in byte-order // of system, so we don't have // to convert the buffers +#endif m_audioHandle.channels = channels(); m_audioHandle.samples = qMax( 1024, mixer()->framesPerPeriod()*2 ); @@ -66,15 +74,47 @@ AudioSdl::AudioSdl( bool & _success_ful, Mixer* _mixer ) : SDL_AudioSpec actual; +#ifdef LMMS_HAVE_SDL2 + m_outputDevice = SDL_OpenAudioDevice (SDL_GetAudioDeviceName(0, 2), + 0, + &m_audioHandle, + &actual, + 0); + if (m_outputDevice == 0) { + qCritical( "Couldn't open SDL-audio: %s\n", SDL_GetError() ); + return; + } +#else // open the audio device, forcing the desired format if( SDL_OpenAudio( &m_audioHandle, &actual ) < 0 ) { qCritical( "Couldn't open SDL-audio: %s\n", SDL_GetError() ); return; } - m_convertEndian = ( m_audioHandle.format != actual.format ); + + m_outConvertEndian = ( m_audioHandle.format != actual.format ); +#endif + _success_ful = true; + +#ifdef LMMS_HAVE_SDL2 + m_inputAudioHandle = m_audioHandle; + m_inputAudioHandle.callback = sdlInputAudioCallback; + + m_inputDevice = SDL_OpenAudioDevice (SDL_GetAudioDeviceName(0, 1), + 1, + &m_inputAudioHandle, + &actual, + 0); + if (m_inputDevice != 0) { + m_supportsCapture = true; + } else { + m_supportsCapture = false; + qWarning ( "Couldn't open SDL capture device: %s\n", SDL_GetError ()); + } + +#endif } @@ -84,9 +124,18 @@ AudioSdl::~AudioSdl() { stopProcessing(); +#ifdef LMMS_HAVE_SDL2 + if (m_inputDevice != 0) + SDL_CloseAudioDevice(m_inputDevice); + if (m_outputDevice != 0) + SDL_CloseAudioDevice(m_outputDevice); +#else SDL_CloseAudio(); - SDL_Quit(); delete[] m_convertedBuf; +#endif + + SDL_Quit(); + delete[] m_outBuf; } @@ -97,7 +146,12 @@ void AudioSdl::startProcessing() { m_stopped = false; +#ifdef LMMS_HAVE_SDL2 + SDL_PauseAudioDevice (m_outputDevice, 0); + SDL_PauseAudioDevice (m_inputDevice, 0); +#else SDL_PauseAudio( 0 ); +#endif } @@ -107,10 +161,24 @@ void AudioSdl::stopProcessing() { if( SDL_GetAudioStatus() == SDL_AUDIO_PLAYING ) { +#ifdef LMMS_HAVE_SDL2 + SDL_LockAudioDevice (m_inputDevice); + SDL_LockAudioDevice (m_outputDevice); + + m_stopped = true; + + SDL_PauseAudioDevice (m_inputDevice, 1); + SDL_PauseAudioDevice (m_outputDevice, 1); + + SDL_UnlockAudioDevice (m_inputDevice); + SDL_UnlockAudioDevice (m_outputDevice); +#else SDL_LockAudio(); m_stopped = true; SDL_PauseAudio( 1 ); SDL_UnlockAudio(); +#endif + } } @@ -119,6 +187,8 @@ void AudioSdl::stopProcessing() void AudioSdl::applyQualitySettings() { + // Better than if (0) +#if 0 if( 0 )//hqAudio() ) { SDL_CloseAudio(); @@ -135,6 +205,7 @@ void AudioSdl::applyQualitySettings() qCritical( "Couldn't open SDL-audio: %s\n", SDL_GetError() ); } } +#endif AudioDevice::applyQualitySettings(); } @@ -160,6 +231,41 @@ void AudioSdl::sdlAudioCallback( Uint8 * _buf, int _len ) return; } + // SDL2: process float samples +#ifdef LMMS_HAVE_SDL2 + while( _len ) + { + if( m_currentBufferFramePos == 0 ) + { + // frames depend on the sample rate + const fpp_t frames = getNextBuffer( m_outBuf ); + if( !frames ) + { + memset( _buf, 0, _len ); + return; + } + m_currentBufferFramesCount = frames; + + } + const uint min_frames_count = qMin( _len/sizeof(sampleFrame), + m_currentBufferFramesCount + - m_currentBufferFramePos ); + + const float gain = mixer()->masterGain(); + for (uint f = 0; f < min_frames_count; f++) + { + (m_outBuf + m_currentBufferFramePos)[f][0] *= gain; + (m_outBuf + m_currentBufferFramePos)[f][1] *= gain; + } + + memcpy( _buf, m_outBuf + m_currentBufferFramePos, min_frames_count*sizeof(sampleFrame) ); + _buf += min_frames_count*sizeof(sampleFrame); + _len -= min_frames_count*sizeof(sampleFrame); + m_currentBufferFramePos += min_frames_count; + + m_currentBufferFramePos %= m_currentBufferFramesCount; + } +#else while( _len ) { if( m_convertedBufPos == 0 ) @@ -177,7 +283,7 @@ void AudioSdl::sdlAudioCallback( Uint8 * _buf, int _len ) convertToS16( m_outBuf, frames, mixer()->masterGain(), (int_sample_t *)m_convertedBuf, - m_convertEndian ); + m_outConvertEndian ); } const int min_len = qMin( _len, m_convertedBufSize - m_convertedBufPos ); @@ -187,10 +293,25 @@ void AudioSdl::sdlAudioCallback( Uint8 * _buf, int _len ) m_convertedBufPos += min_len; m_convertedBufPos %= m_convertedBufSize; } +#endif } +#ifdef LMMS_HAVE_SDL2 +void AudioSdl::sdlInputAudioCallback(void *_udata, Uint8 *_buf, int _len) { + AudioSdl * _this = static_cast( _udata ); + _this->sdlInputAudioCallback( _buf, _len ); +} + +void AudioSdl::sdlInputAudioCallback(Uint8 *_buf, int _len) { + sampleFrame *samples_buffer = (sampleFrame *) _buf; + fpp_t frames = _len / sizeof ( sampleFrame ); + + mixer()->pushInputFrames (samples_buffer, frames); +} + +#endif AudioSdl::setupWidget::setupWidget( QWidget * _parent ) : AudioDeviceSetupWidget( AudioSdl::name(), _parent ) From ff8de2d7ebd567ab4b1a7d079f53d4d7d55c3348 Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Thu, 21 Dec 2017 07:27:37 +0200 Subject: [PATCH 064/445] AudioSDL -> SDL2: Fix a crash from calling a SDL1 function instead of SDL2's. --- src/core/audio/AudioSdl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/audio/AudioSdl.cpp b/src/core/audio/AudioSdl.cpp index 41a8249ee..3e4882f90 100644 --- a/src/core/audio/AudioSdl.cpp +++ b/src/core/audio/AudioSdl.cpp @@ -159,7 +159,11 @@ void AudioSdl::startProcessing() void AudioSdl::stopProcessing() { +#ifdef LMMS_HAVE_SDL2 + if( SDL_GetAudioDeviceStatus(m_outputDevice) == SDL_AUDIO_PLAYING ) +#else if( SDL_GetAudioStatus() == SDL_AUDIO_PLAYING ) +#endif { #ifdef LMMS_HAVE_SDL2 SDL_LockAudioDevice (m_inputDevice); From e2a7587600136d7e076b0a5464beb9042e74f59c Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Mon, 11 Jun 2018 14:30:49 +0200 Subject: [PATCH 065/445] AudioSdl: Use NULL for device names in order to get the default device. The zero index device may not be the default device. Many thanks to @PhysSong. --- src/core/audio/AudioSdl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/audio/AudioSdl.cpp b/src/core/audio/AudioSdl.cpp index 3e4882f90..0dbb9dc79 100644 --- a/src/core/audio/AudioSdl.cpp +++ b/src/core/audio/AudioSdl.cpp @@ -75,7 +75,7 @@ AudioSdl::AudioSdl( bool & _success_ful, Mixer* _mixer ) : SDL_AudioSpec actual; #ifdef LMMS_HAVE_SDL2 - m_outputDevice = SDL_OpenAudioDevice (SDL_GetAudioDeviceName(0, 2), + m_outputDevice = SDL_OpenAudioDevice (NULL, 0, &m_audioHandle, &actual, @@ -102,7 +102,7 @@ AudioSdl::AudioSdl( bool & _success_ful, Mixer* _mixer ) : m_inputAudioHandle = m_audioHandle; m_inputAudioHandle.callback = sdlInputAudioCallback; - m_inputDevice = SDL_OpenAudioDevice (SDL_GetAudioDeviceName(0, 1), + m_inputDevice = SDL_OpenAudioDevice (NULL, 1, &m_inputAudioHandle, &actual, From b4d633263224589ccbda8d8840cf554ab8efa964 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Mon, 11 Jun 2018 14:58:11 +0200 Subject: [PATCH 066/445] Fix AppImage VST --- cmake/linux/package_linux.sh.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index 907c7a999..473046cdb 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -159,7 +159,8 @@ for file in "${APPDIR}usr/lib/lmms/"*.so; do executables="${executables} -executable=$thisfile" done executables="${executables} -executable=${ZYNBIN}" -executables="${executables} -executable=${VSTBIN}" +executables="${executables} -executable=${VSTBIN32}" +executables="${executables} -executable=${VSTBIN64}" executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/imp_1199.so" executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/imbeq_1197.so" executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/pitch_scale_1193.so" From ae815d3ac7be82a40d75ea1d6449bbdf9757990d Mon Sep 17 00:00:00 2001 From: Lukas W Date: Mon, 11 Jun 2018 16:59:09 +0200 Subject: [PATCH 067/445] CircleCI: Display Appimage log when failing --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4b370aed9..22da7548e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -100,7 +100,7 @@ jobs: command: | cd build make install - make appimage + make appimage || cat appimage.log cp ./lmms-*.AppImage /tmp/artifacts/ - store_artifacts: path: /tmp/artifacts/ From 38f6371de6fb4476da578cc897462e0d30708399 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Mon, 11 Jun 2018 16:59:51 +0200 Subject: [PATCH 068/445] Fix AppImage 64bit RemoteVstPlugin libwine discovery --- cmake/linux/package_linux.sh.in | 7 +++++-- cmake/modules/FindWine.cmake | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index 473046cdb..069938656 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -133,8 +133,11 @@ unset LD_LIBRARY_PATH export LD_LIBRARY_PATH="${APPDIR}usr/lib/lmms/":$LD_LIBRARY_PATH # Handle wine linking -if [ -d "@WINE_LIBRARY_FIX@" ]; then - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@WINE_LIBRARY_FIX@:@WINE_LIBRARY_FIX@wine/ +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/ +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/ fi # Move executables so linuxdeployqt can find them diff --git a/cmake/modules/FindWine.cmake b/cmake/modules/FindWine.cmake index 13443b297..65c628136 100644 --- a/cmake/modules/FindWine.cmake +++ b/cmake/modules/FindWine.cmake @@ -9,13 +9,19 @@ 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_LIBRARY(WINE_LIBRARY NAMES wine PATH_SUFFIXES wine i386-linux-gnu/wine) FIND_PROGRAM(WINE_CXX NAMES wineg++ winegcc winegcc64 winegcc32 winegcc-stable PATHS /usr/lib/wine) FIND_PROGRAM(WINE_BUILD NAMES winebuild) +SET(_ARCHITECTURE ${CMAKE_LIBRARY_ARCHITECTURE}) + +FIND_LIBRARY(WINE_LIBRARY NAMES wine PATH_SUFFIXES wine i386-linux-gnu/wine) + +SET(CMAKE_LIBRARY_ARCHITECTURE ${_ARCHITECTURE}) + SET(WINE_INCLUDE_DIRS ${WINE_INCLUDE_DIR} ) SET(WINE_LIBRARIES ${WINE_LIBRARY} ) @@ -25,6 +31,10 @@ 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 @@ -34,8 +44,7 @@ FOREACH(FLAG ${WINEBUILD_FLAGS}) # WineHQ (/opt/wine-stable, /opt/wine-devel, /opt/wine-staging) STRING(REPLACE "/lib64/wine/" "/lib/wine/" FLAG "${FLAG}") - STRING(REGEX REPLACE "/wine/libwinecrt0.a.*" "" WINE_LIBRARY_FIX "${FLAG}") - SET(WINE_LIBRARY_FIX "${WINE_LIBRARY_FIX}/") + SET(WINE_32_LIBRARY_DIR "${FLAG}/") ENDIF() ENDFOREACH() @@ -44,8 +53,8 @@ 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_LIBRARY_FIX) - SET(WINE_32_FLAGS "-L${WINE_LIBRARY_FIX}wine/ -L${WINE_LIBRARY_FIX}") +IF(WINE_32_LIBRARY_DIR) + SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR}wine/ -L${WINE_32_LIBRARY_DIR}") ENDIF() # Create winegcc wrapper From d42194f8e15a21b8e2b27070d3118b46f0c78042 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Mon, 11 Jun 2018 17:01:40 +0200 Subject: [PATCH 069/445] VstPlugin: Fix define naming conflict with MinGW --- plugins/vst_base/VstPlugin.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index b14efcb5e..791150da1 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -74,6 +74,11 @@ namespace PE // Utilities for reading PE file machine type // See specification at https://msdn.microsoft.com/library/windows/desktop/ms680547(v=vs.85).aspx +// Work around name conflict +#ifdef i386 +# undef i386 +#endif + enum class MachineType : uint16_t { unknown = 0x0, From 156c134301a86f57c48be952213b5733952af7a9 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sat, 16 Jun 2018 13:15:24 +0200 Subject: [PATCH 070/445] winegcc_wrapper: Remove misleading usage hint winegcc_wrapper.in is only intended to be used within FindWine.cmake. Also moved it to the same directory for this reason. --- cmake/modules/FindWine.cmake | 2 +- cmake/{linux => modules}/winegcc_wrapper.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename cmake/{linux => modules}/winegcc_wrapper.in (97%) diff --git a/cmake/modules/FindWine.cmake b/cmake/modules/FindWine.cmake index 65c628136..a697a9dbc 100644 --- a/cmake/modules/FindWine.cmake +++ b/cmake/modules/FindWine.cmake @@ -58,5 +58,5 @@ IF(WINE_32_LIBRARY_DIR) ENDIF() # Create winegcc wrapper -configure_file(${CMAKE_CURRENT_LIST_DIR}/../linux/winegcc_wrapper.in winegcc_wrapper @ONLY) +configure_file(${CMAKE_CURRENT_LIST_DIR}/winegcc_wrapper.in winegcc_wrapper @ONLY) SET(WINEGCC "${CMAKE_CURRENT_BINARY_DIR}/winegcc_wrapper") diff --git a/cmake/linux/winegcc_wrapper.in b/cmake/modules/winegcc_wrapper.in similarity index 97% rename from cmake/linux/winegcc_wrapper.in rename to cmake/modules/winegcc_wrapper.in index 5894c593d..fee88c496 100755 --- a/cmake/linux/winegcc_wrapper.in +++ b/cmake/modules/winegcc_wrapper.in @@ -1,7 +1,7 @@ #!/bin/sh # Wrapper script for winegcc to remove .exe file ending automatically # appended by winebuild. -# Usage: winegcc +# See FindWine.cmake for usage set -e From e1cdfd1d478e6137b4c0799704026ae1cc3d9dc7 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 24 Jun 2018 18:40:13 +0200 Subject: [PATCH 071/445] RemotePlugin: Revert unnecessary invalidate() changes Reverts some changes made in 9db8cbfb31f9b6d3e754887a6280770e3d3e2bcd. The consequences of this changes are unsure, so reverting them for now. Since a VST plugin's architecture is now detected before trying to load it, this fix is not needed any more for 64&32-bit VSTs to work, as the idVstBadDllFormat-message-mechanism was removed. It should be noted however that the bug still exists, probably rendering 4fd8ecd7e4084aedbd39900ffe5cfd107ceba1a0 ineffective. --- src/core/RemotePlugin.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/RemotePlugin.cpp b/src/core/RemotePlugin.cpp index c00d26be9..d68f6aa65 100644 --- a/src/core/RemotePlugin.cpp +++ b/src/core/RemotePlugin.cpp @@ -64,9 +64,7 @@ void ProcessWatcher::run() fprintf( stderr, "remote plugin died! invalidating now.\n" ); -#ifndef SYNC_WITH_SHM_FIFO m_plugin->invalidate(); -#endif } } @@ -467,6 +465,9 @@ void RemotePlugin::processFinished( int exitCode, { qCritical() << "Remote plugin exit code: " << exitCode; } +#ifndef SYNC_WITH_SHM_FIFO + invalidate(); +#endif } void RemotePlugin::processErrored( QProcess::ProcessError err ) From f8f38a3d87ab9c6941c615635dc7259eb8fb84bf Mon Sep 17 00:00:00 2001 From: Lukas W Date: Mon, 25 Jun 2018 16:33:17 +0200 Subject: [PATCH 072/445] CircleCI: Make sure build fails when AppImage building does --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 22da7548e..95b98c595 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -100,7 +100,7 @@ jobs: command: | cd build make install - make appimage || cat appimage.log + make appimage || (cat appimage.log && false) cp ./lmms-*.AppImage /tmp/artifacts/ - store_artifacts: path: /tmp/artifacts/ From 1efcec7790aa81a540d365a34a277f957babb1ad Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Mon, 9 Jul 2018 16:47:00 +0100 Subject: [PATCH 073/445] Removing unsetting jack headers path so weakjack can benefit it (#4373) --- CMakeLists.txt | 2 +- src/3rdparty/weakjack/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 026b034ef..503237cd4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -383,7 +383,6 @@ IF(WANT_JACK) SET(LMMS_HAVE_WEAKJACK TRUE) SET(WEAKJACK_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/3rdparty/weakjack/weakjack) SET(STATUS_JACK "OK (weak linking enabled)") - SET(JACK_INCLUDE_DIRS "") # use dlsym instead SET(JACK_LIBRARIES ${CMAKE_DL_LIBS}) ELSE() @@ -391,6 +390,7 @@ IF(WANT_JACK) ENDIF() SET(LMMS_HAVE_JACK TRUE) ELSE(JACK_FOUND) + SET(JACK_INCLUDE_DIRS "") SET(STATUS_JACK "not found, please install libjack0.100.0-dev (or similar) " "if you require JACK support") ENDIF(JACK_FOUND) diff --git a/src/3rdparty/weakjack/CMakeLists.txt b/src/3rdparty/weakjack/CMakeLists.txt index b9f24e331..7600c3915 100644 --- a/src/3rdparty/weakjack/CMakeLists.txt +++ b/src/3rdparty/weakjack/CMakeLists.txt @@ -7,6 +7,6 @@ IF(LMMS_HAVE_WEAKJACK) # Library stub for AppImages running on systems without jack ADD_LIBRARY(weakjack MODULE weakjack/weak_libjack.c weakjack/weak_libjack.h) - TARGET_INCLUDE_DIRECTORIES(weakjack PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/weakjack) + TARGET_INCLUDE_DIRECTORIES(weakjack PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/weakjack ${JACK_INCLUDE_DIRS}) INSTALL(TARGETS weakjack LIBRARY DESTINATION "${PLUGIN_DIR}/optional") ENDIF() From f2d68326a7bc30701d4efcd7d65bb1720a43c649 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 10 Jul 2018 11:13:56 +0900 Subject: [PATCH 074/445] Fix occasional audio interface deadlock (#4450) --- include/AudioJack.h | 2 -- include/AudioPortAudio.h | 1 - include/AudioSoundIo.h | 2 ++ include/fifo_buffer.h | 6 ++++++ src/core/Mixer.cpp | 6 ++++-- src/core/audio/AudioJack.cpp | 4 +--- src/core/audio/AudioPortAudio.cpp | 10 ++-------- src/core/audio/AudioPulseAudio.cpp | 1 + src/core/audio/AudioSdl.cpp | 1 + src/core/audio/AudioSoundIo.cpp | 21 +++++++++++++++++++++ 10 files changed, 38 insertions(+), 16 deletions(-) diff --git a/include/AudioJack.h b/include/AudioJack.h index 60adfc9a5..9bbb3bd48 100644 --- a/include/AudioJack.h +++ b/include/AudioJack.h @@ -37,7 +37,6 @@ #include #include #include -#include #include "AudioDevice.h" #include "AudioDeviceSetupWidget.h" @@ -108,7 +107,6 @@ private: bool m_active; bool m_stopped; - QMutex m_processingMutex; MidiJack *m_midiClient; QVector m_outputPorts; diff --git a/include/AudioPortAudio.h b/include/AudioPortAudio.h index 6a07aad47..e4f27c7e1 100644 --- a/include/AudioPortAudio.h +++ b/include/AudioPortAudio.h @@ -145,7 +145,6 @@ private: int m_outBufSize; bool m_stopped; - QSemaphore m_stopSemaphore; } ; diff --git a/include/AudioSoundIo.h b/include/AudioSoundIo.h index b0192a19e..f743ad676 100644 --- a/include/AudioSoundIo.h +++ b/include/AudioSoundIo.h @@ -109,6 +109,8 @@ private: fpp_t m_outBufFramesTotal; fpp_t m_outBufFrameIndex; + bool m_stopped; + int m_disconnectErr; void onBackendDisconnect(int err); diff --git a/include/fifo_buffer.h b/include/fifo_buffer.h index 39f9867fe..422b48df2 100644 --- a/include/fifo_buffer.h +++ b/include/fifo_buffer.h @@ -66,6 +66,12 @@ public: return( element ); } + void waitUntilRead() + { + m_writer_sem.acquire( m_size ); + m_writer_sem.release( m_size ); + } + bool available() { return( m_reader_sem.available() ); diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index 830d7e6c8..d5baa0a85 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -640,7 +640,7 @@ void Mixer::storeAudioDevice() void Mixer::restoreAudioDevice() { - if( m_oldAudioDev != NULL ) + if( m_oldAudioDev && m_audioDev != m_oldAudioDev ) { stopProcessing(); delete m_audioDev; @@ -648,9 +648,9 @@ void Mixer::restoreAudioDevice() m_audioDev = m_oldAudioDev; emit sampleRateChanged(); - m_oldAudioDev = NULL; startProcessing(); } + m_oldAudioDev = NULL; } @@ -1127,7 +1127,9 @@ void Mixer::fifoWriter::run() write( buffer ); } + // Let audio backend stop processing write( NULL ); + m_fifo->waitUntilRead(); } diff --git a/src/core/audio/AudioJack.cpp b/src/core/audio/AudioJack.cpp index 4d730eed4..bca41356b 100644 --- a/src/core/audio/AudioJack.cpp +++ b/src/core/audio/AudioJack.cpp @@ -201,7 +201,6 @@ bool AudioJack::initJackClient() void AudioJack::startProcessing() { - QMutexLocker m( &m_processingMutex ); m_stopped = false; if( m_active || m_client == NULL ) @@ -254,7 +253,6 @@ void AudioJack::startProcessing() void AudioJack::stopProcessing() { - QMutexLocker m( &m_processingMutex ); m_stopped = true; } @@ -342,7 +340,6 @@ void AudioJack::renamePort( AudioPort * _port ) int AudioJack::processCallback( jack_nframes_t _nframes, void * _udata ) { - QMutexLocker m( &m_processingMutex ); // do midi processing first so that midi input can // add to the following sound processing @@ -406,6 +403,7 @@ int AudioJack::processCallback( jack_nframes_t _nframes, void * _udata ) m_framesDoneInCurBuf = 0; if( !m_framesToDoInCurBuf ) { + m_stopped = true; break; } } diff --git a/src/core/audio/AudioPortAudio.cpp b/src/core/audio/AudioPortAudio.cpp index b14c1e79d..6abb29453 100644 --- a/src/core/audio/AudioPortAudio.cpp +++ b/src/core/audio/AudioPortAudio.cpp @@ -57,8 +57,7 @@ AudioPortAudio::AudioPortAudio( bool & _success_ful, Mixer * _mixer ) : m_paStream( NULL ), m_wasPAInitError( false ), m_outBuf( new surroundSampleFrame[mixer()->framesPerPeriod()] ), - m_outBufPos( 0 ), - m_stopSemaphore( 1 ) + m_outBufPos( 0 ) { _success_ful = false; @@ -167,8 +166,6 @@ AudioPortAudio::AudioPortAudio( bool & _success_ful, Mixer * _mixer ) : printf( "Input device: '%s' backend: '%s'\n", Pa_GetDeviceInfo( inDevIdx )->name, Pa_GetHostApiInfo( Pa_GetDeviceInfo( inDevIdx )->hostApi )->name ); printf( "Output device: '%s' backend: '%s'\n", Pa_GetDeviceInfo( outDevIdx )->name, Pa_GetHostApiInfo( Pa_GetDeviceInfo( outDevIdx )->hostApi )->name ); - m_stopSemaphore.acquire(); - // TODO: debug Mixer::pushInputFrames() //m_supportsCapture = true; @@ -181,7 +178,6 @@ AudioPortAudio::AudioPortAudio( bool & _success_ful, Mixer * _mixer ) : AudioPortAudio::~AudioPortAudio() { stopProcessing(); - m_stopSemaphore.release(); if( !m_wasPAInitError ) { @@ -212,8 +208,7 @@ void AudioPortAudio::stopProcessing() { if( m_paStream && Pa_IsStreamActive( m_paStream ) ) { - m_stopSemaphore.acquire(); - + m_stopped = true; PaError err = Pa_StopStream( m_paStream ); if( err != paNoError ) @@ -283,7 +278,6 @@ int AudioPortAudio::process_callback( if( !frames ) { m_stopped = true; - m_stopSemaphore.release(); memset( _outputBuffer, 0, _framesPerBuffer * channels() * sizeof(float) ); return paComplete; diff --git a/src/core/audio/AudioPulseAudio.cpp b/src/core/audio/AudioPulseAudio.cpp index 23031b10c..20a106ed1 100644 --- a/src/core/audio/AudioPulseAudio.cpp +++ b/src/core/audio/AudioPulseAudio.cpp @@ -103,6 +103,7 @@ void AudioPulseAudio::startProcessing() void AudioPulseAudio::stopProcessing() { + m_quit = true; stopProcessingThread( this ); } diff --git a/src/core/audio/AudioSdl.cpp b/src/core/audio/AudioSdl.cpp index 2b810e913..f513916ba 100644 --- a/src/core/audio/AudioSdl.cpp +++ b/src/core/audio/AudioSdl.cpp @@ -168,6 +168,7 @@ void AudioSdl::sdlAudioCallback( Uint8 * _buf, int _len ) const fpp_t frames = getNextBuffer( m_outBuf ); if( !frames ) { + m_stopped = true; memset( _buf, 0, _len ); return; } diff --git a/src/core/audio/AudioSoundIo.cpp b/src/core/audio/AudioSoundIo.cpp index 46a0315e7..f6c624127 100644 --- a/src/core/audio/AudioSoundIo.cpp +++ b/src/core/audio/AudioSoundIo.cpp @@ -49,6 +49,7 @@ AudioSoundIo::AudioSoundIo( bool & outSuccessful, Mixer * _mixer ) : m_disconnectErr = 0; m_outBufFrameIndex = 0; m_outBufFramesTotal = 0; + m_stopped = true; m_soundio = soundio_create(); if (!m_soundio) @@ -210,15 +211,18 @@ void AudioSoundIo::startProcessing() m_outBuf = new surroundSampleFrame[m_outBufSize]; + m_stopped = false; int err; if ((err = soundio_outstream_start(m_outstream))) { + m_stopped = true; fprintf(stderr, "soundio unable to start stream: %s\n", soundio_strerror(err)); } } void AudioSoundIo::stopProcessing() { + m_stopped = true; if (m_outstream) { soundio_outstream_destroy(m_outstream); @@ -244,6 +248,7 @@ void AudioSoundIo::underflowCallback() void AudioSoundIo::writeCallback(int frameCountMin, int frameCountMax) { + if (m_stopped) {return;} const struct SoundIoChannelLayout *layout = &m_outstream->layout; SoundIoChannelArea *areas; int bytesPerSample = m_outstream->bytes_per_sample; @@ -265,11 +270,27 @@ void AudioSoundIo::writeCallback(int frameCountMin, int frameCountMax) if (!frameCount) break; + + if (m_stopped) + { + for (int channel = 0; channel < layout->channel_count; ++channel) + { + memset(areas[channel].ptr, 0, bytesPerSample * frameCount); + areas[channel].ptr += areas[channel].step * frameCount; + } + continue; + } + for (int frame = 0; frame < frameCount; frame += 1) { if (m_outBufFrameIndex >= m_outBufFramesTotal) { m_outBufFramesTotal = getNextBuffer(m_outBuf); + if (m_outBufFramesTotal == 0) + { + m_stopped = true; + break; + } m_outBufFrameIndex = 0; } From 0dc28436fabf118e223ad71cb24e8365b412e36e Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sat, 7 Jul 2018 16:50:37 +0200 Subject: [PATCH 075/445] Add option to show note values on notes in Piano Roll (#4466) Add the option to show note values on notes in the Piano Roll. This functionality is currently coupled with the option "Enable note labels in piano roll" which can be found in the main menu. The notes are rendered at about 80% of the notes height. They are only rendered if they fit on the whole note and if the font does not become too tiny. Enable the configuration of the note value text's color via the stylesheets and set the value to white for both shipped themes. Other changes: * Clean up some warnings about old school casts and implicit casts. --- data/themes/classic/style.css | 1 + data/themes/default/style.css | 1 + include/PianoRoll.h | 8 +++-- src/gui/editors/PianoRoll.cpp | 67 +++++++++++++++++++++++++++-------- 4 files changed, 61 insertions(+), 16 deletions(-) diff --git a/data/themes/classic/style.css b/data/themes/classic/style.css index 1cf9375bc..9959fddfd 100644 --- a/data/themes/classic/style.css +++ b/data/themes/classic/style.css @@ -123,6 +123,7 @@ PianoRoll { qproperty-backgroundShade: rgba( 255, 255, 255, 10 ); qproperty-noteModeColor: rgb( 255, 255, 255 ); qproperty-noteColor: rgb( 119, 199, 216 ); + qproperty-noteTextColor: rgb( 255, 255, 255 ); qproperty-noteOpacity: 128; qproperty-noteBorders: true; /* boolean property, set false to have borderless notes */ qproperty-selectedNoteColor: rgb( 0, 125, 255 ); diff --git a/data/themes/default/style.css b/data/themes/default/style.css index a4a31ab6b..53a899d8d 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -142,6 +142,7 @@ PianoRoll { qproperty-backgroundShade: rgba(255, 255, 255, 10); qproperty-noteModeColor: #0bd556; qproperty-noteColor: #0bd556; + qproperty-noteTextColor: #ffffff; qproperty-noteOpacity: 165; qproperty-noteBorders: false; /* boolean property, set false to have borderless notes */ qproperty-selectedNoteColor: #064d79; diff --git a/include/PianoRoll.h b/include/PianoRoll.h index 9167804ae..8b0f1babf 100644 --- a/include/PianoRoll.h +++ b/include/PianoRoll.h @@ -59,6 +59,7 @@ 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 noteTextColor READ noteTextColor WRITE setNoteTextColor ) Q_PROPERTY( QColor barColor READ barColor WRITE setBarColor ) Q_PROPERTY( QColor selectedNoteColor READ selectedNoteColor WRITE setSelectedNoteColor ) Q_PROPERTY( QColor textColor READ textColor WRITE setTextColor ) @@ -122,6 +123,8 @@ public: void setNoteModeColor( const QColor & c ); QColor noteColor() const; void setNoteColor( const QColor & c ); + QColor noteTextColor() const; + void setNoteTextColor( const QColor & c ); QColor barColor() const; void setBarColor( const QColor & c ); QColor selectedNoteColor() const; @@ -157,8 +160,8 @@ protected: int getKey( int y ) const; static void drawNoteRect( QPainter & p, int x, int y, - int width, const Note * n, const QColor & noteCol, - const QColor & selCol, const int noteOpc, const bool borderless ); + int width, const Note * n, const QColor & noteCol, const QColor & noteTextColor, + const QColor & selCol, const int noteOpc, const bool borderless, bool drawNoteName ); void removeSelection(); void selectAll(); NoteVector getSelectedNotes(); @@ -384,6 +387,7 @@ private: QColor m_lineColor; QColor m_noteModeColor; QColor m_noteColor; + QColor m_noteTextColor; QColor m_barColor; QColor m_selectedNoteColor; QColor m_textColor; diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index ffcc10c1a..983ffcdc3 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -751,6 +751,12 @@ QColor PianoRoll::noteColor() const void PianoRoll::setNoteColor( const QColor & c ) { m_noteColor = c; } +QColor PianoRoll::noteTextColor() const +{ return m_noteTextColor; } + +void PianoRoll::setNoteTextColor( const QColor & c ) +{ m_noteTextColor = c; } + QColor PianoRoll::barColor() const { return m_barColor; } @@ -810,8 +816,8 @@ 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 & selCol, const int noteOpc, const bool borders ) + int width, const Note * n, const QColor & noteCol, const QColor & noteTextColor, + const QColor & selCol, const int noteOpc, const bool borders, bool drawNoteName ) { ++x; ++y; @@ -822,15 +828,19 @@ void PianoRoll::drawNoteRect( QPainter & p, int x, int y, width = 2; } - int volVal = qMin( 255, 100 + (int) ( ( (float)( n->getVolume() - MinVolume ) ) / - ( (float)( MaxVolume - MinVolume ) ) * 155.0f) ); - float rightPercent = qMin( 1.0f, - ( (float)( n->getPanning() - PanningLeft ) ) / - ( (float)( PanningRight - PanningLeft ) ) * 2.0f ); + // Volume + float const volumeRange = static_cast(MaxVolume - MinVolume); + float const volumeSpan = static_cast(n->getVolume() - MinVolume); + float const volumeRatio = volumeSpan / volumeRange; + int volVal = qMin( 255, 100 + static_cast( volumeRatio * 155.0f) ); - float leftPercent = qMin( 1.0f, - ( (float)( PanningRight - n->getPanning() ) ) / - ( (float)( PanningRight - PanningLeft ) ) * 2.0f ); + // Panning + float const panningRange = static_cast(PanningRight - PanningLeft); + float const leftPanSpan = static_cast(PanningRight - n->getPanning()); + float const rightPanSpan = static_cast(n->getPanning() - PanningLeft); + + float leftPercent = qMin( 1.0f, leftPanSpan / panningRange * 2.0f ); + float rightPercent = qMin( 1.0f, rightPanSpan / panningRange * 2.0f ); QColor col = QColor( noteCol ); QPen pen; @@ -848,9 +858,9 @@ void PianoRoll::drawNoteRect( QPainter & p, int x, int y, // adjust note to make it a bit faded if it has a lower volume // in stereo using gradients QColor lcol = QColor::fromHsv( col.hue(), col.saturation(), - volVal * leftPercent, noteOpc ); + static_cast(volVal * leftPercent), noteOpc ); QColor rcol = QColor::fromHsv( col.hue(), col.saturation(), - volVal * rightPercent, noteOpc ); + static_cast(volVal * rightPercent), noteOpc ); QLinearGradient gradient( x, y, x, y + noteHeight ); gradient.setColorAt( 0, rcol ); @@ -868,6 +878,35 @@ void PianoRoll::drawNoteRect( QPainter & p, int x, int y, p.drawRect( x, y, noteWidth, noteHeight ); + // Draw note key text + if (drawNoteName) + { + p.save(); + int const noteTextHeight = static_cast(noteHeight * 0.8); + if (noteTextHeight > 6) + { + QString noteKeyString = getNoteString(n->key()); + + QFont noteFont(p.font()); + noteFont.setPixelSize(noteTextHeight); + QFontMetrics fontMetrics(noteFont); + QSize textSize = fontMetrics.size(Qt::TextSingleLine, noteKeyString); + + int const distanceToBorder = 2; + int const xOffset = borderWidth + distanceToBorder; + + if (textSize.width() < noteWidth - xOffset) + { + p.setPen(noteTextColor); + p.setFont(noteFont); + QPoint textStart(x + xOffset, y + (noteTextHeight + (noteHeight - noteTextHeight) / 2)); + + p.drawText(textStart, noteKeyString); + } + } + p.restore(); + } + // draw the note endmark, to hint the user to resize p.setBrush( col ); if( width > 2 ) @@ -3022,8 +3061,8 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) // note drawNoteRect( p, x + WHITE_KEY_WIDTH, y_base - key * KEY_LINE_HEIGHT, - note_width, note, noteColor(), selectedNoteColor(), - noteOpacity(), noteBorders() ); + note_width, note, noteColor(), noteTextColor(), selectedNoteColor(), + noteOpacity(), noteBorders(), drawNoteNames ); } // draw note editing stuff From 8dab817e137cf156b6f02bfdbb9281ad9378664f Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Mon, 9 Jul 2018 17:16:40 +0200 Subject: [PATCH 076/445] Implement changes from a code review Use tabs in the style sheets. Make the calculation of the Y offset more concise. --- data/themes/classic/style.css | 2 +- data/themes/default/style.css | 2 +- src/gui/editors/PianoRoll.cpp | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/data/themes/classic/style.css b/data/themes/classic/style.css index 9959fddfd..a952e81dc 100644 --- a/data/themes/classic/style.css +++ b/data/themes/classic/style.css @@ -123,7 +123,7 @@ PianoRoll { qproperty-backgroundShade: rgba( 255, 255, 255, 10 ); qproperty-noteModeColor: rgb( 255, 255, 255 ); qproperty-noteColor: rgb( 119, 199, 216 ); - qproperty-noteTextColor: rgb( 255, 255, 255 ); + qproperty-noteTextColor: rgb( 255, 255, 255 ); qproperty-noteOpacity: 128; qproperty-noteBorders: true; /* boolean property, set false to have borderless notes */ qproperty-selectedNoteColor: rgb( 0, 125, 255 ); diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 53a899d8d..a0ddd3b41 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -142,7 +142,7 @@ PianoRoll { qproperty-backgroundShade: rgba(255, 255, 255, 10); qproperty-noteModeColor: #0bd556; qproperty-noteColor: #0bd556; - qproperty-noteTextColor: #ffffff; + qproperty-noteTextColor: #ffffff; qproperty-noteOpacity: 165; qproperty-noteBorders: false; /* boolean property, set false to have borderless notes */ qproperty-selectedNoteColor: #064d79; diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 983ffcdc3..7a38777e7 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -894,12 +894,13 @@ void PianoRoll::drawNoteRect( QPainter & p, int x, int y, int const distanceToBorder = 2; int const xOffset = borderWidth + distanceToBorder; + int const yOffset = (noteHeight + noteTextHeight) / 2; if (textSize.width() < noteWidth - xOffset) { p.setPen(noteTextColor); p.setFont(noteFont); - QPoint textStart(x + xOffset, y + (noteTextHeight + (noteHeight - noteTextHeight) / 2)); + QPoint textStart(x + xOffset, y + yOffset); p.drawText(textStart, noteKeyString); } From cce730ebffa9f211ce55b40e35dbc9cd2c05d87f Mon Sep 17 00:00:00 2001 From: Lukas W Date: Wed, 13 Jun 2018 10:58:48 +0200 Subject: [PATCH 077/445] Add CMake find modules for FFTW, LibSampleratae and LibSndFile. Removes reliance on pkg-config for finding these libraries. --- CMakeLists.txt | 28 +++------------ cmake/modules/FindFFTW.cmake | 47 +++++++++++++++++++++++++ cmake/modules/FindSamplerate.cmake | 34 ++++++++++++++++++ cmake/modules/FindSndFile.cmake | 39 ++++++++++++++++++++ plugins/Eq/CMakeLists.txt | 1 - plugins/LadspaEffect/swh/CMakeLists.txt | 5 ++- plugins/SpectrumAnalyzer/CMakeLists.txt | 1 - 7 files changed, 127 insertions(+), 28 deletions(-) create mode 100644 cmake/modules/FindFFTW.cmake create mode 100644 cmake/modules/FindSamplerate.cmake create mode 100644 cmake/modules/FindSndFile.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 503237cd4..467c7585a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -165,14 +165,9 @@ FIND_PACKAGE(Qt5Test) SET(QT_QTTEST_LIBRARY Qt5::Test) # check for libsndfile -IF(PKG_CONFIG_FOUND) - PKG_CHECK_MODULES(SNDFILE REQUIRED sndfile>=1.0.18) - IF(NOT SNDFILE_FOUND) - MESSAGE(FATAL_ERROR "LMMS requires libsndfile1 and libsndfile1-dev >= 1.0.18 - please install, remove CMakeCache.txt and try again!") - ENDIF() -ELSE() - FIND_PACKAGE(LibSndFile 1.0.18 REQUIRED) - SET(SNDFILE_LIBRARIES sndfile-shared) +FIND_PACKAGE(SndFile REQUIRED) +IF(NOT SNDFILE_FOUND) + MESSAGE(FATAL_ERROR "LMMS requires libsndfile1 and libsndfile1-dev >= 1.0.18 - please install, remove CMakeCache.txt and try again!") ENDIF() # check if we can use SF_SET_COMPRESSION_LEVEL IF(NOT SNDFILE_VERSION VERSION_LESS 1.0.26) @@ -396,15 +391,8 @@ IF(WANT_JACK) ENDIF(JACK_FOUND) ENDIF(WANT_JACK) - # check for FFTW3F-library -IF(PKG_CONFIG_FOUND) - PKG_CHECK_MODULES(FFTW3F REQUIRED fftw3f>=3.0.0) -ELSE() - #currently find_package for fftw is broken in vcpkg. Replace this when fixed - FIND_PATH(FFTW3F_INCLUDE_DIRS fftw3.h) - FIND_LIBRARY(FFTW3F_LIBRARIES fftw3f) -ENDIF() +FIND_PACKAGE(FFTW COMPONENTS fftw3f REQUIRED) # check for FLTK FIND_PACKAGE(FLTK) @@ -486,13 +474,7 @@ ELSE() ENDIF(WANT_DEBUG_FPE) # check for libsamplerate -IF(PKG_CONFIG_FOUND) - PKG_CHECK_MODULES(SAMPLERATE REQUIRED samplerate>=0.1.8) -ELSE() - #TODO no cmake config support. Can we check the version some other way? - FIND_FILE(SAMPLERATE_INCLUDE_DIRS samplerate.h) - FIND_LIBRARY(SAMPLERATE_LIBRARIES libsamplerate-0) -ENDIF() +FIND_PACKAGE(Samplerate 0.1.8 REQUIRED) # set compiler flags IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") diff --git a/cmake/modules/FindFFTW.cmake b/cmake/modules/FindFFTW.cmake new file mode 100644 index 000000000..9421c86cc --- /dev/null +++ b/cmake/modules/FindFFTW.cmake @@ -0,0 +1,47 @@ +# FindFFTW.cmake - Try to find FFTW3 +# Copyright (c) 2018 Lukas W +# This file is MIT licensed. +# See http://opensource.org/licenses/MIT + +# Try pkgconfig for hints +find_package(PkgConfig QUIET) + +if(NOT FFTW_FIND_COMPONENTS) + set(FFTW_FIND_COMPONENTS fftw3f fftw3 fftwl) +endif() + +if(PKG_CONFIG_FOUND) + pkg_check_modules(FFTW_PKG fftw>=3.0.0) + pkg_check_modules(FFTW3_PKG fftw3>=3.0.0) +endif() + +find_path(FFTW_INCLUDE_DIR + NAMES fftw3.h + PATHS ${FFTW_PKG_INCLUDE_DIRS} ${FFTW3_PKG_INCLUDE_DIRS} +) + +set(check_list) + +foreach(comp ${FFTW_FIND_COMPONENTS}) + string(TOUPPER ${comp} COMP) + if(PKG_CONFIG_FOUND) + pkg_check_modules(${COMP}_PKG REQUIRED ${comp}>=3.0.0) + endif() + + find_library(${COMP}_LIBRARY + NAMES ${comp} + PATHS ${comp}_PKG_LIBRARY_DIRS + ) + list(APPEND check_list ${COMP}_LIBRARY) + + set(${COMP}_LIBRARIES ${${COMP}_LIBRARY} CACHE FILEPATH "${COMP} library path") + set(${COMP}_INCLUDE_DIRS ${FFTW_INCLUDE_DIR} CACHE PATH "${COMP} include path") + mark_as_advanced(${COMP}_LIBRARIES ${COMP}_INCLUDE_DIRS) +endforeach() + +find_package(PackageHandleStandardArgs) +find_package_handle_standard_args(FFTW DEFAULT_MSG FFTW_INCLUDE_DIR ${check_list}) + +set(FFTW_INCLUDE_DIRS ${FFTW_INCLUDE_DIR}) + +mark_as_advanced(FFTW_LIBRARY FFTW_LIBRARIES FFTW_INCLUDE_DIR FFTW_INCLUDE_DIRS ${check_list}) diff --git a/cmake/modules/FindSamplerate.cmake b/cmake/modules/FindSamplerate.cmake new file mode 100644 index 000000000..53b69f6c7 --- /dev/null +++ b/cmake/modules/FindSamplerate.cmake @@ -0,0 +1,34 @@ +# FindFFTW.cmake - Try to find FFTW3 +# Copyright (c) 2018 Lukas W +# This file is MIT licensed. +# See http://opensource.org/licenses/MIT + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(SAMPLERATE_PKG samplerate) +endif() + +find_path(SAMPLERATE_INCLUDE_DIR + NAMES samplerate.h + PATHS ${SAMPLERATE_PKG_INCLUDE_DIRS} +) + +set(SAMPLERATE_NAMES samplerate libsamplerate) +if(Samplerate_FIND_VERSION_MAJOR) + list(APPEND SAMPLERATE_NAMES libsamplerate-${Samplerate_FIND_VERSION_MAJOR}) +else() + list(APPEND SAMPLERATE_NAMES libsamplerate-0) +endif() + +find_library(SAMPLERATE_LIBRARY + NAMES ${SAMPLERATE_NAMES} + PATHS ${SAMPLERATE_PKG_LIBRARY_DIRS} +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(SAMPLERATE DEFAULT_MSG SAMPLERATE_LIBRARY SAMPLERATE_INCLUDE_DIR) + +mark_as_advanced(SAMPLERATE_INCLUDE_DIR SAMPLERATE_LIBRARY ) + +set(SAMPLERATE_LIBRARIES ${SAMPLERATE_LIBRARY} ) +set(SAMPLERATE_INCLUDE_DIRS ${SAMPLERATE_INCLUDE_DIR}) diff --git a/cmake/modules/FindSndFile.cmake b/cmake/modules/FindSndFile.cmake new file mode 100644 index 000000000..28ebb7bb7 --- /dev/null +++ b/cmake/modules/FindSndFile.cmake @@ -0,0 +1,39 @@ +# FindSndFile.cmake - Try to find libsndfile +# Copyright (c) 2018 Lukas W +# This file is MIT licensed. +# See http://opensource.org/licenses/MIT + +# Try pkgconfig for hints +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(SNDFILE_PKG sndfile) +endif(PKG_CONFIG_FOUND) +set(SndFile_DEFINITIONS ${SNDFILE_PKG_CFLAGS_OTHER}) + +if(WIN32) + # Try Vcpkg + find_package(LibSndFile ${SndFile_FIND_VERSION} CONFIG QUIET) + if(LibSndFile_FOUND) + get_target_property(LibSndFile_Location sndfile-shared LOCATION) + get_target_property(LibSndFile_Include_Path sndfile-shared INTERFACE_INCLUDE_DIRECTORIES) + get_filename_component(LibSndFile_Path LibSndFile_Location PATH) + endif() +endif() + +find_path(SNDFILE_INCLUDE_DIR + NAMES sndfile.h + PATHS ${SNDFILE_PKG_INCLUDE_DIRS} ${LibSndFile_Include_Path} +) + +find_library(SNDFILE_LIBRARY + NAMES sndfile libsndfile libsndfile-1 + PATHS ${SNDFILE_PKG_LIBRARY_DIRS} ${LibSndFile_Path} +) + +find_package(PackageHandleStandardArgs) +find_package_handle_standard_args(SndFile DEFAULT_MSG SNDFILE_LIBRARY SNDFILE_INCLUDE_DIR) + +set(SNDFILE_LIBRARIES ${SNDFILE_LIBRARY}) +set(SNDFILE_INCLUDE_DIRS ${SNDFILE_INCLUDE_DIR}) + +mark_as_advanced(SNDFILE_LIBRARY SNDFILE_LIBRARIES SNDFILE_INCLUDE_DIR SNDFILE_INCLUDE_DIRS) diff --git a/plugins/Eq/CMakeLists.txt b/plugins/Eq/CMakeLists.txt index 36109cb3c..899dde5ec 100644 --- a/plugins/Eq/CMakeLists.txt +++ b/plugins/Eq/CMakeLists.txt @@ -1,6 +1,5 @@ INCLUDE(BuildPlugin) INCLUDE_DIRECTORIES(${FFTW3F_INCLUDE_DIRS}) -LINK_DIRECTORIES(${FFTW3F_LIBRARY_DIRS}) LINK_LIBRARIES(${FFTW3F_LIBRARIES}) BUILD_PLUGIN(eq EqEffect.cpp EqCurve.cpp EqCurve.h EqControls.cpp EqControlsDialog.cpp EqFilter.h EqParameterWidget.cpp EqFader.h EqSpectrumView.h EqSpectrumView.cpp MOCFILES EqControls.h EqControlsDialog.h EqCurve.h EqParameterWidget.h EqFader.h EqSpectrumView.h EMBEDDED_RESOURCES *.png) diff --git a/plugins/LadspaEffect/swh/CMakeLists.txt b/plugins/LadspaEffect/swh/CMakeLists.txt index 7703aaa6d..131e60373 100644 --- a/plugins/LadspaEffect/swh/CMakeLists.txt +++ b/plugins/LadspaEffect/swh/CMakeLists.txt @@ -35,7 +35,7 @@ FOREACH(_item ${XML_SOURCES}) # Vocoder does not use fftw IF(NOT ("${_plugin}" STREQUAL "vocoder_1337")) - TARGET_LINK_LIBRARIES("${_plugin}" -lfftw3f) + TARGET_LINK_LIBRARIES("${_plugin}" ${FFTW3F_LIBRARIES}) ENDIF() IF(NOT MSVC) TARGET_LINK_LIBRARIES("${_plugin}" m) @@ -51,10 +51,9 @@ ADD_DEFINITIONS(-DFFTW3) INCLUDE_DIRECTORIES( "${CMAKE_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/ladspa" - ${FFTW3F_INCLUDE_DIRS} + "${FFTW3F_INCLUDE_DIRS}" "${CMAKE_BINARY_DIR}" ) -LINK_DIRECTORIES(${FFTW3F_LIBRARY_DIRS}) ADD_LIBRARY(iir STATIC ladspa/util/iir.c) SET_TARGET_PROPERTIES(iir PROPERTIES COMPILE_FLAGS "${PIC_FLAGS}") diff --git a/plugins/SpectrumAnalyzer/CMakeLists.txt b/plugins/SpectrumAnalyzer/CMakeLists.txt index c2aec0d43..29187b39d 100644 --- a/plugins/SpectrumAnalyzer/CMakeLists.txt +++ b/plugins/SpectrumAnalyzer/CMakeLists.txt @@ -1,5 +1,4 @@ INCLUDE(BuildPlugin) INCLUDE_DIRECTORIES(${FFTW3F_INCLUDE_DIRS}) -LINK_DIRECTORIES(${FFTW3F_LIBRARY_DIRS}) LINK_LIBRARIES(${FFTW3F_LIBRARIES}) BUILD_PLUGIN(spectrumanalyzer SpectrumAnalyzer.cpp SpectrumAnalyzerControls.cpp SpectrumAnalyzerControlDialog.cpp SpectrumAnalyzer.h SpectrumAnalyzerControls.h SpectrumAnalyzerControlDialog.h MOCFILES SpectrumAnalyzerControlDialog.h SpectrumAnalyzerControls.h EMBEDDED_RESOURCES *.png) From c670d4827a6fbaca519d917d012a65c55aad0ee6 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Wed, 11 Jul 2018 20:13:47 +0200 Subject: [PATCH 078/445] Minor QString usage improvements --- include/FileBrowser.h | 4 ++-- plugins/patman/patman.cpp | 1 - src/core/Track.cpp | 1 - src/gui/AutomatableModelView.cpp | 4 +--- src/gui/SetupDialog.cpp | 18 +++++++++--------- 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/include/FileBrowser.h b/include/FileBrowser.h index 1565017d1..7e0482ce3 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -131,11 +131,11 @@ public: inline QString fullName( QString path = QString() ) { - if( path == QString() ) + if( path.isEmpty() ) { path = m_directories[0]; } - if( path != QString() ) + if( ! path.isEmpty() ) { path += QDir::separator(); } diff --git a/plugins/patman/patman.cpp b/plugins/patman/patman.cpp index bf1275321..cd34dea39 100644 --- a/plugins/patman/patman.cpp +++ b/plugins/patman/patman.cpp @@ -78,7 +78,6 @@ PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) patmanInstrument::patmanInstrument( InstrumentTrack * _instrument_track ) : Instrument( _instrument_track, &patman_plugin_descriptor ), - m_patchFile( QString() ), m_loopedModel( true, this ), m_tunedModel( true, this ) { diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 36d649e77..9ceff8f44 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -95,7 +95,6 @@ TextFloat * TrackContentObjectView::s_textFloat = NULL; TrackContentObject::TrackContentObject( Track * track ) : Model( track ), m_track( track ), - m_name( QString() ), m_startPosition(), m_length(), m_mutedModel( false, this, tr( "Mute" ) ), diff --git a/src/gui/AutomatableModelView.cpp b/src/gui/AutomatableModelView.cpp index cdb1a5a04..039c75c99 100644 --- a/src/gui/AutomatableModelView.cpp +++ b/src/gui/AutomatableModelView.cpp @@ -42,9 +42,7 @@ static float floatFromClipboard(bool* ok=nullptr); AutomatableModelView::AutomatableModelView( ::Model* model, QWidget* _this ) : - ModelView( model, _this ), - m_description( QString() ), - m_unit( QString() ) + ModelView( model, _this ) { widget()->setAcceptDrops( true ); widget()->setCursor( QCursor( embed::getIconPixmap( "hand" ), 3, 3 ) ); diff --git a/src/gui/SetupDialog.cpp b/src/gui/SetupDialog.cpp index 555969fb3..84c76128d 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -1269,7 +1269,7 @@ void SetupDialog::openWorkingDir() { QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose LMMS working directory" ), m_workingDir ); - if( new_dir != QString() ) + if( ! new_dir.isEmpty() ) { m_wdLineEdit->setText( new_dir ); } @@ -1280,7 +1280,7 @@ void SetupDialog::openGIGDir() QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose your GIG directory" ), m_gigDir ); - if( new_dir != QString() ) + if( ! new_dir.isEmpty() ) { m_gigLineEdit->setText( new_dir ); } @@ -1291,7 +1291,7 @@ void SetupDialog::openSF2Dir() QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose your SF2 directory" ), m_sf2Dir ); - if( new_dir != QString() ) + if( ! new_dir.isEmpty() ) { m_sf2LineEdit->setText( new_dir ); } @@ -1313,7 +1313,7 @@ void SetupDialog::openVSTDir() QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose your VST-plugin directory" ), m_vstDir ); - if( new_dir != QString() ) + if( ! new_dir.isEmpty() ) { m_vdLineEdit->setText( new_dir ); } @@ -1345,7 +1345,7 @@ void SetupDialog::openArtworkDir() QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose artwork-theme directory" ), m_artworkDir ); - if( new_dir != QString() ) + if( ! new_dir.isEmpty() ) { m_adLineEdit->setText( new_dir ); } @@ -1367,7 +1367,7 @@ void SetupDialog::openLADSPADir() QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose LADSPA plugin directory" ), m_ladDir ); - if( new_dir != QString() ) + if( ! new_dir.isEmpty() ) { if( m_ladLineEdit->text() == "" ) { @@ -1389,7 +1389,7 @@ void SetupDialog::openSTKDir() QString new_dir = FileDialog::getExistingDirectory( this, tr( "Choose STK rawwave directory" ), m_stkDir ); - if( new_dir != QString() ) + if( ! new_dir.isEmpty() ) { m_stkLineEdit->setText( new_dir ); } @@ -1406,7 +1406,7 @@ void SetupDialog::openDefaultSoundfont() tr( "Choose default SoundFont" ), m_defaultSoundfont, "SoundFont2 Files (*.sf2)" ); - if( new_file != QString() ) + if( ! new_file.isEmpty() ) { m_sfLineEdit->setText( new_file ); } @@ -1439,7 +1439,7 @@ void SetupDialog::openBackgroundArtwork() tr( "Choose background artwork" ), dir, "Image Files (" + fileTypes + ")" ); - if( new_file != QString() ) + if( ! new_file.isEmpty() ) { m_baLineEdit->setText( new_file ); } From 3a7b5207b458f2ba4e146a23e1eef00d15e576ff Mon Sep 17 00:00:00 2001 From: Lukas W Date: Wed, 11 Jul 2018 21:56:50 +0200 Subject: [PATCH 079/445] CMake: Fix mismatching if condition error Regression from c45a21aac3beb0bba4c1796cf591ea44d2f2bc46 --- cmake/modules/FindSndio.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/FindSndio.cmake b/cmake/modules/FindSndio.cmake index 3fcd71360..e993702c2 100644 --- a/cmake/modules/FindSndio.cmake +++ b/cmake/modules/FindSndio.cmake @@ -29,6 +29,6 @@ find_package_handle_standard_args(SNDIO DEFAULT_MSG SNDIO_LIBRARY SNDIO_INCLUDE_ if(SNDIO_FOUND) set(SNDIO_INCLUDE_DIRS "${SNDIO_INCLUDE_DIR}") set(SNDIO_LIBRARIES "${SNDIO_LIBRARY}") -endif(HAVE_SNDIO) +endif() mark_as_advanced(SNDIO_INCLUDE_DIR SNDIO_LIBRARY SNDIO_INCLUDE_DIRS SNDIO_LIBRARIES) From 9f64d5214628545dd1692f51812c1b9e82860d75 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Thu, 12 Jul 2018 09:49:02 +0900 Subject: [PATCH 080/445] Always show sample track panning knobs (#4477) Fix hidden sample track panning knobs when using compact track buttons --- src/tracks/SampleTrack.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 3c16025a5..63efa4d26 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -755,15 +755,12 @@ SampleTrackView::SampleTrackView( SampleTrack * _t, TrackContainerView* tcv ) : m_volumeKnob->setVolumeKnob( true ); m_volumeKnob->setModel( &_t->m_volumeModel ); m_volumeKnob->setHintText( tr( "Channel volume:" ), "%" ); - if( ConfigManager::inst()->value( "ui", - "compacttrackbuttons" ).toInt() ) - { - m_volumeKnob->move( DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT-2*24, 2 ); - } - else - { - m_volumeKnob->move( DEFAULT_SETTINGS_WIDGET_WIDTH-2*24, 2 ); - } + + int settingsWidgetWidth = ConfigManager::inst()-> + value( "ui", "compacttrackbuttons" ).toInt() + ? DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + : DEFAULT_SETTINGS_WIDGET_WIDTH; + m_volumeKnob->move( settingsWidgetWidth - 2 * 24, 2 ); m_volumeKnob->setLabel( tr( "VOL" ) ); m_volumeKnob->show(); @@ -771,7 +768,7 @@ SampleTrackView::SampleTrackView( SampleTrack * _t, TrackContainerView* tcv ) : tr( "Panning" ) ); m_panningKnob->setModel( &_t->m_panningModel ); m_panningKnob->setHintText( tr( "Panning:" ), "%" ); - m_panningKnob->move( DEFAULT_SETTINGS_WIDGET_WIDTH-24, 2 ); + m_panningKnob->move( settingsWidgetWidth - 24, 2 ); m_panningKnob->setLabel( tr( "PAN" ) ); m_panningKnob->show(); From 408b72c798cddb6d837cd09d83f3369f9f3b98f1 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Fri, 13 Jul 2018 10:40:24 +0900 Subject: [PATCH 081/445] Use tryLock in audio threads for VST/ZynAddSubFX (#4460) Prevent loading VST or toggling ZynAddSubFX GUI from blocking entire audio processing --- plugins/VstEffect/VstEffect.cpp | 8 +++++--- plugins/vestige/vestige.cpp | 4 +--- plugins/zynaddsubfx/ZynAddSubFx.cpp | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/VstEffect/VstEffect.cpp b/plugins/VstEffect/VstEffect.cpp index ea0241a5a..05cc7a070 100644 --- a/plugins/VstEffect/VstEffect.cpp +++ b/plugins/VstEffect/VstEffect.cpp @@ -95,9 +95,11 @@ bool VstEffect::processAudioBuffer( sampleFrame * _buf, const fpp_t _frames ) sampleFrame * buf = new sampleFrame[_frames]; #endif memcpy( buf, _buf, sizeof( sampleFrame ) * _frames ); - m_pluginMutex.lock(); - m_plugin->process( buf, buf ); - m_pluginMutex.unlock(); + if (m_pluginMutex.tryLock()) + { + m_plugin->process( buf, buf ); + m_pluginMutex.unlock(); + } double out_sum = 0.0; const float w = wetLevel(); diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index 9ea053e8e..540c8b5ce 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -359,14 +359,12 @@ void vestigeInstrument::loadFile( const QString & _file ) void vestigeInstrument::play( sampleFrame * _buf ) { - m_pluginMutex.lock(); + if (!m_pluginMutex.tryLock()) {return;} const fpp_t frames = Engine::mixer()->framesPerPeriod(); if( m_plugin == NULL ) { - BufferManager::clear( _buf, frames ); - m_pluginMutex.unlock(); return; } diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index 8bba1f10f..8c1da751f 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -326,7 +326,7 @@ QString ZynAddSubFxInstrument::nodeName() const void ZynAddSubFxInstrument::play( sampleFrame * _buf ) { - m_pluginMutex.lock(); + if (!m_pluginMutex.tryLock()) {return;} if( m_remotePlugin ) { m_remotePlugin->process( NULL, _buf ); From 45d3359e2114022f875cb28d2a5b9974e826dd09 Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Sun, 15 Jul 2018 14:03:37 +0200 Subject: [PATCH 082/445] Some demo project license fixes (#4481) Add some missing licenses and split out CapDan and Skiessi project licenses to their own files in the corresponding directories. --- data/projects/demos/CapDan/LICENSES.TXT | 15 +++++++++ data/projects/demos/LICENSES.TXT | 40 +++++++----------------- data/projects/demos/Skiessi/LICENSES.TXT | 7 +++++ data/projects/shorties/LICENSES.TXT | 8 +++++ 4 files changed, 42 insertions(+), 28 deletions(-) create mode 100644 data/projects/demos/CapDan/LICENSES.TXT create mode 100644 data/projects/demos/Skiessi/LICENSES.TXT diff --git a/data/projects/demos/CapDan/LICENSES.TXT b/data/projects/demos/CapDan/LICENSES.TXT new file mode 100644 index 000000000..6a640decd --- /dev/null +++ b/data/projects/demos/CapDan/LICENSES.TXT @@ -0,0 +1,15 @@ +* CapDan-ReggaeTry.mmpz + - Artistic 2.0 + - https://lmms.io/lsp/index.php?action=show&file=1369 + +* CapDan-ReggaetonTry.mmpz + - Artistic 2.0 + - https://lmms.io/lsp/index.php?action=show&file=1370 + +* CapDan-TwilightArea-OriginalByAlf42red.mmpz + - CC (by-sa) + - https://lmms.io/lsp/index.php?action=show&file=1439 + +* CapDan-ZeroSumGame-OriginalByZakarra.mmpz + - Artistic 2.0 + - https://lmms.io/lsp/index.php?action=show&file=1565 diff --git a/data/projects/demos/LICENSES.TXT b/data/projects/demos/LICENSES.TXT index c33cc02c8..399d7909f 100644 --- a/data/projects/demos/LICENSES.TXT +++ b/data/projects/demos/LICENSES.TXT @@ -2,22 +2,6 @@ - CC (by-sa) - https://lmms.io/lsp/index.php?action=show&file=819 -* CapDan-ReggaeTry.mmpz - - Artistic 2.0 - - https://lmms.io/lsp/index.php?action=show&file=1369 - -* CapDan-ReggaetonTry.mmpz - - Artistic 2.0 - - https://lmms.io/lsp/index.php?action=show&file=1370 - -* CapDan-TwilightArea-OriginalByAlf42red.mmpz - - CC (by-sa) - - https://lmms.io/lsp/index.php?action=show&file=1439 - -* CapDan-ZeroSumGame-OriginalByZakarra.mmpz - - Artistic 2.0 - - https://lmms.io/lsp/index.php?action=show&file=1565 - * EsoXLB-CPU.mmpz - Artistic 2.0 - https://lmms.io/lsp/index.php?action=show&file=723 @@ -34,6 +18,10 @@ - Artistic 2.0 - https://lmms.io/lsp/index.php?action=show&file=581 +* Jousboxx-BuzzerBeater.mmpz + - CC BY-SA 4.0 + - https://github.com/LMMS/lmms/pull/3482#issuecomment-293609866 + * Momo64-esp.mmpz - Artistic 2.0 - https://lmms.io/lsp/index.php?action=show&file=1534 @@ -50,6 +38,10 @@ - Artistic 2.0 - https://lmms.io/lsp/index.php?action=show&file=1156 +* Popsip-Electric Dancer.mmpz + - Creative Commons (by-nc) + - https://lmms.io/lsp/?action=show&file=5414 + * Root84-Initialize.mmpz - Yellow openmusic - https://lmms.io/lsp/index.php?action=show&file=628 @@ -62,14 +54,6 @@ - Artistic 2.0 - https://lmms.io/lsp/index.php?action=show&file=515 -* Skiessi-C64.mmpz - - CC (by sa) - - https://lmms.io/lsp/index.php?action=show&file=472 - -* Skiessi-Onion.mmpz - - CC (by-sa) - - https://lmms.io/lsp/index.php?action=show&file=405 - * Socceroos-Progress.mmpz - Artistic 2.0 - https://lmms.io/lsp/index.php?action=show&file=1516 @@ -78,6 +62,10 @@ - Artistic 2.0 - https://lmms.io/lsp/index.php?action=show&file=1060 +* Thaledric-Armageddon.mmpz + - Creative Commons (by-nc-sa) + - https://lmms.io/lsp/?action=show&file=1947 + * Thomasso-AxeFromThe80s.mmpz - Artistic 2.0 - https://lmms.io/lsp/index.php?action=show&file=474 @@ -85,7 +73,3 @@ * unfa-Spoken.mmpz - CC (by-nc) - https://lmms.io/lsp/index.php?action=show&file=4929 - -* Jousboxx-BuzzerBeater.mmpz - - CC (by-sa) - - https://lmms.io/lsp/?action=show&file=10488 diff --git a/data/projects/demos/Skiessi/LICENSES.TXT b/data/projects/demos/Skiessi/LICENSES.TXT new file mode 100644 index 000000000..8cb4adc86 --- /dev/null +++ b/data/projects/demos/Skiessi/LICENSES.TXT @@ -0,0 +1,7 @@ +* Skiessi-C64.mmpz + - CC (by sa) + - https://lmms.io/lsp/index.php?action=show&file=472 + +* Skiessi-Onion.mmpz + - CC (by-sa) + - https://lmms.io/lsp/index.php?action=show&file=405 diff --git a/data/projects/shorties/LICENSES.TXT b/data/projects/shorties/LICENSES.TXT index bba2b5547..47969a984 100644 --- a/data/projects/shorties/LICENSES.TXT +++ b/data/projects/shorties/LICENSES.TXT @@ -1,3 +1,11 @@ +* Crunk(Demo).mmp + - Artistic 2.0 + - https://lmms.io/lsp/?action=show&file=4093 + +* DirtyLove.mmpz + - CC-BY-SA + - https://github.com/LMMS/lmms/pull/2727 + * Greshz-CoolSnip.mmpz - Artistic 2.0 - https://lmms.io/lsp/index.php?action=show&file=1170 From 820d006c4e5594f8e009aef46ca1e8f1fe0febcc Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 17 Jun 2018 10:04:14 +0200 Subject: [PATCH 083/445] Add Appveyor script, fix 32bit Windows compilation --- .appveyor.yml | 22 ++++++++++++++++++++++ CMakeLists.txt | 2 +- include/AudioSdl.h | 4 ++-- 3 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 .appveyor.yml diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 000000000..d9cf55c2a --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,22 @@ +clone_depth: 1 +version: "{build}" +image: Visual Studio 2015 +platform: + - x86 + - x64 +environment: + matrix: + - compiler: msvc +install: + - vcpkg install --triplet %PLATFORM%-windows fftw3 libsamplerate libsndfile sdl2 +build_script: + - cd %APPVEYOR_BUILD_FOLDER% + - mkdir build + - cd build + - ps: $env:CMAKE_PLATFORM="$(if ($env:PLATFORM -eq 'x64') { 'x64' } else { '' })" + - ps: $env:QT_SUFFIX="$(if ($env:PLATFORM -eq 'x64') { '_64' } else { '' })" + - cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_PREFIX_PATH=c:/Qt/5.9.5/msvc2015%QT_SUFFIX%;c:/tools/vcpkg/installed/%PLATFORM%-windows -DCMAKE_GENERATOR_PLATFORM="%CMAKE_PLATFORM%" .. + - cmake --build . -- /maxcpucount:4 + - cmake --build . --target tests +cache: + - c:/tools/vcpkg/installed diff --git a/CMakeLists.txt b/CMakeLists.txt index 467c7585a..b9c0c6885 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -474,7 +474,7 @@ ELSE() ENDIF(WANT_DEBUG_FPE) # check for libsamplerate -FIND_PACKAGE(Samplerate 0.1.8 REQUIRED) +FIND_PACKAGE(Samplerate 0.1.8 MODULE REQUIRED) # set compiler flags IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") diff --git a/include/AudioSdl.h b/include/AudioSdl.h index 19d9606eb..fd8c544c2 100644 --- a/include/AudioSdl.h +++ b/include/AudioSdl.h @@ -88,8 +88,8 @@ private: surroundSampleFrame * m_outBuf; #ifdef LMMS_HAVE_SDL2 - uint64_t m_currentBufferFramePos; - uint64_t m_currentBufferFramesCount; + size_t m_currentBufferFramePos; + size_t m_currentBufferFramesCount; #else Uint8 * m_convertedBuf; int m_convertedBufPos; From 8cca464c2761081849251aa2d7b6c89e000a3fd6 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 17 Jun 2018 19:31:32 +0200 Subject: [PATCH 084/445] CMake: Add support for clcache --- .appveyor.yml | 3 ++- CMakeLists.txt | 12 +----------- cmake/modules/CompileCache.cmake | 25 +++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 12 deletions(-) create mode 100644 cmake/modules/CompileCache.cmake diff --git a/.appveyor.yml b/.appveyor.yml index d9cf55c2a..a12ea1260 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -9,13 +9,14 @@ environment: - compiler: msvc install: - vcpkg install --triplet %PLATFORM%-windows fftw3 libsamplerate libsndfile sdl2 + - nuget install clcache -Version 4.1.0 build_script: - cd %APPVEYOR_BUILD_FOLDER% - mkdir build - cd build - ps: $env:CMAKE_PLATFORM="$(if ($env:PLATFORM -eq 'x64') { 'x64' } else { '' })" - ps: $env:QT_SUFFIX="$(if ($env:PLATFORM -eq 'x64') { '_64' } else { '' })" - - cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_PREFIX_PATH=c:/Qt/5.9.5/msvc2015%QT_SUFFIX%;c:/tools/vcpkg/installed/%PLATFORM%-windows -DCMAKE_GENERATOR_PLATFORM="%CMAKE_PLATFORM%" .. + - cmake -DUSE_COMPILE_CACHE=ON -DCACHE_TOOL=%APPVEYOR_BUILD_FOLDER%/clcache.4.1.0/clcache-4.1.0/clcache.exe -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_PREFIX_PATH=c:/Qt/5.9.5/msvc2015%QT_SUFFIX%;c:/tools/vcpkg/installed/%PLATFORM%-windows -DCMAKE_GENERATOR_PLATFORM="%CMAKE_PLATFORM%" .. - cmake --build . -- /maxcpucount:4 - cmake --build . --target tests cache: diff --git a/CMakeLists.txt b/CMakeLists.txt index b9c0c6885..fce878428 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -546,17 +546,7 @@ IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") ENDIF() # use ccache -OPTION(USE_CCACHE "Use ccache for compilation" OFF) -IF(USE_CCACHE) - FIND_PROGRAM(CCACHE ccache) - IF (CCACHE) - MESSAGE(STATUS "Using ccache found in PATH") - SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE}) - SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE}) - ELSE() - MESSAGE(WARNING "USE_CCACHE enabled, but no ccache found") - ENDIF() -ENDIF() +include(CompileCache) # make sub-directories ADD_SUBDIRECTORY(cmake) diff --git a/cmake/modules/CompileCache.cmake b/cmake/modules/CompileCache.cmake new file mode 100644 index 000000000..ed4622bd9 --- /dev/null +++ b/cmake/modules/CompileCache.cmake @@ -0,0 +1,25 @@ +option(USE_COMPILE_CACHE "Use ccache or clcache for compilation" OFF) + +# Compatibility for old option name +if(USE_CCACHE) + set(USE_COMPILE_CACHE ON) +endif() + +if(USE_COMPILE_CACHE) + if(MSVC) + set(CACHE_TOOL_NAME clcache) + elseif(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|AppleClang|Clang)") + set(CACHE_TOOL_NAME ccache) + else() + message(WARNING "Compile cache only available with MSVC or GNU") + endif() + + find_program(CACHE_TOOL ${CACHE_TOOL_NAME}) + if (CACHE_TOOL) + message(STATUS "Using ${CACHE_TOOL} found for caching") + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CACHE_TOOL}) + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CACHE_TOOL}) + else() + message(WARNING "USE_COMPILE_CACHE enabled, but no ${CACHE_TOOL_NAME} found") + endif() +endif() From 020ce8e4db673d06fc52c17e675b2a65cb6900d6 Mon Sep 17 00:00:00 2001 From: "P.J. Finlay" Date: Sun, 15 Jul 2018 22:26:25 -0400 Subject: [PATCH 085/445] Added an uninstall target for make --- CMakeLists.txt | 11 +++++- cmake/uninstall.cmake | 78 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 cmake/uninstall.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index da5be324a..87ef9c952 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.7) +CMAKE_MINIMUM_REQUIRED(VERSION 3.3) PROJECT(lmms) @@ -609,6 +609,15 @@ ADD_CUSTOM_TARGET(dist COMMAND tar cjf lmms-${VERSION}-src.tar.bz2 "${TMP}" COMMAND rm -rf "${TMP}") + +# +# add uninstall-target +# +ADD_CUSTOM_TARGET(uninstall + COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/uninstall.cmake" +) + + # # display configuration information # diff --git a/cmake/uninstall.cmake b/cmake/uninstall.cmake new file mode 100644 index 000000000..093d1dbfe --- /dev/null +++ b/cmake/uninstall.cmake @@ -0,0 +1,78 @@ +MESSAGE(STATUS "Attempting to create uninstall target for make") + +#Remove all of the files listed in install_manifest.txt +SET(INSTALL_MANIFEST_PATH "${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt") +IF(NOT EXISTS ${INSTALL_MANIFEST_PATH}) + MESSAGE(FATAL_ERROR "Could not find install manifest at ${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\nThis may be because 'make install' has not been run or install_manifest.txt has been deleted") +ENDIF() +MESSAGE(STATUS "install_manifest.txt found") +FILE(STRINGS ${INSTALL_MANIFEST_PATH} FILES_TO_REMOVE) +FOREACH(FILE_TO_REMOVE ${FILES_TO_REMOVE}) + IF(EXISTS ${FILE_TO_REMOVE}) + EXECUTE_PROCESS( + COMMAND ${CMAKE_COMMAND} -E remove ${FILE_TO_REMOVE} + RESULT_VARIABLE EXIT_CODE + ) + IF(${EXIT_CODE} EQUAL 0) + MESSAGE(STATUS "Successfully removed file ${FILE_TO_REMOVE}") + ELSE() + MESSAGE(FATAL_ERROR "Failed to remove file ${FILE_TO_REMOVE} with error code ${EXIT_CODE}") + ENDIF() + ELSE() + MESSAGE(WARNING "Could not find file ${FILE_TO_REMOVE}") + ENDIF() +ENDFOREACH(FILE_TO_REMOVE) + +#Remove empty directories created during installation +#Required to support IN_LIST operator +CMAKE_POLICY(SET CMP0057 NEW) + +# Checks if a directory is empty and saves the result in out_var +FUNCTION(IS_EMPTY_DIR OUT_VAR DIR) + FILE(GLOB FILES "${DIR}/*") + LIST(LENGTH FILES NUM_FILES) + IF(NUM_FILES EQUAL 0) + SET(${OUT_VAR} TRUE PARENT_SCOPE) + ELSE() + SET(${OUT_VAR} FALSE PARENT_SCOPE) + ENDIF() +ENDFUNCTION() + +# Recursively append all parent directories of path to out_var +FUNCTION(PARENT_DIRECTORIES OUT_VAR PATH) + GET_FILENAME_COMPONENT(PARENT "${PATH}" DIRECTORY) + IF(PARENT AND NOT PARENT STREQUAL PATH AND NOT PARENT IN_LIST ${OUT_VAR}) + LIST(APPEND ${OUT_VAR} ${PARENT}) + PARENT_DIRECTORIES(${OUT_VAR} "${PARENT}") + ENDIF() + SET(${OUT_VAR} ${${OUT_VAR}} PARENT_SCOPE) +ENDFUNCTION() + +# Removes all empty parent directories of the given files +FUNCTION(REMOVE_EMPTY_DIRECTORIES FILES) + SET(DIRECTORIES) + FOREACH(FILE_TO_REMOVE ${FILES}) + PARENT_DIRECTORIES(DIRECTORIES "${FILE_TO_REMOVE}") + endforeach() + LIST(REMOVE_DUPLICATES DIRECTORIES) + # Sort and reverse so we remove subdirectories first + LIST(SORT DIRECTORIES) + LIST(REVERSE DIRECTORIES) + + FOREACH(DIR ${DIRECTORIES}) + # Skip directories not inside the install prefix + IF(NOT (EXISTS "${DIR}" AND DIR MATCHES "^${CMAKE_INSTALL_PREFIX}/")) + CONTINUE() + ENDIF() + + IS_EMPTY_DIR(DIR_EMPTY "${DIR}") + IF(DIR_EMPTY) + MESSAGE(STATUS "Removing empty directory ${DIR}") + FILE(REMOVE_RECURSE "${DIR}") + ELSEIF() + MESSAGE(STATUS "Skipping non-empty directory ${DIR}") + ENDIF() + ENDFOREACH() +ENDFUNCTION() + +REMOVE_EMPTY_DIRECTORIES("${FILES_TO_REMOVE}") From 63fd427c5e386fe769d1dde10057a094e68f2fd4 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 22 Jul 2018 11:41:54 +0200 Subject: [PATCH 086/445] CMake: Minor uninstall changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix missing CMAKE_UNINSTALL_PREFIX variable * Use CMAKE_MINIMUM_REQUIRED instead of CMAKE_POLICY for IN_LIST support * Use FILE(REMOVE …) instead of EXECUTE_PROCESS(…) for better performance * Control flow changes --- CMakeLists.txt | 2 +- cmake/uninstall.cmake | 26 ++++++++++++-------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 87ef9c952..d264c20c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -614,7 +614,7 @@ ADD_CUSTOM_TARGET(dist # add uninstall-target # ADD_CUSTOM_TARGET(uninstall - COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/uninstall.cmake" + COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}" -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/uninstall.cmake" ) diff --git a/cmake/uninstall.cmake b/cmake/uninstall.cmake index 093d1dbfe..6f6260b58 100644 --- a/cmake/uninstall.cmake +++ b/cmake/uninstall.cmake @@ -1,3 +1,5 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.3) + MESSAGE(STATUS "Attempting to create uninstall target for make") #Remove all of the files listed in install_manifest.txt @@ -8,24 +10,20 @@ ENDIF() MESSAGE(STATUS "install_manifest.txt found") FILE(STRINGS ${INSTALL_MANIFEST_PATH} FILES_TO_REMOVE) FOREACH(FILE_TO_REMOVE ${FILES_TO_REMOVE}) - IF(EXISTS ${FILE_TO_REMOVE}) - EXECUTE_PROCESS( - COMMAND ${CMAKE_COMMAND} -E remove ${FILE_TO_REMOVE} - RESULT_VARIABLE EXIT_CODE - ) - IF(${EXIT_CODE} EQUAL 0) - MESSAGE(STATUS "Successfully removed file ${FILE_TO_REMOVE}") - ELSE() - MESSAGE(FATAL_ERROR "Failed to remove file ${FILE_TO_REMOVE} with error code ${EXIT_CODE}") - ENDIF() - ELSE() + IF(NOT EXISTS "${FILE_TO_REMOVE}") MESSAGE(WARNING "Could not find file ${FILE_TO_REMOVE}") + CONTINUE() + ENDIF() + + FILE(REMOVE "${FILE_TO_REMOVE}") + IF(NOT EXISTS "${FILE_TO_REMOVE}") + MESSAGE(STATUS "Successfully removed file ${FILE_TO_REMOVE}") + ELSE() + MESSAGE(FATAL_ERROR "Failed to remove file ${FILE_TO_REMOVE}.") ENDIF() ENDFOREACH(FILE_TO_REMOVE) -#Remove empty directories created during installation -#Required to support IN_LIST operator -CMAKE_POLICY(SET CMP0057 NEW) +# Remove empty directories created during installation # Checks if a directory is empty and saves the result in out_var FUNCTION(IS_EMPTY_DIR OUT_VAR DIR) From 7ddca851d1b18bbc64b7d1ee15078b0daa8501c9 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Thu, 26 Jul 2018 14:16:15 +0200 Subject: [PATCH 087/445] VstPlugin: Fix detecting machine type with relative paths --- plugins/vst_base/VstPlugin.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 9b2bdc88d..72bad8d60 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -125,11 +125,16 @@ VstPlugin::VstPlugin( const QString & _plugin ) : m_version( 0 ), m_currentProgram() { + if( QDir::isRelativePath( m_plugin ) ) + { + m_plugin = ConfigManager::inst()->vstDir() + m_plugin; + } + setSplittedChannels( true ); PE::MachineType machineType; try { - PE::FileInfo peInfo(_plugin); + PE::FileInfo peInfo(m_plugin); machineType = peInfo.machineType(); } catch (std::runtime_error& e) { qCritical() << "Error while determining PE file's machine type: " << e.what(); @@ -197,16 +202,7 @@ void VstPlugin::tryLoad( const QString &remoteVstPluginExecutable ) default: break; } sendMessage( message( IdVstSetLanguage ).addInt( hlang ) ); - - - QString p = m_plugin; - if( QFileInfo( p ).dir().isRelative() ) - { - p = ConfigManager::inst()->vstDir() + p; - } - - - sendMessage( message( IdVstLoadPlugin ).addString( QSTR_TO_STDSTR( p ) ) ); + sendMessage( message( IdVstLoadPlugin ).addString( QSTR_TO_STDSTR( m_plugin ) ) ); waitForInitDone(); From 515fefa6ce734fcc5cf119b8eff8c3c0db65cdfc Mon Sep 17 00:00:00 2001 From: Lukas W Date: Thu, 26 Jul 2018 18:37:35 +0200 Subject: [PATCH 088/445] Winewrapper fixes (#4501) * Fix library fix regression from 38f6371de6 * Fix missing windows include directory --- cmake/modules/FindWine.cmake | 2 +- cmake/modules/winegcc_wrapper.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/FindWine.cmake b/cmake/modules/FindWine.cmake index a697a9dbc..225d6a824 100644 --- a/cmake/modules/FindWine.cmake +++ b/cmake/modules/FindWine.cmake @@ -42,7 +42,7 @@ FOREACH(FLAG ${WINEBUILD_FLAGS}) # Gentoo systems STRING(REPLACE "/lib/wine-" "/lib32/wine-" FLAG "${FLAG}") # WineHQ (/opt/wine-stable, /opt/wine-devel, /opt/wine-staging) - STRING(REPLACE "/lib64/wine/" "/lib/wine/" FLAG "${FLAG}") + STRING(REGEX REPLACE "/lib64$" "/lib" FLAG "${FLAG}") SET(WINE_32_LIBRARY_DIR "${FLAG}/") ENDIF() diff --git a/cmake/modules/winegcc_wrapper.in b/cmake/modules/winegcc_wrapper.in index fee88c496..d7d680be2 100755 --- a/cmake/modules/winegcc_wrapper.in +++ b/cmake/modules/winegcc_wrapper.in @@ -40,7 +40,7 @@ fi # Some Wine distributions can't find their own headers. WINE_INCLUDE_DIR provided # by FindWine.cmake -extra_args="-I@WINE_INCLUDE_DIR@" +extra_args="-I@WINE_INCLUDE_DIR@ -I@WINE_INCLUDE_DIR@/wine/windows" # Apply -m32 library fix if necessary if [ "$win32" = true ] && [ "$no_link" != true ]; then From 112d34226ad1ee3f8c53f0160aba4ff27c0fb6d6 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Fri, 27 Jul 2018 15:48:58 +0900 Subject: [PATCH 089/445] Fix broken MIDI import Fix a regression in 3e538d510c135d6b6504298aa57135506397c708 (#4401) that readAllData doesn't read the file from the beginning --- include/ImportFilter.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/ImportFilter.h b/include/ImportFilter.h index 1b6fe2b59..53c769adf 100644 --- a/include/ImportFilter.h +++ b/include/ImportFilter.h @@ -80,6 +80,7 @@ protected: inline QByteArray readAllData() { + m_file.seek(0); return m_file.readAll(); } From f245d7454b9e0c07959f804e046d80d489666db7 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Fri, 27 Jul 2018 18:03:51 +0200 Subject: [PATCH 090/445] MSVC: Enable VstEffect --- plugins/CMakeLists.txt | 2 +- plugins/VstEffect/CMakeLists.txt | 1 - plugins/VstEffect/VstEffectControls.cpp | 16 +++++++--------- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 0f7e59443..01e313c17 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -96,7 +96,7 @@ IF(MSVC) ReverbSC sid vibed - VstEffect + #VstEffect Xpressive zynaddsubfx ) diff --git a/plugins/VstEffect/CMakeLists.txt b/plugins/VstEffect/CMakeLists.txt index 78d8e6483..68ef141d9 100644 --- a/plugins/VstEffect/CMakeLists.txt +++ b/plugins/VstEffect/CMakeLists.txt @@ -11,7 +11,6 @@ ELSE() ENDIF() BUILD_PLUGIN(vsteffect VstEffect.cpp VstEffectControls.cpp VstEffectControlDialog.cpp VstSubPluginFeatures.cpp VstEffect.h VstEffectControls.h VstEffectControlDialog.h VstSubPluginFeatures.h MOCFILES VstEffectControlDialog.h VstEffectControls.h EMBEDDED_RESOURCES *.png) -SET_TARGET_PROPERTIES(vsteffect PROPERTIES COMPILE_FLAGS "-Wno-attributes") TARGET_LINK_LIBRARIES(vsteffect vstbase) ENDIF(LMMS_SUPPORT_VST) diff --git a/plugins/VstEffect/VstEffectControls.cpp b/plugins/VstEffect/VstEffectControls.cpp index 173a76913..07c7063c6 100644 --- a/plugins/VstEffect/VstEffectControls.cpp +++ b/plugins/VstEffect/VstEffectControls.cpp @@ -209,18 +209,16 @@ void VstEffectControls::updateMenu( void ) QMenu * to_menu = m_selPresetButton->menu(); to_menu->clear(); - QAction *presetActions[list1.size()]; - for (int i = 0; i < list1.size(); i++) { - presetActions[i] = new QAction(this); - connect(presetActions[i], SIGNAL(triggered()), this, SLOT(selPreset())); + QAction* presetAction = new QAction(this); + connect(presetAction, SIGNAL(triggered()), this, SLOT(selPreset())); - presetActions[i]->setText(QString("%1. %2").arg(QString::number(i+1), list1.at(i))); - presetActions[i]->setData(i); + presetAction->setText(QString("%1. %2").arg(QString::number(i+1), list1.at(i))); + presetAction->setData(i); if (i == lastPosInMenu) { - presetActions[i]->setIcon(embed::getIconPixmap( "sample_file", 16, 16 )); - } else presetActions[i]->setIcon(embed::getIconPixmap( "edit_copy", 16, 16 )); - to_menu->addAction( presetActions[i] ); + presetAction->setIcon(embed::getIconPixmap( "sample_file", 16, 16 )); + } else presetAction->setIcon(embed::getIconPixmap( "edit_copy", 16, 16 )); + to_menu->addAction( presetAction ); } } From adcc009d2bda519bb62365121e6d8f1769f61a09 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sat, 28 Jul 2018 13:44:16 +0200 Subject: [PATCH 091/445] MSVC: Fix vibed plugin --- plugins/CMakeLists.txt | 1 - plugins/vibed/vibrating_string.cpp | 2 +- plugins/vibed/vibrating_string.h | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 01e313c17..798c45ae4 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -95,7 +95,6 @@ IF(MSVC) organic ReverbSC sid - vibed #VstEffect Xpressive zynaddsubfx diff --git a/plugins/vibed/vibrating_string.cpp b/plugins/vibed/vibrating_string.cpp index a2080a69c..c32202717 100644 --- a/plugins/vibed/vibrating_string.cpp +++ b/plugins/vibed/vibrating_string.cpp @@ -56,7 +56,7 @@ vibratingString::vibratingString( float _pitch, int pick = static_cast( ceil( string_length * _pick ) ); - if( not _state ) + if( ! _state ) { m_impulse = new float[string_length]; resample( _impulse, _len, string_length ); diff --git a/plugins/vibed/vibrating_string.h b/plugins/vibed/vibrating_string.h index 06358501f..3739d19a9 100644 --- a/plugins/vibed/vibrating_string.h +++ b/plugins/vibed/vibrating_string.h @@ -121,7 +121,7 @@ private: float r; float offset; - if( not _state ) + if( ! _state ) { for( int i = 0; i < _pick; i++ ) { From ac65fb99245b44655ef7ac1f637bb2a68808683a Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sat, 28 Jul 2018 14:00:06 +0200 Subject: [PATCH 092/445] MSVC: Fix Organic instrument --- plugins/CMakeLists.txt | 1 - plugins/organic/organic.cpp | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 798c45ae4..8c814736b 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -92,7 +92,6 @@ IF(MSVC) SET(MSVC_INCOMPATIBLE_PLUGINS LadspaEffect monstro - organic ReverbSC sid #VstEffect diff --git a/plugins/organic/organic.cpp b/plugins/organic/organic.cpp index 8f5ae6b36..b6d45c8d3 100644 --- a/plugins/organic/organic.cpp +++ b/plugins/organic/organic.cpp @@ -233,8 +233,8 @@ void organicInstrument::playNote( NotePlayHandle * _n, if( _n->totalFramesPlayed() == 0 || _n->m_pluginData == NULL ) { - Oscillator * oscs_l[m_numOscillators]; - Oscillator * oscs_r[m_numOscillators]; + Oscillator * oscs_l[NUM_OSCILLATORS]; + Oscillator * oscs_r[NUM_OSCILLATORS]; _n->m_pluginData = new oscPtr; From 57c85f49b7e0675a9a8704e4673543fedfd5eb96 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sat, 28 Jul 2018 14:09:00 +0200 Subject: [PATCH 093/445] MSVC: Fix ReverbSC --- plugins/CMakeLists.txt | 1 - plugins/ReverbSC/revsc.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 8c814736b..5c8000933 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -92,7 +92,6 @@ IF(MSVC) SET(MSVC_INCOMPATIBLE_PLUGINS LadspaEffect monstro - ReverbSC sid #VstEffect Xpressive diff --git a/plugins/ReverbSC/revsc.c b/plugins/ReverbSC/revsc.c index 35084c175..503052be3 100644 --- a/plugins/ReverbSC/revsc.c +++ b/plugins/ReverbSC/revsc.c @@ -72,7 +72,7 @@ int sp_revsc_init(sp_data *sp, sp_revsc *p) sp_auxdata_alloc(&p->aux, nBytes); nBytes = 0; for (i = 0; i < 8; i++) { - p->delayLines[i].buf = (p->aux.ptr) + nBytes; + p->delayLines[i].buf = ((char*) p->aux.ptr) + nBytes; init_delay_line(p, &p->delayLines[i], i); nBytes += delay_line_bytes_alloc(sp->sr, 1, i); } From b7c09974acc3644e6aaf1324c853f77cec152efa Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sat, 28 Jul 2018 14:20:36 +0200 Subject: [PATCH 094/445] MSVC: Fix Monstro instrument --- plugins/CMakeLists.txt | 1 - plugins/monstro/Monstro.cpp | 47 +++++++++++++++++++------------------ plugins/monstro/Monstro.h | 4 ++++ 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 5c8000933..8f751b10d 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -91,7 +91,6 @@ ENDIF("${PLUGIN_LIST}" STREQUAL "") IF(MSVC) SET(MSVC_INCOMPATIBLE_PLUGINS LadspaEffect - monstro sid #VstEffect Xpressive diff --git a/plugins/monstro/Monstro.cpp b/plugins/monstro/Monstro.cpp index 44a535100..baee242bb 100644 --- a/plugins/monstro/Monstro.cpp +++ b/plugins/monstro/Monstro.cpp @@ -100,6 +100,11 @@ MonstroSynth::MonstroSynth( MonstroInstrument * _i, NotePlayHandle * _nph ) : m_counter2r = 0; m_counter3l = 0; m_counter3r = 0; + + m_lfo[0].resize( m_parent->m_fpp ); + m_lfo[1].resize( m_parent->m_fpp ); + m_env[0].resize( m_parent->m_fpp ); + m_env[1].resize( m_parent->m_fpp ); } @@ -114,31 +119,31 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) // macros for modulating with env/lfos #define modulatefreq( car, mod ) \ modtmp = 0.0f; \ - if( mod##_e1 != 0.0f ) modtmp += env[0][f] * mod##_e1; \ - if( mod##_e2 != 0.0f ) modtmp += env[1][f] * mod##_e2; \ - if( mod##_l1 != 0.0f ) modtmp += lfo[0][f] * mod##_l1; \ - if( mod##_l2 != 0.0f ) modtmp += lfo[1][f] * mod##_l2; \ + if( mod##_e1 != 0.0f ) modtmp += m_env[0][f] * mod##_e1; \ + if( mod##_e2 != 0.0f ) modtmp += m_env[1][f] * mod##_e2; \ + if( mod##_l1 != 0.0f ) modtmp += m_lfo[0][f] * mod##_l1; \ + if( mod##_l2 != 0.0f ) modtmp += m_lfo[1][f] * mod##_l2; \ car = qBound( MIN_FREQ, car * powf( 2.0f, modtmp ), MAX_FREQ ); #define modulateabs( car, mod ) \ - if( mod##_e1 != 0.0f ) car += env[0][f] * mod##_e1; \ - if( mod##_e2 != 0.0f ) car += env[1][f] * mod##_e2; \ - if( mod##_l1 != 0.0f ) car += lfo[0][f] * mod##_l1; \ - if( mod##_l2 != 0.0f ) car += lfo[1][f] * mod##_l2; + if( mod##_e1 != 0.0f ) car += m_env[0][f] * mod##_e1; \ + if( mod##_e2 != 0.0f ) car += m_env[1][f] * mod##_e2; \ + if( mod##_l1 != 0.0f ) car += m_lfo[0][f] * mod##_l1; \ + if( mod##_l2 != 0.0f ) car += m_lfo[1][f] * mod##_l2; #define modulatephs( car, mod ) \ - if( mod##_e1 != 0.0f ) car += env[0][f] * mod##_e1; \ - if( mod##_e2 != 0.0f ) car += env[1][f] * mod##_e2; \ - if( mod##_l1 != 0.0f ) car += lfo[0][f] * mod##_l1; \ - if( mod##_l2 != 0.0f ) car += lfo[1][f] * mod##_l2; + if( mod##_e1 != 0.0f ) car += m_env[0][f] * mod##_e1; \ + if( mod##_e2 != 0.0f ) car += m_env[1][f] * mod##_e2; \ + if( mod##_l1 != 0.0f ) car += m_lfo[0][f] * mod##_l1; \ + if( mod##_l2 != 0.0f ) car += m_lfo[1][f] * mod##_l2; #define modulatevol( car, mod ) \ - if( mod##_e1 > 0.0f ) car *= ( 1.0f - mod##_e1 + mod##_e1 * env[0][f] ); \ - if( mod##_e1 < 0.0f ) car *= ( 1.0f + mod##_e1 * env[0][f] ); \ - if( mod##_e2 > 0.0f ) car *= ( 1.0f - mod##_e2 + mod##_e2 * env[1][f] ); \ - if( mod##_e2 < 0.0f ) car *= ( 1.0f + mod##_e2 * env[1][f] ); \ - if( mod##_l1 != 0.0f ) car *= ( 1.0f + mod##_l1 * lfo[0][f] ); \ - if( mod##_l2 != 0.0f ) car *= ( 1.0f + mod##_l2 * lfo[1][f] ); \ + if( mod##_e1 > 0.0f ) car *= ( 1.0f - mod##_e1 + mod##_e1 * m_env[0][f] ); \ + if( mod##_e1 < 0.0f ) car *= ( 1.0f + mod##_e1 * m_env[0][f] ); \ + if( mod##_e2 > 0.0f ) car *= ( 1.0f - mod##_e2 + mod##_e2 * m_env[1][f] ); \ + if( mod##_e2 < 0.0f ) car *= ( 1.0f + mod##_e2 * m_env[1][f] ); \ + if( mod##_l1 != 0.0f ) car *= ( 1.0f + mod##_l1 * m_lfo[0][f] ); \ + if( mod##_l2 != 0.0f ) car *= ( 1.0f + mod##_l2 * m_lfo[1][f] ); \ car = qBound( -MODCLIP, car, MODCLIP ); @@ -340,12 +345,8 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) float o3r_p = m_osc3r_phase + o3rpo; float sub; - // modulators - float lfo[2][ m_parent->m_fpp ]; - float env[2][ m_parent->m_fpp ]; - // render modulators: envelopes, lfos - updateModulators( &env[0][0], &env[1][0], &lfo[0][0], &lfo[1][0], _frames ); + updateModulators( m_env[0].data(), m_env[1].data(), m_lfo[0].data(), m_lfo[1].data(), _frames ); // begin for loop for( f_cnt_t f = 0; f < _frames; ++f ) diff --git a/plugins/monstro/Monstro.h b/plugins/monstro/Monstro.h index 2cf05f300..a8b186904 100644 --- a/plugins/monstro/Monstro.h +++ b/plugins/monstro/Monstro.h @@ -26,6 +26,7 @@ #ifndef MONSTRO_H #define MONSTRO_H +#include #include "Instrument.h" #include "InstrumentView.h" @@ -299,6 +300,9 @@ private: int m_counter2r; int m_counter3l; int m_counter3r; + + std::vector m_lfo[2]; + std::vector m_env[2]; }; class MonstroInstrument : public Instrument From d4f4500359f078c99f325551724514207f425c29 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sat, 28 Jul 2018 14:38:51 +0200 Subject: [PATCH 095/445] Fix compiler warning --- plugins/ReverbSC/revsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/ReverbSC/revsc.c b/plugins/ReverbSC/revsc.c index 503052be3..d9808963f 100644 --- a/plugins/ReverbSC/revsc.c +++ b/plugins/ReverbSC/revsc.c @@ -72,7 +72,7 @@ int sp_revsc_init(sp_data *sp, sp_revsc *p) sp_auxdata_alloc(&p->aux, nBytes); nBytes = 0; for (i = 0; i < 8; i++) { - p->delayLines[i].buf = ((char*) p->aux.ptr) + nBytes; + p->delayLines[i].buf = (SPFLOAT*) (((char*) p->aux.ptr) + nBytes); init_delay_line(p, &p->delayLines[i], i); nBytes += delay_line_bytes_alloc(sp->sr, 1, i); } From 1c5e374192da80d09b8c4078c316bc0de4214a01 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sat, 28 Jul 2018 14:44:51 +0200 Subject: [PATCH 096/445] MSVC: Fix Xpressive instrument --- plugins/CMakeLists.txt | 1 - plugins/Xpressive/CMakeLists.txt | 2 ++ plugins/Xpressive/Xpressive.cpp | 7 ------- plugins/Xpressive/Xpressive.h | 10 ++-------- 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 8f751b10d..b4a1081f6 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -93,7 +93,6 @@ IF(MSVC) LadspaEffect sid #VstEffect - Xpressive zynaddsubfx ) message(WARNING "Compiling with MSVC. The following plugins are not available: ${MSVC_INCOMPATIBLE_PLUGINS}") diff --git a/plugins/Xpressive/CMakeLists.txt b/plugins/Xpressive/CMakeLists.txt index 6745c71d5..366381e62 100644 --- a/plugins/Xpressive/CMakeLists.txt +++ b/plugins/Xpressive/CMakeLists.txt @@ -12,6 +12,8 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WERROR_FLAGS} -fexceptions") IF(LMMS_BUILD_WIN32 AND NOT MSVC) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj -Dexprtk_disable_enhanced_features") +ELSEIF(LMMS_BUILD_WIN32 AND MSVC) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") ENDIF() BUILD_PLUGIN(xpressive diff --git a/plugins/Xpressive/Xpressive.cpp b/plugins/Xpressive/Xpressive.cpp index 5822c9567..cb0293710 100644 --- a/plugins/Xpressive/Xpressive.cpp +++ b/plugins/Xpressive/Xpressive.cpp @@ -807,8 +807,6 @@ void XpressiveView::usrWaveClicked() { Engine::getSong()->setModified(); } -XpressiveHelpView* XpressiveHelpView::s_instance=0; - QString XpressiveHelpView::s_helpText= "O1, O2 - Two output waves. Panning is controled by PN1 and PN2.
" "W1, W2, W3 - Wave samples evaluated by expression. In these samples, t variable ranges [0,1).
" @@ -876,11 +874,6 @@ void XpressiveView::helpClicked() { } -__attribute__((destructor)) static void module_destroy() -{ - XpressiveHelpView::finalize(); -} - extern "C" { // necessary for getting instance out of shared lib diff --git a/plugins/Xpressive/Xpressive.h b/plugins/Xpressive/Xpressive.h index 9d4636ca5..ca80f2b78 100644 --- a/plugins/Xpressive/Xpressive.h +++ b/plugins/Xpressive/Xpressive.h @@ -206,22 +206,16 @@ class XpressiveHelpView: public QTextEdit public: static XpressiveHelpView* getInstance() { - if (!s_instance) - { - s_instance = new XpressiveHelpView(); - } - return s_instance; + static XpressiveHelpView instance; + return &instance; } static void finalize() { - if (s_instance) { delete s_instance; } } private: XpressiveHelpView(); - static XpressiveHelpView *s_instance; static QString s_helpText; - }; #endif From b9634fa672db3def2036c251cefacfa98c775b20 Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Sat, 28 Jul 2018 20:07:21 +0200 Subject: [PATCH 097/445] Setup Dialog - Fix bottom of letters cut off (#4483) --- 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 5063761e2..5e8f53c5c 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -188,7 +188,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : SLOT( setBufferSize( int ) ) ); m_bufSizeLbl = new QLabel( bufsize_tw ); - m_bufSizeLbl->setGeometry( 10, 40, 200, 24 ); + m_bufSizeLbl->setGeometry( 10, 40, 200, 32 ); setBufferSize( m_bufSizeSlider->value() ); QPushButton * bufsize_reset_btn = new QPushButton( From 792cf7a26291e26653ed94689731dbb8b3571d1a Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 29 Jul 2018 14:03:36 +0200 Subject: [PATCH 098/445] CMake: Fix FindFFTW pkg-config bug Remove the REQUIRED flag from pkg_check_modules for when pkg-config is available but cannot locate FFTW. --- cmake/modules/FindFFTW.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/modules/FindFFTW.cmake b/cmake/modules/FindFFTW.cmake index 9421c86cc..a7f7c153a 100644 --- a/cmake/modules/FindFFTW.cmake +++ b/cmake/modules/FindFFTW.cmake @@ -11,8 +11,8 @@ if(NOT FFTW_FIND_COMPONENTS) endif() if(PKG_CONFIG_FOUND) - pkg_check_modules(FFTW_PKG fftw>=3.0.0) - pkg_check_modules(FFTW3_PKG fftw3>=3.0.0) + pkg_check_modules(FFTW_PKG QUIET fftw>=3.0.0) + pkg_check_modules(FFTW3_PKG QUIET fftw3>=3.0.0) endif() find_path(FFTW_INCLUDE_DIR @@ -25,7 +25,7 @@ set(check_list) foreach(comp ${FFTW_FIND_COMPONENTS}) string(TOUPPER ${comp} COMP) if(PKG_CONFIG_FOUND) - pkg_check_modules(${COMP}_PKG REQUIRED ${comp}>=3.0.0) + pkg_check_modules(${COMP}_PKG QUIET ${comp}>=3.0.0) endif() find_library(${COMP}_LIBRARY From b67cfffe5f580a6af49e59b4f8faea48b0f8a845 Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Sun, 29 Jul 2018 15:34:46 +0200 Subject: [PATCH 099/445] InstrumentFunctions - Arpeggiator code refactoring (#4487) --- src/core/InstrumentFunctions.cpp | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/core/InstrumentFunctions.cpp b/src/core/InstrumentFunctions.cpp index a2aecb9c9..70e2c5e80 100644 --- a/src/core/InstrumentFunctions.cpp +++ b/src/core/InstrumentFunctions.cpp @@ -349,6 +349,8 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) return; } + // Set master note if not playing arp note or it will play as an ordinary note + _n->setMasterNote(); const int selected_arp = m_arpModel.value(); @@ -401,8 +403,6 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) if( m_arpModeModel.value() == SortMode && ( ( cur_frame / arp_frames ) % total_range ) / range != (f_cnt_t) _n->index() ) { - // Set master note if not playing arp note or it will play as an ordinary note - _n->setMasterNote(); // update counters frames_processed += arp_frames; cur_frame += arp_frames; @@ -414,9 +414,6 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) { if( 100 * ( (float) rand() / (float)( RAND_MAX + 1.0f ) ) < m_arpSkipModel.value() ) { - // Set master note to prevent the note to extend over skipped notes - // This may only be needed for lb302 - _n->setMasterNote(); // update counters frames_processed += arp_frames; cur_frame += arp_frames; @@ -517,13 +514,6 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) frames_processed += arp_frames; cur_frame += arp_frames; } - - // make sure note is handled as arp-base-note, even - // if we didn't add a sub-note so far - if( m_arpModeModel.value() != FreeMode ) - { - _n->setMasterNote(); - } } From b268abba45130b04a67c222a9e3bb161ab0f9fc3 Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Tue, 31 Jul 2018 05:04:20 +0200 Subject: [PATCH 100/445] Fix some formatting issues in translations (#4482) * Swedish translation formatting and fixes * German translation formatting * Czech translation formatting * Spanish translation formatting * Farsi translation formatting * French translation formatting * Italian translation formatting * Portuguese translation formatting * Galician translation formatting * Russian translation formatting * Ukrainian translation formatting * Japanese translation formatting --- data/locale/cs.ts | 4 ++-- data/locale/de.ts | 4 ++-- data/locale/es.ts | 8 ++++---- data/locale/fa.ts | 4 ++-- data/locale/fr.ts | 6 +++--- data/locale/gl.ts | 4 ++-- data/locale/it.ts | 8 ++++---- data/locale/ja.ts | 4 ++-- data/locale/pt.ts | 12 ++++++------ data/locale/ru.ts | 4 ++-- data/locale/sv.ts | 24 ++++++++++++------------ data/locale/uk.ts | 2 +- 12 files changed, 42 insertions(+), 42 deletions(-) diff --git a/data/locale/cs.ts b/data/locale/cs.ts index ebaee2c00..cf55f760f 100644 --- a/data/locale/cs.ts +++ b/data/locale/cs.ts @@ -1034,7 +1034,7 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis
FDBK - ZP. VAZBA + FDBK RATE @@ -2172,7 +2172,7 @@ Please make sure you have write permission to the file and the directory contain FDBK - ZP. VAZBA + FDBK NOISE diff --git a/data/locale/de.ts b/data/locale/de.ts index ccc4e4438..10f37d009 100644 --- a/data/locale/de.ts +++ b/data/locale/de.ts @@ -1030,7 +1030,7 @@ Wenn Sie daran interessiert sind LMMS in eine andere Sprache zu übersetzen oder DELAY - VERZÖGERUNG + DELAY FDBK @@ -2164,7 +2164,7 @@ Please make sure you have write permission to the file and the directory contain DELAY - VERZÖGERUNG + DELAY RATE diff --git a/data/locale/es.ts b/data/locale/es.ts index d50953d8e..d363900b8 100644 --- a/data/locale/es.ts +++ b/data/locale/es.ts @@ -700,11 +700,11 @@ Si te interesa traducir LMMS a otros idiomas o mejorar las traducciones existent BitcrushControlDialog IN - ENTRADA + IN OUT - SALIDA + OUT GAIN @@ -728,7 +728,7 @@ Si te interesa traducir LMMS a otros idiomas o mejorar las traducciones existent CLIP - RECORTE + CLIP Output Clip: @@ -1031,7 +1031,7 @@ Si te interesa traducir LMMS a otros idiomas o mejorar las traducciones existent DELAY - RETRASO + DELAY FDBK diff --git a/data/locale/fa.ts b/data/locale/fa.ts index 7593cb57e..17f010cd1 100644 --- a/data/locale/fa.ts +++ b/data/locale/fa.ts @@ -1218,7 +1218,7 @@ If you're interested in translating LMMS in another language or want to imp DECAY - محو-DECAY + DECAY Time: @@ -1360,7 +1360,7 @@ Right clicking will bring up a context menu where you can change the order in wh HOLD - نگهداری-HOLD + HOLD Hold: diff --git a/data/locale/fr.ts b/data/locale/fr.ts index ae72c61dd..65df2cf97 100644 --- a/data/locale/fr.ts +++ b/data/locale/fr.ts @@ -699,11 +699,11 @@ Si vous êtes intéressé par la traduction de LMMS dans une nouvelle langue ou BitcrushControlDialog IN - ENTRÉE + IN OUT - SORTIE + OUT GAIN @@ -2173,7 +2173,7 @@ Veuillez vérifier que vous avez les droits d'accès en écriture à ce fic DELAY - DE RETARD + DELAY RATE diff --git a/data/locale/gl.ts b/data/locale/gl.ts index 0956b9173..b427a057f 100644 --- a/data/locale/gl.ts +++ b/data/locale/gl.ts @@ -1468,7 +1468,7 @@ Ao premer co botón dereito aparece un menú de contexto no que se pode cambiar EnvelopeAndLfoView DEL - TMP REV + DEL Predelay: @@ -1540,7 +1540,7 @@ Ao premer co botón dereito aparece un menú de contexto no que se pode cambiar AMT - CANTIDADE + AMT Modulation amount: diff --git a/data/locale/it.ts b/data/locale/it.ts index f019943ab..e092c9d98 100644 --- a/data/locale/it.ts +++ b/data/locale/it.ts @@ -1033,7 +1033,7 @@ Se sei interessato a tradurre LMMS o vuoi migliorare una traduzione esistente, s DELAY - RITARDO + DELAY FDBK @@ -1041,7 +1041,7 @@ Se sei interessato a tradurre LMMS o vuoi migliorare una traduzione esistente, s RATE - FREQUENZA + RATE AMNT @@ -2168,11 +2168,11 @@ Si prega di controllare i permessi di scrittura sul file e la cartella che lo co DELAY - RITARDO + DELAY RATE - FREQUENZA + RATE Rate: diff --git a/data/locale/ja.ts b/data/locale/ja.ts index 4b355e2c3..258baeb09 100644 --- a/data/locale/ja.ts +++ b/data/locale/ja.ts @@ -3277,7 +3277,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri PAN - パニング + PAN MIDI @@ -5984,7 +5984,7 @@ Reason: "%2" PAN - パニング + PAN diff --git a/data/locale/pt.ts b/data/locale/pt.ts index 58a5318e4..1980df7f7 100644 --- a/data/locale/pt.ts +++ b/data/locale/pt.ts @@ -80,7 +80,7 @@ Esteban Viveros LEFT - ESQUERDA + LEFT Left gain: @@ -88,7 +88,7 @@ Esteban Viveros RIGHT - DIREITA + RIGHT Right gain: @@ -701,11 +701,11 @@ Esteban Viveros BitcrushControlDialog IN - DENTRO + IN OUT - FORA + OUT GAIN @@ -3000,7 +3000,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri VELOCITY - INTENSIDADE + VELOCITY ENABLE MIDI OUTPUT @@ -7776,7 +7776,7 @@ Por favor certifique-se que você tem permissões de leitura para o arquivo e pa RELEASE - LANÇAMENTO + RELEASE Peak release time: diff --git a/data/locale/ru.ts b/data/locale/ru.ts index 4ef85094a..b26a4e82f 100644 --- a/data/locale/ru.ts +++ b/data/locale/ru.ts @@ -703,11 +703,11 @@ Oe Ai <oeai/at/symbiants/dot/com> BitcrushControlDialog IN - ВХОД + IN OUT - ВЫХОД + OUT GAIN diff --git a/data/locale/sv.ts b/data/locale/sv.ts index ec36538f0..29f99f555 100644 --- a/data/locale/sv.ts +++ b/data/locale/sv.ts @@ -1063,7 +1063,7 @@ If you're interested in translating LMMS in another language or want to imp FREQ - FREKV. + FREQ Cutoff frequency @@ -1443,7 +1443,7 @@ Right clicking will bring up a context menu where you can change the order in wh Freq x 100 - Frekv. x 100 + Freq x 100 Modulate Env-Amount @@ -1454,7 +1454,7 @@ Right clicking will bring up a context menu where you can change the order in wh EnvelopeAndLfoView DEL - RADERA + DEL Predelay: @@ -1526,7 +1526,7 @@ Right clicking will bring up a context menu where you can change the order in wh AMT - MÄNGD + AMT Modulation amount: @@ -1590,7 +1590,7 @@ Right clicking will bring up a context menu where you can change the order in wh FREQ x 100 - FREKV. x 100 + FREQ x 100 Click here if the frequency of this LFO should be multiplied by 100. @@ -1883,7 +1883,7 @@ Right clicking will bring up a context menu where you can change the order in wh Freq: - Frekv.: + Freq: @@ -3197,7 +3197,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri FREQ - FREKV. + FREQ cutoff frequency: @@ -3275,7 +3275,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri PAN - PANORERA + PAN MIDI @@ -3322,7 +3322,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri PAN - PANORERA + PAN Pitch @@ -5982,14 +5982,14 @@ Orsak: "%2" PAN - PANORERA + PAN SetupDialog Setup LMMS - Ställ in LMMS + Inställningar General settings @@ -6077,7 +6077,7 @@ Orsak: "%2" STK rawwave directory - Katalog för STK rå-vågform + Katalog för STK vågformer Default Soundfont File diff --git a/data/locale/uk.ts b/data/locale/uk.ts index 583dbf136..88d92b82b 100644 --- a/data/locale/uk.ts +++ b/data/locale/uk.ts @@ -1341,7 +1341,7 @@ If you're interested in translating LMMS in another language or want to imp DECAY - ЗГАСАННЯ + DECAY Time: From e07f9a3b648d8ce168f247217509677ecd38811d Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 1 Aug 2018 14:35:16 +0900 Subject: [PATCH 101/445] Don't use dummy controllers for connections if not loading projects (#4493) Remove the need of ControllerConnection::finalizeConnections when not loading projects. Fix ZynAddSubFX knob disconnection when exporting. --- plugins/LadspaEffect/LadspaEffect.cpp | 3 --- plugins/zynaddsubfx/ZynAddSubFx.cpp | 2 -- src/core/ControllerConnection.cpp | 18 ++++++++++++------ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/plugins/LadspaEffect/LadspaEffect.cpp b/plugins/LadspaEffect/LadspaEffect.cpp index 72b195314..a274bef6d 100644 --- a/plugins/LadspaEffect/LadspaEffect.cpp +++ b/plugins/LadspaEffect/LadspaEffect.cpp @@ -121,9 +121,6 @@ void LadspaEffect::changeSampleRate() // the IDs of re-created controls have been saved and now need to be // resolved again AutomationPattern::resolveAllIDs(); - - // make sure, connections are ok - ControllerConnection::finalizeConnections(); } diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index 8c1da751f..adc337542 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -645,8 +645,6 @@ void ZynAddSubFxView::toggleUI() connect( model->m_remotePlugin, SIGNAL( clickedCloseButton() ), m_toggleUIButton, SLOT( toggle() ) ); } - - ControllerConnection::finalizeConnections(); } } diff --git a/src/core/ControllerConnection.cpp b/src/core/ControllerConnection.cpp index 4f04cbc20..af398d389 100644 --- a/src/core/ControllerConnection.cpp +++ b/src/core/ControllerConnection.cpp @@ -204,16 +204,22 @@ void ControllerConnection::loadSettings( const QDomElement & _this ) } else { - if( _this.attribute( "id", "-1" ).toInt() >= 0 ) - { - m_controllerId = _this.attribute( "id" ).toInt(); - } - else + m_controllerId = _this.attribute( "id", "-1" ).toInt(); + if( m_controllerId < 0 ) { qWarning( "controller index invalid\n" ); m_controllerId = -1; } - m_controller = Controller::create( Controller::DummyController, NULL ); + + if (!Engine::getSong()->isLoadingProject() && m_controllerId != -1) + { + setController( Engine::getSong()-> + controllers().at( m_controllerId ) ); + } + else + { + m_controller = Controller::create( Controller::DummyController, NULL ); + } } } From c44bc4eb7f802c7337ee7f272b8cd28cf2eb6c83 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Thu, 2 Aug 2018 21:20:25 +0200 Subject: [PATCH 102/445] CMake: Fix missing space in linker flags Fixes #4518, a regression from a7b0c99242cf7ce6b513df89bd3b37ce1408b833 --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0fcdd04cd..cd40ad747 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -196,7 +196,7 @@ IF(NOT MSVC) # ENABLE_EXPORTS property has no effect in some MSYS2 configurations. # Add the linker flag manually to create liblmms.dll.a import library SET_PROPERTY(TARGET lmms - APPEND_STRING PROPERTY LINK_FLAGS -Wl,--out-implib,liblmms.dll.a + APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--out-implib,liblmms.dll.a" ) ENDIF() From b5dc70c20a3c4d8881bfd1bfc119b2a2581b706a Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Sun, 5 Aug 2018 23:53:49 -0400 Subject: [PATCH 103/445] Fix AppImage shim launcher Due to upstream change in linuxdeployqt --- cmake/linux/package_linux.sh.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index 61afe35a0..99c5aebc1 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -55,6 +55,7 @@ echo -e "\nWriting verbose output to \"${LOGFILE}\"" export PATH="$(pwd -P)/squashfs-root/usr/bin:$(dirname "@QT_QMAKE_EXECUTABLE@")":$PATH # Fetch portable linuxdeployqt if cache is older than $DAYSOLD +APPIMAGETOOL="squashfs-root/usr/bin/appimagetool" echo -e "\nDownloading linuxdeployqt to ${LINUXDEPLOYQT}..." mkdir -p "$HOME/bin" DAYSOLD=2 @@ -69,7 +70,6 @@ elif ! find "$LINUXDEPLOYQT" -mtime -$DAYSOLD 2>/dev/null|grep -q "." > /dev/nul touch "$LINUXDEPLOYQT" success "Downloaded $LINUXDEPLOYQT" "$LINUXDEPLOYQT" --appimage-extract > /dev/null 2>&1 - APPIMAGETOOL="squashfs-root/usr/bin/appimagetool" success "Extracted $APPIMAGETOOL" else skipped "$LINUXDEPLOYQT is less than $DAYSOLD days old" @@ -181,6 +181,10 @@ if [ -e "${APPDIR}/usr/lib/libjack.so.0" ]; then mv "${APPDIR}/usr/lib/libjack.so.0" "${APPDIR}usr/lib/lmms/optional/" fi +# Point the AppRun to the shim launcher +rm -f "${APPDIR}/AppRun" +ln -sr "${APPDIR}/usr/bin/lmms" "${APPDIR}/AppRun" + # Create AppImage echo -e "\nFinishing the AppImage..." echo -e "\n\n>>>>> appimagetool" >> "$LOGFILE" From 2ecc8bb4fafd112cbe9205b5c78ba969646400c9 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Tue, 7 Aug 2018 15:26:58 -0400 Subject: [PATCH 104/445] Add CMake 2 support (#4530) Partially reverts d599955 --- cmake/modules/MinGWCrossCompile.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/modules/MinGWCrossCompile.cmake b/cmake/modules/MinGWCrossCompile.cmake index 50ea72900..90dd7c607 100644 --- a/cmake/modules/MinGWCrossCompile.cmake +++ b/cmake/modules/MinGWCrossCompile.cmake @@ -51,6 +51,10 @@ ELSE() SET(STRIP ${MINGW_TOOL_PREFIX}strip) SET(WINDRES ${MINGW_TOOL_PREFIX}windres) SET(ENV{PKG_CONFIG} ${MINGW_TOOL_PREFIX}pkg-config) + IF(CMAKE_VERSION LESS 3) + SET(PKG_CONFIG_EXECUTABLE $ENV{PKG_CONFIG}) + SET(PKG_CONFIG_FOUND TRUE) + ENDIF() # Search for programs in the build host directories SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) From 0cddc469bca910ad4b3e1fffdb9b798ebde27632 Mon Sep 17 00:00:00 2001 From: Ivo Wetzel Date: Thu, 16 Aug 2018 05:05:50 +0200 Subject: [PATCH 105/445] Fix Freeboy noise channel playback (#4538) Writing the enable bit to `FF23` causes the noise oscillator to start outputting samples and writing the other registers (including the one for the SRW value) during the time the oscillator is active has undefined behaviour. In order for `GB_apu` to correctly generate samples when the LSFR width is set to `7`, the trigger write to `0xff23` must happen after all other writes. --- plugins/papu/papu_instrument.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/papu/papu_instrument.cpp b/plugins/papu/papu_instrument.cpp index b555310a0..b9c1b28ae 100644 --- a/plugins/papu/papu_instrument.cpp +++ b/plugins/papu/papu_instrument.cpp @@ -276,9 +276,6 @@ void papuInstrument::playNote( NotePlayHandle * _n, data += m_ch4SweepStepLengthModel.value(); papu->write_register( 0xff21, data ); - //channel 4 init - papu->write_register( 0xff23, 128 ); - _n->m_pluginData = papu; } @@ -380,6 +377,10 @@ void papuInstrument::playNote( NotePlayHandle * _n, data = data << 3; data += ropt; papu->write_register( 0xff22, data ); + + //channel 4 init + papu->write_register( 0xff23, 128 ); + } int const buf_size = 2048; From 160488c0963f67b13013dc6e198b2f7d42530c64 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Mon, 30 Jul 2018 20:00:08 +0200 Subject: [PATCH 106/445] Make the oscilloscope colors available as properties Make the oscilloscope colors available as properties so that they can be changed via style sheets. Adjust the existing styles to use the colors that have been hard coded previously. Cleanup the paintEvent method of VisualizationWidget, e.g. by extracting a method to determine the color to use for the line and by pulling variables to the place where they are used. Fix some Clang warnings. --- data/themes/classic/style.css | 3 + data/themes/default/style.css | 3 + include/VisualizationWidget.h | 17 +++++ src/gui/widgets/VisualizationWidget.cpp | 89 +++++++++++++++++-------- 4 files changed, 83 insertions(+), 29 deletions(-) diff --git a/data/themes/classic/style.css b/data/themes/classic/style.css index 55f82e4b3..112d8f05c 100644 --- a/data/themes/classic/style.css +++ b/data/themes/classic/style.css @@ -157,6 +157,9 @@ GroupBox { VisualizationWidget { background: none; border: none; + qproperty-normalColor: rgb(71, 253, 133); + qproperty-warningColor: rgb(255, 192, 64); + qproperty-clippingColor: rgb(255, 64, 64); } /* main toolbar cpu load widget - this can have transparent bg now */ diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 8493abbf3..cd74c349d 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -176,6 +176,9 @@ GroupBox { VisualizationWidget { background: none; border: none; + qproperty-normalColor: rgb(71, 253, 133); + qproperty-warningColor: rgb(255, 192, 64); + qproperty-clippingColor: rgb(255, 64, 64); } /* main toolbar cpu load widget - this can have transparent bg now */ diff --git a/include/VisualizationWidget.h b/include/VisualizationWidget.h index 4d73f052d..a178b1ad8 100644 --- a/include/VisualizationWidget.h +++ b/include/VisualizationWidget.h @@ -36,6 +36,9 @@ class VisualizationWidget : public QWidget { Q_OBJECT public: + Q_PROPERTY( QColor normalColor READ normalColor WRITE setNormalColor ) + Q_PROPERTY( QColor warningColor READ warningColor WRITE setWarningColor ) + Q_PROPERTY( QColor clippingColor READ clippingColor WRITE setClippingColor ) enum visualizationTypes { Simple // add more here @@ -47,6 +50,15 @@ public: void setActive( bool _active ); + QColor const & normalColor() const; + void setNormalColor(QColor const & normalColor); + + QColor const & warningColor() const; + void setWarningColor(QColor const & warningColor); + + QColor const & clippingColor() const; + void setClippingColor(QColor const & clippingColor); + protected: virtual void paintEvent( QPaintEvent * _pe ); @@ -56,6 +68,8 @@ protected: protected slots: void updateAudioBuffer( const surroundSampleFrame * buffer ); +private: + QColor const & determineLineColor(float level) const; private: QPixmap s_background; @@ -64,6 +78,9 @@ private: sampleFrame * m_buffer; bool m_active; + QColor m_normalColor; + QColor m_warningColor; + QColor m_clippingColor; } ; #endif diff --git a/src/gui/widgets/VisualizationWidget.cpp b/src/gui/widgets/VisualizationWidget.cpp index 1fd4e4c00..3b484ca0a 100644 --- a/src/gui/widgets/VisualizationWidget.cpp +++ b/src/gui/widgets/VisualizationWidget.cpp @@ -43,7 +43,10 @@ VisualizationWidget::VisualizationWidget( const QPixmap & _bg, QWidget * _p, QWidget( _p ), s_background( _bg ), m_points( new QPointF[Engine::mixer()->framesPerPeriod()] ), - m_active( false ) + m_active( false ), + m_normalColor(71, 253, 133), + m_warningColor(255, 192, 64), + m_clippingColor(255, 64, 64) { setFixedSize( s_background.width(), s_background.height() ); setAttribute( Qt::WA_OpaquePaintEvent, true ); @@ -110,6 +113,35 @@ void VisualizationWidget::setActive( bool _active ) } +QColor const & VisualizationWidget::normalColor() const +{ + return m_normalColor; +} + +void VisualizationWidget::setNormalColor(QColor const & normalColor) +{ + m_normalColor = normalColor; +} + +QColor const & VisualizationWidget::warningColor() const +{ + return m_warningColor; +} + +void VisualizationWidget::setWarningColor(QColor const & warningColor) +{ + m_warningColor = warningColor; +} + +QColor const & VisualizationWidget::clippingColor() const +{ + return m_clippingColor; +} + +void VisualizationWidget::setClippingColor(QColor const & clippingColor) +{ + m_clippingColor = clippingColor; +} void VisualizationWidget::paintEvent( QPaintEvent * ) @@ -123,13 +155,6 @@ void VisualizationWidget::paintEvent( QPaintEvent * ) Mixer const * mixer = Engine::mixer(); float master_output = mixer->masterGain(); - int w = width()-4; - const float half_h = -( height() - 6 ) / 3.0 * master_output - 1; - int x_base = 2; - const float y_base = height()/2 - 0.5f; - -// p.setClipRect( 2, 2, w, height()-4 ); - const fpp_t frames = mixer->framesPerPeriod(); float peakLeft; @@ -137,35 +162,27 @@ void VisualizationWidget::paintEvent( QPaintEvent * ) mixer->getPeakValues( m_buffer, frames, peakLeft, peakRight ); const float max_level = qMax( peakLeft, peakRight ); - // and set color according to that... - if( max_level * master_output < 0.9 ) - { - p.setPen( QColor( 71, 253, 133 ) ); - } - else if( max_level * master_output < 1.0 ) - { - p.setPen( QColor( 255, 192, 64 ) ); - } - else - { - p.setPen( QColor( 255, 64, 64 ) ); - } + // Set the color of the line according to the maximum level + float const maxLevelWithAppliedMasterGain = max_level * master_output; + p.setPen(QPen(determineLineColor(maxLevelWithAppliedMasterGain), 0.7)); - p.setPen( QPen( p.pen().color(), 0.7 ) ); - - const float xd = (float) w / frames; p.setRenderHint( QPainter::Antialiasing ); // now draw all that stuff + int w = width() - 4; + const qreal xd = static_cast(w) / frames; + const qreal half_h = -( height() - 6 ) / 3.0 * static_cast(master_output) - 1; + int x_base = 2; + const qreal y_base = height() / 2 - 0.5; + for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch ) { for( int frame = 0; frame < frames; ++frame ) { + sample_t const clippedSample = Mixer::clip(m_buffer[frame][ch]); m_points[frame] = QPointF( - x_base + (float) frame * xd, - y_base + ( Mixer::clip( - m_buffer[frame][ch] ) * - half_h ) ); + x_base + static_cast(frame) * xd, + y_base + ( static_cast(clippedSample) * half_h ) ); } p.drawPolyline( m_points, frames ); } @@ -190,7 +207,21 @@ void VisualizationWidget::mousePressEvent( QMouseEvent * _me ) } - +QColor const & VisualizationWidget::determineLineColor(float level) const +{ + if( level < 0.9f ) + { + return normalColor(); + } + else if( level < 1.0f ) + { + return warningColor(); + } + else + { + return clippingColor(); + } +} From 8d00e90322710ed3dd8ce1a4bdcc83f18b64d59b Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Mon, 30 Jul 2018 20:05:48 +0200 Subject: [PATCH 107/445] Remove peak value references from Mixer::getPeakValues Adjust Mixer::getPeakValues so client do not have to allocate the variables that will store the peak values. Adjust both existing clients: FxMixer and VisualizationWidget. --- include/Mixer.h | 8 +++++++- src/core/FxMixer.cpp | 8 +++----- src/core/Mixer.cpp | 8 +++++--- src/gui/widgets/VisualizationWidget.cpp | 6 ++---- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/include/Mixer.h b/include/Mixer.h index bd057753a..743547b0f 100644 --- a/include/Mixer.h +++ b/include/Mixer.h @@ -273,7 +273,13 @@ public: } - void getPeakValues( sampleFrame * _ab, const f_cnt_t _frames, float & peakLeft, float & peakRight ) const; + struct StereoSample + { + StereoSample(sample_t _left, sample_t _right) : left(_left), right(_right) {} + sample_t left; + sample_t right; + }; + StereoSample getPeakValues(sampleFrame * _ab, const f_cnt_t _frames) const; bool criticalXRuns() const; diff --git a/src/core/FxMixer.cpp b/src/core/FxMixer.cpp index 51e66939a..0e5f200d6 100644 --- a/src/core/FxMixer.cpp +++ b/src/core/FxMixer.cpp @@ -170,11 +170,9 @@ void FxChannel::doProcessing() m_stillRunning = m_fxChain.processAudioBuffer( m_buffer, fpp, m_hasInput ); - float peakLeft = 0.; - float peakRight = 0.; - Engine::mixer()->getPeakValues( m_buffer, fpp, peakLeft, peakRight ); - m_peakLeft = qMax( m_peakLeft, peakLeft * v ); - m_peakRight = qMax( m_peakRight, peakRight * v ); + Mixer::StereoSample peakSamples = Engine::mixer()->getPeakValues(m_buffer, fpp); + m_peakLeft = qMax( m_peakLeft, peakSamples.left * v ); + m_peakRight = qMax( m_peakRight, peakSamples.right * v ); } else { diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index 07a9d592f..f34f9dbbc 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -534,10 +534,10 @@ void Mixer::clearInternal() -void Mixer::getPeakValues( sampleFrame * _ab, const f_cnt_t _frames, float & peakLeft, float & peakRight ) const +Mixer::StereoSample Mixer::getPeakValues(sampleFrame * _ab, const f_cnt_t _frames) const { - peakLeft = 0.0f; - peakRight = 0.0f; + sample_t peakLeft = 0.0f; + sample_t peakRight = 0.0f; for( f_cnt_t f = 0; f < _frames; ++f ) { @@ -553,6 +553,8 @@ void Mixer::getPeakValues( sampleFrame * _ab, const f_cnt_t _frames, float & pea peakRight = absRight; } } + + return StereoSample(peakLeft, peakRight); } diff --git a/src/gui/widgets/VisualizationWidget.cpp b/src/gui/widgets/VisualizationWidget.cpp index 00521f7bc..df0012816 100644 --- a/src/gui/widgets/VisualizationWidget.cpp +++ b/src/gui/widgets/VisualizationWidget.cpp @@ -131,10 +131,8 @@ void VisualizationWidget::paintEvent( QPaintEvent * ) const fpp_t frames = mixer->framesPerPeriod(); - float peakLeft; - float peakRight; - mixer->getPeakValues( m_buffer, frames, peakLeft, peakRight ); - const float max_level = qMax( peakLeft, peakRight ); + Mixer::StereoSample peakValues = mixer->getPeakValues(m_buffer, frames); + const float max_level = qMax( peakValues.left, peakValues.right ); // and set color according to that... if( max_level * master_output < 0.9 ) From 7f541a544e34790fd23c52de3afdac0b73124386 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 22 Aug 2018 20:17:56 +0900 Subject: [PATCH 108/445] Don't try to clear null buffer in NotePlayHandle::play (#4545) This is a workaround for rare crashes when changing the tempo while playing notes with stacking and/or arpeggio. When playing the master note, _working_buffer is null. Tempo change causes false positive in the check because NotePlayHandle::resize changes m_totalFramesPlayed. Thanks to 6fc4577f102e5bb60cc246a426fb9ed8b4ac3be9, we can safely drop the memset call. --- src/core/NotePlayHandle.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/core/NotePlayHandle.cpp b/src/core/NotePlayHandle.cpp index 11f71d8f1..9dd29fe32 100644 --- a/src/core/NotePlayHandle.cpp +++ b/src/core/NotePlayHandle.cpp @@ -238,13 +238,6 @@ void NotePlayHandle::play( sampleFrame * _working_buffer ) // decreasing release of an instrument-track while the note is active if( framesLeft() > 0 ) { - // clear offset frames if we're at the first period - // skip for single-streamed instruments, because in their case NPH::play() could be called from an IPH without a buffer argument - // ... also, they don't actually render the sound in NPH's, which is an even better reason to skip... - if( m_totalFramesPlayed == 0 && ! ( m_instrumentTrack->instrument()->flags() & Instrument::IsSingleStreamed ) ) - { - memset( _working_buffer, 0, sizeof( sampleFrame ) * offset() ); - } // play note! m_instrumentTrack->playNote( this, _working_buffer ); } From 763c08b8b65d2bb72628878a6c78b7328d34b4d9 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Sat, 25 Aug 2018 08:51:29 +0900 Subject: [PATCH 109/445] Fix typo in previous merge --- 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 386ba5c1d..31fa8ad53 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -57,7 +57,7 @@ PATH="$(pwd -P)/squashfs-root/usr/bin:$(dirname "@QT_QMAKE_EXECUTABLE@")":$PATH export PATH # Fetch portable linuxdeployqt if not in PATH -APPIMAGETOOL="squashfs-root/usr/bin/appimagetool"= +APPIMAGETOOL="squashfs-root/usr/bin/appimagetool" echo -e "\nDownloading linuxdeployqt to ${LINUXDEPLOYQT}..." if env -i which linuxdeployqt > /dev/null 2>&1; then skipped "System already provides this utility" From a0cbcb6ec4f92b15ede784ffcc078d41ae042d8b Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Sat, 25 Aug 2018 15:29:40 +0900 Subject: [PATCH 110/445] Remove Qt temporary files after loading ZynAddSubFX settings (#4551) --- plugins/zynaddsubfx/ZynAddSubFx.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index adc337542..49a97d35e 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -240,7 +240,6 @@ void ZynAddSubFxInstrument::loadSettings( const QDomElement & _this ) doc.appendChild( doc.importNode( data, true ) ); QTemporaryFile tf; - tf.setAutoRemove( false ); if( tf.open() ) { QByteArray a = doc.toString( 0 ).toUtf8(); From 4bb6586c66fdeb0ef2f84667958d340a8355c5fe Mon Sep 17 00:00:00 2001 From: Tobias Kortkamp Date: Mon, 27 Aug 2018 22:19:23 +0200 Subject: [PATCH 111/445] Allow building with sndio support on more systems than just OpenBSD (#4486) Sndio also supports FreeBSD and Linux. --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index da5be324a..8be2f701f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,7 @@ OPTION(WANT_MP3LAME "Include MP3/Lame support" ON) OPTION(WANT_OGGVORBIS "Include OGG/Vorbis support" ON) OPTION(WANT_PULSEAUDIO "Include PulseAudio support" ON) OPTION(WANT_PORTAUDIO "Include PortAudio support" ON) +OPTION(WANT_SNDIO "Include sndio support" ON) OPTION(WANT_SOUNDIO "Include libsoundio support" ON) OPTION(WANT_SDL "Include SDL (Simple DirectMedia Layer) support" ON) OPTION(WANT_SF2 "Include SoundFont2 player plugin" ON) @@ -86,6 +87,7 @@ IF(LMMS_BUILD_WIN32) SET(WANT_JACK OFF) SET(WANT_PULSEAUDIO OFF) SET(WANT_PORTAUDIO OFF) + SET(WANT_SNDIO OFF) SET(WANT_SOUNDIO OFF) SET(WANT_WINMM ON) SET(LMMS_HAVE_WINMM TRUE) @@ -428,7 +430,7 @@ IF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE OR LMMS_BUILD_OPENBSD) FIND_PACKAGE(Threads) ENDIF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE OR LMMS_BUILD_OPENBSD) -IF(LMMS_BUILD_OPENBSD) +IF(WANT_SNDIO) FIND_PACKAGE(Sndio) IF(SNDIO_FOUND) SET(LMMS_HAVE_SNDIO TRUE) @@ -436,7 +438,7 @@ IF(LMMS_BUILD_OPENBSD) ELSE() SET(STATUS_SNDIO "") ENDIF(SNDIO_FOUND) -ENDIF(LMMS_BUILD_OPENBSD) +ENDIF(WANT_SNDIO) # check for WINE IF(WANT_VST) From a1415a374b867f552d928b0f4b137ce13a85e1b1 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Sat, 1 Sep 2018 14:04:48 +0900 Subject: [PATCH 112/445] Fix AppVeyor CI failure due to Vcpkg Adds --recurse option to allow rebuilding dependencies --- .appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index a12ea1260..350e4351f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -8,7 +8,7 @@ environment: matrix: - compiler: msvc install: - - vcpkg install --triplet %PLATFORM%-windows fftw3 libsamplerate libsndfile sdl2 + - vcpkg install --triplet %PLATFORM%-windows --recurse fftw3 libsamplerate libsndfile sdl2 - nuget install clcache -Version 4.1.0 build_script: - cd %APPVEYOR_BUILD_FOLDER% From 6f32c962b48911564b0443628b4700edb82c37ce Mon Sep 17 00:00:00 2001 From: Lukas W Date: Mon, 3 Sep 2018 12:39:23 +0200 Subject: [PATCH 113/445] Fix invisible editors on project load by validating size (#4502) --- src/gui/MainWindow.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 6ff55f06f..c047bf96c 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -802,7 +802,10 @@ void MainWindow::restoreWidgetState( QWidget * _w, const QDomElement & _de ) // first restore the window, as attempting to resize a maximized window causes graphics glitching _w->setWindowState( _w->windowState() & ~(Qt::WindowMaximized | Qt::WindowMinimized) ); - _w->resize( r.size() ); + // Check isEmpty() to work around corrupt project files with empty size + if ( ! r.size().isEmpty() ) { + _w->resize( r.size() ); + } _w->move( r.topLeft() ); // set the window to its correct minimized/maximized/restored state From de427bbcf8a9dc012afdf1a4e65a5cd1d3dbe466 Mon Sep 17 00:00:00 2001 From: DomClark Date: Tue, 14 Aug 2018 20:04:59 +0100 Subject: [PATCH 114/445] Suspend plugin when changing sample rate/buffer size Some plugins ignore updates to these values if they're changed while the plugin is in a "resumed" state, resulting in incorrect tuning after a change of sample rate. --- plugins/vst_base/RemoteVstPlugin.cpp | 36 ++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 127036cd0..5a73bd10e 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -147,6 +147,7 @@ public: // set given sample-rate for plugin virtual void updateSampleRate() { + SuspendPlugin suspend( this ); pluginDispatch( effSetSampleRate, 0, 0, NULL, (float) sampleRate() ); } @@ -154,9 +155,20 @@ public: // set given buffer-size for plugin virtual void updateBufferSize() { + SuspendPlugin suspend( this ); pluginDispatch( effSetBlockSize, 0, bufferSize() ); } + void setResumed( bool resumed ) + { + m_resumed = resumed; + pluginDispatch( effMainsChanged, 0, resumed ? 1 : 0 ); + } + + inline bool isResumed() const + { + return m_resumed; + } inline bool isInitialized() const { @@ -309,6 +321,24 @@ private: ClosePlugin } ; + struct SuspendPlugin { + SuspendPlugin( RemoteVstPlugin * plugin ) : + m_plugin( plugin ), + m_resumed( plugin->isResumed() ) + { + if( m_resumed ) { m_plugin->setResumed( false ); } + } + + ~SuspendPlugin() + { + if( m_resumed ) { m_plugin->setResumed( true ); } + } + + private: + RemoteVstPlugin * m_plugin; + bool m_resumed; + }; + // callback used by plugin for being able to communicate with it's host static intptr_t hostCallback( AEffect * _effect, int32_t _opcode, int32_t _index, intptr_t _value, @@ -339,6 +369,7 @@ private: int m_windowHeight; bool m_initialized; + bool m_resumed; bool m_processing; @@ -390,6 +421,7 @@ RemoteVstPlugin::RemoteVstPlugin( const char * socketPath ) : m_windowWidth( 0 ), m_windowHeight( 0 ), m_initialized( false ), + m_resumed( false ), m_processing( false ), m_messageList(), m_shouldGiveIdle( false ), @@ -470,7 +502,7 @@ RemoteVstPlugin::RemoteVstPlugin( const char * socketPath ) : RemoteVstPlugin::~RemoteVstPlugin() { destroyEditor(); - pluginDispatch( effMainsChanged, 0, 0 ); + setResumed( false ); pluginDispatch( effClose ); #ifndef USE_QT_SHMEM // detach shared memory segment @@ -648,7 +680,7 @@ void RemoteVstPlugin::init( const std::string & _plugin_file ) pluginDispatch( effSetProgram, 0, 0 ); */ // request rate and blocksize - pluginDispatch( effMainsChanged, 0, 1 ); + setResumed( true ); debugMessage( "creating editor\n" ); initEditor(); From cc2ae66540cdf62a9f6b9d4daf5cb4b82d229fa3 Mon Sep 17 00:00:00 2001 From: DomClark Date: Tue, 14 Aug 2018 20:52:48 +0100 Subject: [PATCH 115/445] Fix hang when updateInOutCount called from processReplacing Ignore requests to change the I/O count from within processReplacing and print a warning instead; the shared memory is in use so it can't be reallocated. Add a special case to return immediately if the I/O count hasn't changed at all; this will prevent spurious warnings when the plugin is only updating the latency and should reduce unnecessary reallocations in general. --- plugins/vst_base/RemoteVstPlugin.cpp | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 5a73bd10e..e0b51381e 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -118,6 +118,7 @@ class RemoteVstPlugin; RemoteVstPlugin * __plugin = NULL; HWND __MessageHwnd = NULL; +DWORD __processingThreadId = 0; @@ -251,7 +252,7 @@ public: } // has to be called as soon as input- or output-count changes - void updateInOutCount(); + int updateInOutCount(); inline void lockShm() { @@ -1438,8 +1439,21 @@ void RemoteVstPlugin::loadChunkFromFile( const std::string & _file, int _len ) -void RemoteVstPlugin::updateInOutCount() +int RemoteVstPlugin::updateInOutCount() { + if( inputCount() == RemotePluginClient::inputCount() && + outputCount() == RemotePluginClient::outputCount() ) + { + return 1; + } + + if( GetCurrentThreadId() == __processingThreadId ) + { + debugMessage( "Plugin requested I/O change from processing " + "thread. Request denied; stability may suffer.\n" ); + return 0; + } + lockShm(); setShmIsValid( false ); @@ -1467,6 +1481,8 @@ void RemoteVstPlugin::updateInOutCount() { m_outputs = new float * [outputCount()]; } + + return 1; } @@ -1611,10 +1627,9 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode, return 0; case audioMasterIOChanged: - __plugin->updateInOutCount(); SHOW_CALLBACK( "amc: audioMasterIOChanged\n" ); - // numInputs and/or numOutputs has changed - return 0; + // numInputs, numOutputs, and/or latency has changed + return __plugin->updateInOutCount(); #ifdef OLD_VST_SDK case audioMasterWantMidi: @@ -1897,6 +1912,8 @@ void RemoteVstPlugin::processUIThreadMessages() DWORD WINAPI RemoteVstPlugin::processingThread( LPVOID _param ) { + __processingThreadId = GetCurrentThreadId(); + RemoteVstPlugin * _this = static_cast( _param ); RemotePluginClient::message m; From 2c5cda563b4985659a7408008915f0e4e0f85edb Mon Sep 17 00:00:00 2001 From: DomClark Date: Tue, 14 Aug 2018 21:37:22 +0100 Subject: [PATCH 116/445] Fix kVstTransportChanged flag usage in VST sync Changed according to feedback from AudioBlast. The flag used to be set most of the time, now it is only set when playback starts/stops, looping is toggled, or playback jumps around. --- include/Song.h | 9 +++++++++ include/VstSyncController.h | 6 ++++++ include/VstSyncData.h | 1 + plugins/vst_base/RemoteVstPlugin.cpp | 12 +++++++++++- src/core/Song.cpp | 24 +++++++++++++++++++++--- src/gui/TimeLineWidget.cpp | 1 + 6 files changed, 49 insertions(+), 4 deletions(-) diff --git a/include/Song.h b/include/Song.h index 0ba8a3503..08c99af47 100644 --- a/include/Song.h +++ b/include/Song.h @@ -87,10 +87,19 @@ public: { return m_currentFrame; } + inline void setJumped( const bool jumped ) + { + m_jumped = jumped; + } + inline bool jumped() const + { + return m_jumped; + } TimeLineWidget * m_timeLine; private: float m_currentFrame; + bool m_jumped; } ; diff --git a/include/VstSyncController.h b/include/VstSyncController.h index b969ebbbe..e858f5545 100644 --- a/include/VstSyncController.h +++ b/include/VstSyncController.h @@ -61,6 +61,11 @@ public: m_syncData->isCycle = false; } + void setPlaybackJumped( bool jumped ) + { + m_syncData->m_playbackJumped = jumped; + } + void update(); @@ -79,6 +84,7 @@ private: bool hasSHM; float cycleStart; float cycleEnd; + bool m_playbackJumped; int m_bufferSize; int m_sampleRate; int m_bpm; diff --git a/include/VstSyncData.h b/include/VstSyncData.h index a4c5db80b..d8694f1b2 100644 --- a/include/VstSyncData.h +++ b/include/VstSyncData.h @@ -49,6 +49,7 @@ struct VstSyncData bool hasSHM; float cycleStart; float cycleEnd; + bool m_playbackJumped; int m_bufferSize; int m_sampleRate; int m_bpm; diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index e0b51381e..1e810f0b7 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -396,6 +396,7 @@ private: { float lastppqPos; float m_Timestamp; + int32_t m_lastFlags; } ; in * m_in; @@ -478,12 +479,14 @@ RemoteVstPlugin::RemoteVstPlugin( const char * socketPath ) : m_vstSyncData->ppqPos = 0; m_vstSyncData->isCycle = false; m_vstSyncData->hasSHM = false; + m_vstSyncData->m_playbackJumped = false; m_vstSyncData->m_sampleRate = sampleRate(); } m_in = ( in* ) new char[ sizeof( in ) ]; m_in->lastppqPos = 0; m_in->m_Timestamp = -1; + m_in->m_lastFlags = 0; // process until we have loaded the plugin while( 1 ) @@ -1588,7 +1591,6 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode, __plugin->m_in->m_Timestamp ) { _timeInfo.ppqPos = __plugin->m_vstSyncData->ppqPos; - _timeInfo.flags |= kVstTransportChanged; __plugin->m_in->lastppqPos = __plugin->m_vstSyncData->ppqPos; __plugin->m_in->m_Timestamp = __plugin->m_vstSyncData->ppqPos; } @@ -1615,6 +1617,14 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode, _timeInfo.flags |= kVstBarsValid; + if( ( _timeInfo.flags & ( kVstTransportPlaying | kVstTransportCycleActive ) ) != + ( __plugin->m_in->m_lastFlags & ( kVstTransportPlaying | kVstTransportCycleActive ) ) + || __plugin->m_vstSyncData->m_playbackJumped ) + { + _timeInfo.flags |= kVstTransportChanged; + } + __plugin->m_in->m_lastFlags = _timeInfo.flags; + #ifdef LMMS_BUILD_WIN64 return (long long) &_timeInfo; #else diff --git a/src/core/Song.cpp b/src/core/Song.cpp index be0c7dddc..217a8752e 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -193,6 +193,8 @@ void Song::savePos() void Song::processNextBuffer() { + m_vstSyncController.setPlaybackJumped( false ); + // if not playing, nothing to do if( m_playing == false ) { @@ -262,10 +264,21 @@ void Song::processNextBuffer() ( tl->loopBegin().getTicks() * 60 * 1000 / 48 ) / getTempo(); m_playPos[m_playMode].setTicks( tl->loopBegin().getTicks() ); + + m_vstSyncController.setAbsolutePosition( + tl->loopBegin().getTicks() ); + m_vstSyncController.setPlaybackJumped( true ); + emit updateSampleTracks(); } } + if( m_playPos[m_playMode].jumped() ) + { + m_vstSyncController.setPlaybackJumped( true ); + m_playPos[m_playMode].setJumped( false ); + } + f_cnt_t framesPlayed = 0; const float framesPerTick = Engine::framesPerTick(); @@ -320,6 +333,7 @@ void Song::processNextBuffer() ( ticks * 60 * 1000 / 48 ) / getTempo(); m_vstSyncController.setAbsolutePosition( ticks ); + m_vstSyncController.setPlaybackJumped( true ); } } m_playPos[m_playMode].setTicks( ticks ); @@ -334,11 +348,14 @@ void Song::processNextBuffer() // beginning of the range if( m_playPos[m_playMode] >= tl->loopEnd() ) { - m_playPos[m_playMode].setTicks( tl->loopBegin().getTicks() ); + ticks = tl->loopBegin().getTicks(); + m_playPos[m_playMode].setTicks( ticks ); m_elapsedMilliSeconds = - ( ( tl->loopBegin().getTicks() ) * 60 * 1000 / 48 ) / - getTempo(); + ( ticks * 60 * 1000 / 48 ) / getTempo(); + + m_vstSyncController.setAbsolutePosition( ticks ); + m_vstSyncController.setPlaybackJumped( true ); } else if( m_playPos[m_playMode] == tl->loopEnd() - 1 ) { @@ -609,6 +626,7 @@ void Song::setPlayPos( tick_t ticks, PlayModes playMode ) getTempo() ); m_playPos[playMode].setTicks( ticks ); m_playPos[playMode].setCurrentFrame( 0.0f ); + m_playPos[playMode].setJumped( true ); // send a signal if playposition changes during playback if( isPlaying() ) diff --git a/src/gui/TimeLineWidget.cpp b/src/gui/TimeLineWidget.cpp index 06b32ff7f..47d9db95e 100644 --- a/src/gui/TimeLineWidget.cpp +++ b/src/gui/TimeLineWidget.cpp @@ -375,6 +375,7 @@ void TimeLineWidget::mouseMoveEvent( QMouseEvent* event ) ( 60 * 1000 / 48 ) ) / Engine::getSong()->getTempo() ); m_pos.setCurrentFrame( 0 ); + m_pos.setJumped( true ); updatePosition(); positionMarkerMoved(); break; From 53dadd57355a893639fbc99dbea3b5e43025c614 Mon Sep 17 00:00:00 2001 From: DomClark Date: Tue, 14 Aug 2018 21:45:59 +0100 Subject: [PATCH 117/445] Fix VST windows resizing a little incorrectly This was fixed for setting the initial size of the window in 8e9f74d, but I missed the resizing case. --- plugins/vst_base/RemoteVstPlugin.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 1e810f0b7..12a27d183 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -1726,6 +1726,7 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode, #endif case audioMasterSizeWindow: + { SHOW_CALLBACK( "amc: audioMasterSizeWindow\n" ); if( __plugin->m_window == 0 ) { @@ -1733,8 +1734,13 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode, } __plugin->m_windowWidth = _index; __plugin->m_windowHeight = _value; - SetWindowPos( __plugin->m_window, 0, 0, 0, - _index + 8, _value + 26, + HWND window = __plugin->m_window; + DWORD dwStyle = GetWindowLongPtr( window, GWL_STYLE ); + RECT windowSize = { 0, 0, (int) _index, (int) _value }; + AdjustWindowRect( &windowSize, dwStyle, false ); + SetWindowPos( window, 0, 0, 0, + windowSize.right - windowSize.left, + windowSize.bottom - windowSize.top, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER ); __plugin->sendMessage( @@ -1742,6 +1748,7 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode, addInt( __plugin->m_windowWidth ). addInt( __plugin->m_windowHeight ) ); return 1; + } case audioMasterGetSampleRate: SHOW_CALLBACK( "amc: audioMasterGetSampleRate\n" ); From 0ad8527ff7f34f798ba911271ad936ca6964bb0d Mon Sep 17 00:00:00 2001 From: DomClark Date: Tue, 14 Aug 2018 21:58:44 +0100 Subject: [PATCH 118/445] Link RemoteVstPlugin with -mwindows Stops each remote plugin process spawning a console host, and seems more in line with what other hosts do. --- plugins/vst_base/CMakeLists.txt | 2 +- plugins/vst_base/Win64/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/vst_base/CMakeLists.txt b/plugins/vst_base/CMakeLists.txt index 67e52a9ff..5e2b50206 100644 --- a/plugins/vst_base/CMakeLists.txt +++ b/plugins/vst_base/CMakeLists.txt @@ -12,7 +12,7 @@ IF(LMMS_BUILD_WIN32) TARGET_LINK_LIBRARIES(RemoteVstPlugin -lQtCore4) ENDIF() TARGET_LINK_LIBRARIES(RemoteVstPlugin -lpthread -lgdi32 -lws2_32) - SET_TARGET_PROPERTIES(RemoteVstPlugin PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -O0") + SET_TARGET_PROPERTIES(RemoteVstPlugin PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -O0" LINK_FLAGS "${LINK_FLAGS} -mwindows") ADD_CUSTOM_COMMAND(TARGET RemoteVstPlugin POST_BUILD COMMAND "${STRIP}" "$") INSTALL(TARGETS RemoteVstPlugin RUNTIME DESTINATION "${PLUGIN_DIR}") diff --git a/plugins/vst_base/Win64/CMakeLists.txt b/plugins/vst_base/Win64/CMakeLists.txt index 6a670829c..4895fcbac 100644 --- a/plugins/vst_base/Win64/CMakeLists.txt +++ b/plugins/vst_base/Win64/CMakeLists.txt @@ -11,7 +11,7 @@ ENDIF() TARGET_LINK_LIBRARIES(RemoteVstPlugin32 -l${QTCORE} -lpthread -lgdi32 -lws2_32) ADD_CUSTOM_COMMAND(TARGET RemoteVstPlugin32 POST_BUILD COMMAND "${STRIP}" "$") -SET_TARGET_PROPERTIES(RemoteVstPlugin32 PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -O0") +SET_TARGET_PROPERTIES(RemoteVstPlugin32 PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -O0" LINK_FLAGS "${LINK_FLAGS} -mwindows") INSTALL(TARGETS RemoteVstPlugin32 RUNTIME DESTINATION "${PLUGIN_DIR}/32") INSTALL(FILES "${MINGW_PREFIX32}/bin/${QTCORE}.dll" "${MINGW_PREFIX32}/bin/zlib1.dll" "${MINGW_PREFIX32}/${CMAKE_SYSTEM_PROCESSOR32}-w64-mingw32/bin/libwinpthread-1.dll" From 4c7c68f45a3414f355ec2b17ff235943f93bd199 Mon Sep 17 00:00:00 2001 From: justnope Date: Fri, 18 May 2018 21:04:54 +0200 Subject: [PATCH 119/445] Initialise OLE in RemoteVstPlugin Some plugins don't initialise it themselves, expecting it already to be done for them, and so are liable to hang without it (e.g. TX16Wx). Co-authored-by: Hyunjin Song Co-authored-by: Dominic Clark --- plugins/vst_base/CMakeLists.txt | 2 +- plugins/vst_base/RemoteVstPlugin.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/vst_base/CMakeLists.txt b/plugins/vst_base/CMakeLists.txt index 5e2b50206..84920d9be 100644 --- a/plugins/vst_base/CMakeLists.txt +++ b/plugins/vst_base/CMakeLists.txt @@ -56,7 +56,7 @@ SET(WINE_CXX_ARGS -L${WINE_LIBRARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/RemoteVstPlugin.cpp -std=c++0x - -mwindows -lpthread ${EXTRA_FLAGS} -fno-omit-frame-pointer + -mwindows -lpthread -lole32 ${EXTRA_FLAGS} -fno-omit-frame-pointer ${WINE_BUILD_FLAGS} -o ../RemoteVstPlugin ) diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 12a27d183..219a153f5 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -2061,6 +2061,8 @@ int main( int _argc, char * * _argv ) return -1; } + OleInitialize(nullptr); + #ifdef LMMS_BUILD_WIN32 #ifndef __WINPTHREADS_VERSION // (non-portable) initialization of statically linked pthread library @@ -2176,6 +2178,7 @@ int main( int _argc, char * * _argv ) delete __plugin; + OleUninitialize(); #ifdef LMMS_BUILD_WIN32 #ifndef __WINPTHREADS_VERSION From c3db486be0cd404b3d1a93d7976b6b4819b957b6 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Fri, 7 Sep 2018 22:02:45 +0100 Subject: [PATCH 120/445] Set VST program first when restoring settings Fixes a bug where some VSTs (e.g. Temper) would have their settings reset on project load, due to using programs as presets. --- plugins/vst_base/VstPlugin.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 26c789275..157665eb5 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -157,6 +157,11 @@ void VstPlugin::tryLoad( const QString &remoteVstPluginExecutable ) void VstPlugin::loadSettings( const QDomElement & _this ) { + if( _this.hasAttribute( "program" ) ) + { + setProgram( _this.attribute( "program" ).toInt() ); + } + const int num_params = _this.attribute( "numparams" ).toInt(); // if it exists try to load settings chunk if( _this.hasAttribute( "chunk" ) ) @@ -176,11 +181,6 @@ void VstPlugin::loadSettings( const QDomElement & _this ) } setParameterDump( dump ); } - - if( _this.hasAttribute( "program" ) ) - { - setProgram( _this.attribute( "program" ).toInt() ); - } } From f37ca49e6d52886d40858e23acd1d3ed32f97a71 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 12 Sep 2018 11:02:40 +0900 Subject: [PATCH 121/445] Fix decimal separator handling (#4547) Makes LMMS can handle both periods and commas properly when loading real numbers. --- include/DataFile.h | 19 ------ include/LocaleHelper.h | 67 +++++++++++++++++++ plugins/MidiExport/MidiExport.cpp | 7 +- plugins/VstEffect/VstEffectControls.cpp | 9 +-- plugins/vestige/vestige.cpp | 9 +-- plugins/vst_base/VstPlugin.cpp | 3 +- .../zynaddsubfx/src/Misc/QtXmlWrapper.cpp | 9 +-- src/core/AutomatableModel.cpp | 5 +- src/core/AutomationPattern.cpp | 7 +- src/core/DataFile.cpp | 38 ++--------- src/core/Song.cpp | 4 -- src/gui/widgets/Knob.cpp | 3 +- src/tracks/InstrumentTrack.cpp | 2 - 13 files changed, 101 insertions(+), 81 deletions(-) create mode 100644 include/LocaleHelper.h diff --git a/include/DataFile.h b/include/DataFile.h index 6b6b1a98e..9a420135a 100644 --- a/include/DataFile.h +++ b/include/DataFile.h @@ -84,25 +84,6 @@ public: return m_type; } - // small helper class for adjusting application's locale settings - // when loading or saving floating point values rendered to strings - class LocaleHelper - { - public: - enum Modes - { - ModeLoad, - ModeSave, - ModeCount - }; - typedef Modes Mode; - - LocaleHelper( Mode mode ); - ~LocaleHelper(); - - }; - - private: static Type type( const QString& typeName ); static QString typeName( Type type ); diff --git a/include/LocaleHelper.h b/include/LocaleHelper.h new file mode 100644 index 000000000..c5d9d4c46 --- /dev/null +++ b/include/LocaleHelper.h @@ -0,0 +1,67 @@ +/* + * LocaleHelper.h - compatibility functions for handling decimal separators + * Providing helper functions which handle both periods and commas + * for decimal separators to load old projects correctly + * + * Copyright (c) 2014 Tobias Doerffel + * Copyright (c) 2018 Hyunjin Song + * + * 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 LOCALEHELPER_H +#define LOCALEHELPER_H + +#include + +#include +#include + +namespace LocaleHelper +{ +inline double toDouble(QString str, bool* ok = nullptr) +{ + bool isOkay; + double value; + QLocale c(QLocale::C); + c.setNumberOptions(QLocale::RejectGroupSeparator); + value = c.toDouble(str, &isOkay); + if (!isOkay) + { + QLocale german(QLocale::German); + german.setNumberOptions(QLocale::RejectGroupSeparator); + value = german.toDouble(str, &isOkay); + } + if (ok != nullptr) {*ok = isOkay;} + return value; +} + +inline float toFloat(QString str, bool* ok = nullptr) +{ + double d = toDouble(str, ok); + if (!std::isinf(d) && std::fabs(d) > std::numeric_limits::max()) + { + if (ok != nullptr) {*ok = false;} + return 0.0f; + } + return static_cast(d); +} +} + +#endif // LOCALEHELPER_H diff --git a/plugins/MidiExport/MidiExport.cpp b/plugins/MidiExport/MidiExport.cpp index 1e20e9d40..65eaf4613 100644 --- a/plugins/MidiExport/MidiExport.cpp +++ b/plugins/MidiExport/MidiExport.cpp @@ -36,6 +36,7 @@ #include "TrackContainer.h" #include "BBTrack.h" #include "InstrumentTrack.h" +#include "LocaleHelper.h" extern "C" @@ -133,7 +134,7 @@ bool MidiExport::tryExport(const TrackContainer::TrackList &tracks, { base_pitch += masterPitch; } - base_volume = it.attribute("volume", "100").toDouble()/100.0; + base_volume = LocaleHelper::toDouble(it.attribute("volume", "100"))/100.0; } if (n.nodeName() == "pattern") @@ -204,7 +205,7 @@ bool MidiExport::tryExport(const TrackContainer::TrackList &tracks, { base_pitch += masterPitch; } - base_volume = it.attribute("volume", "100").toDouble() / 100.0; + base_volume = LocaleHelper::toDouble(it.attribute("volume", "100")) / 100.0; } if (n.nodeName() == "pattern") @@ -273,7 +274,7 @@ 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 * note.attribute("vol", "100").toDouble()), 127); + mnote.volume = qMin(qRound(base_volume * LocaleHelper::toDouble(note.attribute("vol", "100"))), 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/VstEffect/VstEffectControls.cpp b/plugins/VstEffect/VstEffectControls.cpp index 21d940ddc..e5261d625 100644 --- a/plugins/VstEffect/VstEffectControls.cpp +++ b/plugins/VstEffect/VstEffectControls.cpp @@ -27,6 +27,7 @@ #include "VstEffectControls.h" #include "VstEffect.h" +#include "LocaleHelper.h" #include "MainWindow.h" #include "GuiApplication.h" #include @@ -85,8 +86,8 @@ void VstEffectControls::loadSettings( const QDomElement & _this ) if( !( knobFModel[ i ]->isAutomated() || knobFModel[ i ]->controllerConnection() ) ) { - knobFModel[ i ]->setValue( (s_dumpValues.at( 2 ) ).toFloat() ); - knobFModel[ i ]->setInitValue( (s_dumpValues.at( 2 ) ).toFloat() ); + knobFModel[ i ]->setValue(LocaleHelper::toFloat(s_dumpValues.at(2))); + knobFModel[ i ]->setInitValue(LocaleHelper::toFloat(s_dumpValues.at(2))); } connect( knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) ); @@ -381,7 +382,7 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls * if( !hasKnobModel ) { sprintf( paramStr, "%d", i); - m_vi->knobFModel[ i ] = new FloatModel( ( s_dumpValues.at( 2 ) ).toFloat(), + 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, @@ -445,7 +446,7 @@ void manageVSTEffectView::syncPlugin( void ) { sprintf( paramStr, "param%d", i ); s_dumpValues = dump[ paramStr ].split( ":" ); - f_value = ( s_dumpValues.at( 2 ) ).toFloat(); + f_value = LocaleHelper::toFloat(s_dumpValues.at(2)); m_vi2->knobFModel[ i ]->setAutomatedValue( f_value ); m_vi2->knobFModel[ i ]->setInitValue( f_value ); } diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index 540c8b5ce..b958e8ddf 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -41,6 +41,7 @@ #include "InstrumentPlayHandle.h" #include "InstrumentTrack.h" #include "VstPlugin.h" +#include "LocaleHelper.h" #include "MainWindow.h" #include "Mixer.h" #include "GuiApplication.h" @@ -203,8 +204,8 @@ void vestigeInstrument::loadSettings( const QDomElement & _this ) if( !( knobFModel[ i ]->isAutomated() || knobFModel[ i ]->controllerConnection() ) ) { - knobFModel[ i ]->setValue( ( s_dumpValues.at( 2 )).toFloat() ); - knobFModel[ i ]->setInitValue( ( s_dumpValues.at( 2 )).toFloat() ); + knobFModel[ i ]->setValue(LocaleHelper::toFloat(s_dumpValues.at(2))); + knobFModel[ i ]->setInitValue(LocaleHelper::toFloat(s_dumpValues.at(2))); } connect( knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) ); @@ -991,7 +992,7 @@ manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrume if( !hasKnobModel ) { sprintf( paramStr, "%d", i); - m_vi->knobFModel[ i ] = new FloatModel( (s_dumpValues.at( 2 )).toFloat(), + 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() ) ); @@ -1052,7 +1053,7 @@ void manageVestigeInstrumentView::syncPlugin( void ) { sprintf( paramStr, "param%d", i ); s_dumpValues = dump[ paramStr ].split( ":" ); - f_value = ( s_dumpValues.at( 2 ) ).toFloat(); + f_value = LocaleHelper::toFloat(s_dumpValues.at(2)); m_vi->knobFModel[ i ]->setAutomatedValue( f_value ); m_vi->knobFModel[ i ]->setInitValue( f_value ); } diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 157665eb5..a97802bdc 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -56,6 +56,7 @@ #include "ConfigManager.h" #include "GuiApplication.h" +#include "LocaleHelper.h" #include "MainWindow.h" #include "Mixer.h" #include "Song.h" @@ -299,7 +300,7 @@ void VstPlugin::setParameterDump( const QMap & _pdump ) { ( *it ).section( ':', 0, 0 ).toInt(), "", - ( *it ).section( ':', 2, -1 ).toFloat() + LocaleHelper::toFloat((*it).section(':', 2, -1)) } ; m.addInt( item.index ); m.addString( item.shortLabel ); diff --git a/plugins/zynaddsubfx/zynaddsubfx/src/Misc/QtXmlWrapper.cpp b/plugins/zynaddsubfx/zynaddsubfx/src/Misc/QtXmlWrapper.cpp index bab513829..d4b6875a0 100644 --- a/plugins/zynaddsubfx/zynaddsubfx/src/Misc/QtXmlWrapper.cpp +++ b/plugins/zynaddsubfx/zynaddsubfx/src/Misc/QtXmlWrapper.cpp @@ -61,6 +61,7 @@ // Include LMMS headers #include "lmmsconfig.h" #include "IoHelper.h" +#include "LocaleHelper.h" struct XmlData @@ -228,14 +229,14 @@ int QtXmlWrapper::dosavefile(const char *filename, void QtXmlWrapper::addpar(const std::string &name, int val) { - d->addparams("par", 2, "name", name.c_str(), "value", stringFrom( - val).c_str()); + d->addparams("par", 2, "name", name.c_str(), "value", + QString::number(val).toLocal8Bit().constData()); } void QtXmlWrapper::addparreal(const std::string &name, float val) { d->addparams("par_real", 2, "name", name.c_str(), "value", - stringFrom(val).c_str()); + QString::number(val, 'f').toLocal8Bit().constData()); } void QtXmlWrapper::addparbool(const std::string &name, int val) @@ -510,7 +511,7 @@ float QtXmlWrapper::getparreal(const char *name, float defaultpar) const return defaultpar; } - return QLocale().toFloat( tmp.attribute( "value" ) ); + return LocaleHelper::toFloat( tmp.attribute( "value" ) ); } float QtXmlWrapper::getparreal(const char *name, diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index 0b2a1522b..ba81a5893 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -28,6 +28,7 @@ #include "AutomationPattern.h" #include "ControllerConnection.h" +#include "LocaleHelper.h" #include "Mixer.h" #include "ProjectJournal.h" @@ -183,7 +184,7 @@ void AutomatableModel::loadSettings( const QDomElement& element, const QString& if( node.isElement() ) { changeID( node.toElement().attribute( "id" ).toInt() ); - setValue( node.toElement().attribute( "value" ).toFloat() ); + setValue( LocaleHelper::toFloat( node.toElement().attribute( "value" ) ) ); if( node.toElement().hasAttribute( "scale_type" ) ) { if( node.toElement().attribute( "scale_type" ) == "linear" ) @@ -204,7 +205,7 @@ void AutomatableModel::loadSettings( const QDomElement& element, const QString& if( element.hasAttribute( name ) ) // attribute => read the element's value from the attribute list { - setInitValue( element.attribute( name ).toFloat() ); + setInitValue( LocaleHelper::toFloat( element.attribute( name ) ) ); } else { diff --git a/src/core/AutomationPattern.cpp b/src/core/AutomationPattern.cpp index 32b13f3f4..25da6defb 100644 --- a/src/core/AutomationPattern.cpp +++ b/src/core/AutomationPattern.cpp @@ -28,6 +28,7 @@ #include "AutomationPatternView.h" #include "AutomationTrack.h" +#include "LocaleHelper.h" #include "Note.h" #include "ProjectJournal.h" #include "BBTrackContainer.h" @@ -154,11 +155,11 @@ void AutomationPattern::setProgressionType( void AutomationPattern::setTension( QString _new_tension ) { bool ok; - float nt = _new_tension.toFloat( & ok ); + float nt = LocaleHelper::toFloat(_new_tension, & ok); if( ok && nt > -0.01 && nt < 1.01 ) { - m_tension = _new_tension.toFloat(); + m_tension = nt; } } @@ -595,7 +596,7 @@ void AutomationPattern::loadSettings( const QDomElement & _this ) if( element.tagName() == "time" ) { m_timeMap[element.attribute( "pos" ).toInt()] - = element.attribute( "value" ).toFloat(); + = LocaleHelper::toFloat(element.attribute("value")); } else if( element.tagName() == "object" ) { diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index dc2b1de57..47df25614 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -38,6 +38,7 @@ #include "Effect.h" #include "embed.h" #include "GuiApplication.h" +#include "LocaleHelper.h" #include "PluginFactory.h" #include "ProjectVersion.h" #include "SongEditor.h" @@ -65,37 +66,6 @@ DataFile::typeDescStruct -DataFile::LocaleHelper::LocaleHelper( Mode mode ) -{ - switch( mode ) - { - case ModeLoad: - // set a locale for which QString::fromFloat() returns valid values if - // floating point separator is a comma - otherwise we would fail to load - // older projects made by people from various countries due to their - // locale settings - QLocale::setDefault( QLocale::German ); - break; - - case ModeSave: - // set default locale to C so that floating point decimals are rendered to - // strings with periods as decimal point instead of commas in some countries - QLocale::setDefault( QLocale::C ); - - default: break; - } -} - - - -DataFile::LocaleHelper::~LocaleHelper() -{ - // revert to original locale - QLocale::setDefault( QLocale::system() ); -} - - - DataFile::DataFile( Type type ) : QDomDocument( "lmms-project" ), @@ -416,8 +386,8 @@ void DataFile::upgrade_0_2_1_20070501() QDomElement el = list.item( i ).toElement(); if( el.attribute( "vol" ) != "" ) { - el.setAttribute( "vol", el.attribute( - "vol" ).toFloat() * 100.0f ); + el.setAttribute( "vol", LocaleHelper::toFloat( + el.attribute( "vol" ) ) * 100.0f ); } else { @@ -543,7 +513,7 @@ void DataFile::upgrade_0_2_1_20070508() QDomElement el = list.item( i ).toElement(); if( el.hasAttribute( "vol" ) ) { - float value = el.attribute( "vol" ).toFloat(); + float value = LocaleHelper::toFloat( el.attribute( "vol" ) ); value = roundf( value * 0.585786438f ); el.setAttribute( "vol", value ); } diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 217a8752e..1ebc684c1 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -1034,8 +1034,6 @@ void Song::loadProject( const QString & fileName ) clearErrors(); - DataFile::LocaleHelper localeHelper( DataFile::LocaleHelper::ModeLoad ); - Engine::mixer()->requestChangeInModel(); // get the header information from the DOM @@ -1191,8 +1189,6 @@ void Song::loadProject( const QString & fileName ) // only save current song as _filename and do nothing else bool Song::saveProjectFile( const QString & filename ) { - DataFile::LocaleHelper localeHelper( DataFile::LocaleHelper::ModeSave ); - DataFile dataFile( DataFile::SongProject ); m_tempoModel.saveSettings( dataFile, dataFile.head(), "bpm" ); diff --git a/src/gui/widgets/Knob.cpp b/src/gui/widgets/Knob.cpp index 73ef42758..72c6c7f8b 100644 --- a/src/gui/widgets/Knob.cpp +++ b/src/gui/widgets/Knob.cpp @@ -42,6 +42,7 @@ #include "embed.h" #include "gui_templates.h" #include "GuiApplication.h" +#include "LocaleHelper.h" #include "MainWindow.h" #include "ProjectJournal.h" #include "Song.h" @@ -560,7 +561,7 @@ void Knob::dropEvent( QDropEvent * _de ) QString val = StringPairDrag::decodeValue( _de ); if( type == "float_value" ) { - model()->setValue( val.toFloat() ); + model()->setValue( LocaleHelper::toFloat(val) ); _de->accept(); } else if( type == "automatable_model" ) diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 90dbf11a6..d5ded0c70 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -1618,8 +1618,6 @@ void InstrumentTrackWindow::saveSettingsBtnClicked() !sfd.selectedFiles().isEmpty() && !sfd.selectedFiles().first().isEmpty() ) { - DataFile::LocaleHelper localeHelper( DataFile::LocaleHelper::ModeSave ); - DataFile dataFile( DataFile::InstrumentTrackSettings ); m_track->setSimpleSerializing(); m_track->saveSettings( dataFile, dataFile.content() ); From a5a13b1256704b136ea60ac475cfae745396c857 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Wed, 29 Aug 2018 19:35:06 +0200 Subject: [PATCH 122/445] Restructure help * Allow actions (dump, render*, upgrade) without minuses * Restructure help in CLI * Restructure help in man pages --- doc/lmms.1 | 146 +++++++++++++++++----------------------------- src/core/main.cpp | 121 ++++++++++++++++++-------------------- 2 files changed, 109 insertions(+), 158 deletions(-) diff --git a/doc/lmms.1 b/doc/lmms.1 index 41f906ecf..16b1e5284 100644 --- a/doc/lmms.1 +++ b/doc/lmms.1 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH LMMS 1 "June 15, 2017" +.TH LMMS 1 "September 10, 2018" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -19,125 +19,83 @@ lmms \- software for easy music production .SH SYNOPSIS .B lmms -.RB "[ \--\fBallowroot\fP ]" +.RB "[\fBglobal options...\fP] [\fBaction\fP [\fBaction parameters\fP...]] .br -.B lmms -.RB "[ \--\fBbitrate\fP \fIbitrate\fP ]" -.br -.B lmms -.RB "[ \--\fBconfig\fP \fIconfigfile\fP ]" -.br -.B lmms -.RB "[ \--\fBdump\fP \fIin\fP ]" -.br -.B lmms -.RB "[ \--\fBfloat\fP ]" -.br -.B lmms -.RB "[ \--\fBformat\fP \fIformat\fP ]" -.br -.B lmms -.RB "[ \--\fBgeometry\fP \fIgeometry\fP ]" -.br -.B lmms -.RB "[ \--\fBhelp\fP ]" -.br -.B lmms -.RB "[ \--\interpolation\fP \fImethod\fP ]" -.br -.B lmms -.RB "[ \--\fBimport\fP \fIin\fP [ \-e ] ]" -.br -.B lmms -.RB "[ \--\fBloop\fP ]" -.br -.B lmms -.RB "[ \--\fBmode\fP \fIstereomode\fP ]" -.br -.B lmms -.RB "[ \--\fBoutput\fP \fIpath\fP ]" -.br -.B lmms -.RB "[ \--\fBoversampling\fP \fIvalue\fP ]" -.br -.B lmms -.RB "[ \--\fBprofile\fP \fIout\fP ]" -.br -.B lmms -.RB "[ \--\fBrender\fP \fIfile\fP ] [options]" -.br -.B lmms -.RB "[ \--\fBsamplerate\fP \fIsamplerate\fP ]" -.br -.B lmms -.RB "[ \--\fBupgrade\fP \fIin\fP \fIout\fP ]" -.br -.B lmms -.RB "[ \--\fBversion\fP ]" -.br -.B lmms -.RI "[ file ]" .SH DESCRIPTION .PP .\" TeX users may be more comfortable with the \fB\fP and .\" \fI\fP escape sequences to invode bold face and italics, .\" respectively. .B LMMS -LMMS is a free cross-platform alternative to commercial programs like FL Studio®, which allow you to produce music with your computer. This includes the creation of melodies and beats, the synthesis and mixing of sounds, and arranging of samples. You can have fun with your MIDI-keyboard and much more; all in a user-friendly and modern interface. +is a free cross-platform alternative to commercial programs like FL Studio®, which allow you to produce music with your computer. This includes the creation of melodies and beats, the synthesis and mixing of sounds, and arranging of samples. You can have fun with your MIDI-keyboard and much more; all in a user-friendly and modern interface. LMMS features components such as a Song Editor, a Beat+Bassline Editor, a Piano Roll, an FX Mixer as well as many powerful instruments and effects. -.SH OPTIONS -.IP "\fB\-a, --float\fP -32bit float bit depth -.IP "\fB\-b, --bitrate\fP \fIbitrate\fP -Specify output bitrate in KBit/s (for OGG encoding only), default is 160 +.SH ACTIONS + +.IP " [\fIoptions\fP...] [\fIproject\fP] +Start LMMS in normal GUI mode. +.IP "\fBdump\fP \fIin\fP +Dump XML of compressed (MMPZ) file \fIin\fP. +.IP "\fBrender\fP \fIproject\fP [\fIoptions\fP...] +Render given project file. +.IP "\fBrendertracks\fP \fIproject\fP [\fIoptions\fP...] +Render each track to a different file. +.IP "\fBupgrade\fP \fIin\fP [\fIout\fP] +Upgrade file \fIin\fP and save as \fIout\fP. Standard out is used if no output file is specifed. + +.SH GLOBAL OPTIONS + +.IP "\fB\ --allowroot +Bypass root user startup check (use with caution). .IP "\fB\-c, --config\fP \fIconfigfile\fP -Get the configuration from \fIconfigfile\fP instead of ~/.lmmsrc.xml (default) -.IP "\fB\-d, --dump\fP \fIin\fP -Dump XML of compressed file \fIin\fP (i.e. MMPZ-file) -.IP "\fB\-f, --format\fP \fIformat\fP -Specify format of render-output where \fIformat\fP is either 'wav', 'ogg' or 'mp3'. -.IP "\fB\ --geometry\fP \fIgeometry\fP -Specify the prefered size and position of the main window -.br -\fIgeometry\fP syntax is <\fIxsize\fPx\fIysize\fP+\fIxoffset\fP+\fIyoffset\fP>. -.br -Default: full screen +Get the configuration from \fIconfigfile\fP instead of ~/.lmmsrc.xml (default). .IP "\fB\-h, --help\fP Show usage information and exit. -.IP "\fB\-i, --interpolation\fP \fImethod\fP -Specify interpolation method - possible values are \fIlinear\fP, \fIsincfastest\fP (default), \fIsincmedium\fP, \fIsincbest\fP -.IP "\fB\ --import\fP \fIin\fP \fB\-e\fP -Import MIDI file \fIin\fP +.IP "\fB\-v, --version +Show version information and exit. + +.SH OPTIONS IF NO ACTION IS GIVEN + +.IP "\fB\ --geometry\fP \fIgeometry\fP +Specify the prefered size and position of the main window. .br +\fIgeometry\fP syntax is \fIxsize\fPx\fIysize\fP+\fIxoffset\fP+\fIyoffset\fP. +.br +Default: full screen. +.IP "\fB\ --import\fP \fIin\fP \fB\-e\fP +Import MIDI or Hydrogen file \fIin\fP. +.br + +.SH OPTIONS FOR RENDER AND RENDERTRACKS + +.IP "\fB\-a, --float\fP +Use 32bit float bit depth. +.IP "\fB\-b, --bitrate\fP \fIbitrate\fP +Specify output bitrate in KBit/s (for OGG encoding only), default is 160. +.IP "\fB\-f, --format\fP \fIformat\fP +Specify format of render-output where \fIformat\fP is either 'wav', 'ogg' or 'mp3'. +.IP "\fB\-i, --interpolation\fP \fImethod\fP +Specify interpolation method - possible values are \fIlinear\fP, \fIsincfastest\fP (default), \fIsincmedium\fP, \fIsincbest\fP. + If -e is specified lmms exits after importing the file. .IP "\fB\-l, --loop Render the given file as a loop, i.e. stop rendering at exactly the end of the song. Additional silence or reverb tails at the end of the song are not rendered. .IP "\fB\-m, --mode\fP \fIstereomode\fP Set the stereo mode used for the MP3 export. \fIstereomode\fP can be either 's' (stereo mode), 'j' (joint stereo) or 'm' (mono). If no mode is given 'j' is used as the default. .IP "\fB\-o, --output\fP \fIpath\fP -Render into \fIpath\fP +Render into \fIpath\fP. .br For --render, this is interpreted as a file path. .br For --render-tracks, this is interpreted as a path to an existing directory. -IP "\fB\-p, --profile\fP \fIout\fP -Dump profiling information to file \fIout\fP -.IP "\fB\-r, --render\fP \fIproject-file\fP -Render given file to either a wav\- or ogg\-file. See \fB\-f\fP for details -.IP "\fB\-r, --rendertracks\fP \fIproject-file\fP -Render each track into a separate wav\- or ogg\-file. See \fB\-f\fP for details +.IP "\fB\-p, --profile\fP \fIout\fP +Dump profiling information to file \fIout\fP. .IP "\fB\-s, --samplerate\fP \fIsamplerate\fP -Specify output samplerate in Hz - range is 44100 (default) to 192000 -.IP "\fB\-u, --upgrade\fP \fIin\fP \fIout\fP -Upgrade file \fIin\fP and save as \fIout\fP -.IP "\fB\-v, --version -Show version information and exit. +Specify output samplerate in Hz - range is 44100 (default) to 192000. .IP "\fB\-x, --oversampling\fP \fIvalue\fP -Specify oversampling, possible values: 1, 2 (default), 4, 8 -.IP "\fB\ --allowroot -Bypass root user startup check (use with caution). +Specify oversampling, possible values: 1, 2 (default), 4, 8. + .SH SEE ALSO .BR https://lmms.io/ .BR https://lmms.io/documentation/ diff --git a/src/core/main.cpp b/src/core/main.cpp index fc8dd5de2..721f83479 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -113,65 +113,57 @@ void printHelp() { printf( "LMMS %s\n" "Copyright (c) %s\n\n" - "Usage: lmms [ -a ]\n" - " [ -b ]\n" - " [ -c ]\n" - " [ -d ]\n" - " [ -f ]\n" - " [ --geometry ]\n" - " [ -h ]\n" - " [ -i ]\n" - " [ --import [-e]]\n" - " [ -l ]\n" - " [ -m ]\n" - " [ -o ]\n" - " [ -p ]\n" - " [ -r ] [ options ]\n" - " [ -s ]\n" - " [ -u ]\n" - " [ -v ]\n" - " [ -x ]\n" - " [ ]\n\n" - "-a, --float 32bit float bit depth\n" - "-b, --bitrate Specify output bitrate in KBit/s\n" - " Default: 160.\n" - "-c, --config Get the configuration from \n" - "-d, --dump Dump XML of compressed file \n" - "-f, --format Specify format of render-output where\n" - " Format is either 'wav', 'ogg' or 'mp3'.\n" - " --geometry Specify the size and position of the main window\n" - " geometry is .\n" - "-h, --help Show this usage information and exit.\n" - "-i, --interpolation Specify interpolation method\n" - " Possible values:\n" - " - linear\n" - " - sincfastest (default)\n" - " - sincmedium\n" - " - sincbest\n" - " --import [-e] Import MIDI file .\n" - " If -e is specified lmms exits after importing the file.\n" - "-l, --loop Render as a loop\n" - "-m, --mode Stereo mode used for MP3 export\n" - " Possible values: s, j, m\n" - " s: Stereo\n" - " j: Joint Stereo\n" - " m: Mono\n" - " Default: j\n" - "-o, --output Render into \n" - " For --render, provide a file path\n" - " For --rendertracks, provide a directory path\n" - "-p, --profile Dump profiling information to file \n" - "-r, --render Render given project file\n" - " --rendertracks Render each track to a different file\n" - "-s, --samplerate Specify output samplerate in Hz\n" - " Range: 44100 (default) to 192000\n" - "-u, --upgrade [out] Upgrade file and save as \n" - " Standard out is used if no output file is specifed\n" - "-v, --version Show version information and exit.\n" - " --allowroot Bypass root user startup check (use with caution).\n" - "-x, --oversampling Specify oversampling\n" - " Possible values: 1, 2, 4, 8\n" - " Default: 2\n\n", + "Usage: lmms [global options...] [ [action parameters...]]\n\n" + "Actions:\n" + " [options...] [] Start LMMS in normal GUI mode\n" + " dump Dump XML of compressed file \n" + " render [options...] Render given project file\n" + " rendertracks [options...] Render each track to a different file\n" + " upgrade [out] Upgrade file and save as \n" + " Standard out is used if no output file\n" + " is specifed\n" + "\nGlobal options:\n" + " --allowroot Bypass root user startup check (use with\n" + " caution).\n" + " -c, --config Get the configuration from \n" + " -h, --help Show this usage information and exit.\n" + " -v, --version Show version information and exit.\n" + "\nOptions if no action is given:\n" + " --geometry Specify the size and position of\n" + " the main window\n" + " geometry is .\n" + " --import [-e] Import MIDI or Hydrogen file .\n" + " If -e is specified lmms exits after importing the file.\n" + "\nOptions for \"render\" and \"rendertracks\":\n" + " -a, --float Use 32bit float bit depth\n" + " -b, --bitrate Specify output bitrate in KBit/s\n" + " Default: 160.\n" + " -f, --format Specify format of render-output where\n" + " Format is either 'wav', 'flac', 'ogg' or 'mp3'.\n" + " -i, --interpolation Specify interpolation method\n" + " Possible values:\n" + " - linear\n" + " - sincfastest (default)\n" + " - sincmedium\n" + " - sincbest\n" + " -l, --loop Render as a loop\n" + " -m, --mode Stereo mode used for MP3 export\n" + " Possible values: s, j, m\n" + " s: Stereo\n" + " j: Joint Stereo\n" + " m: Mono\n" + " Default: j\n" + " -o, --output Render into \n" + " For \"render\", provide a file path\n" + " For \"rendertracks\", provide a directory path\n" + " If not specified, render will overwrite the input file\n" + " For \"rendertracks\", this might be required\n" + " -p, --profile Dump profiling information to file \n" + " -s, --samplerate Specify output samplerate in Hz\n" + " Range: 44100 (default) to 192000\n" + " -x, --oversampling Specify oversampling\n" + " Possible values: 1, 2, 4, 8\n" + " Default: 2\n\n", LMMS_VERSION, LMMS_PROJECT_COPYRIGHT ); } @@ -224,11 +216,11 @@ int main( int argc, char * * argv ) if( arg == "--help" || arg == "-h" || arg == "--version" || arg == "-v" || - arg == "--render" || arg == "-r" ) + arg == "render" || arg == "--render" || arg == "-r" ) { coreOnly = true; } - else if( arg == "--rendertracks" ) + else if( arg == "rendertracks" || arg == "--rendertracks" ) { coreOnly = true; renderTracks = true; @@ -283,7 +275,7 @@ int main( int argc, char * * argv ) printHelp(); return EXIT_SUCCESS; } - else if( arg == "--upgrade" || arg == "-u" ) + else if( arg == "upgrade" || arg == "--upgrade" || arg == "-u") { ++i; @@ -321,7 +313,7 @@ int main( int argc, char * * argv ) #endif } - else if( arg == "--dump" || arg == "-d" ) + else if( arg == "dump" || arg == "--dump" || arg == "-d" ) { ++i; @@ -340,7 +332,8 @@ int main( int argc, char * * argv ) return EXIT_SUCCESS; } - else if( arg == "--render" || arg == "-r" || arg == "--rendertracks" ) + else if( arg == "render" || arg == "--render" || arg == "-r" || + arg == "rendertracks" || arg == "--rendertracks" ) { ++i; From 3064f03818198bf8881aff644a14b57e500938ed Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Wed, 6 Jun 2018 09:35:03 +0900 Subject: [PATCH 123/445] Validate audio/MIDI backend when opening setup dialog Original work: #4372 by @justnope --- src/gui/SetupDialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/SetupDialog.cpp b/src/gui/SetupDialog.cpp index 5e8f53c5c..23266f153 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -833,7 +833,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : // If no preferred audio device is saved, save the current one QString audioDevName = ConfigManager::inst()->value( "mixer", "audiodev" ); - if( audioDevName.length() == 0 ) + if( m_audioInterfaces->findText(audioDevName) < 0 ) { audioDevName = Engine::mixer()->audioDevName(); ConfigManager::inst()->setValue( @@ -936,7 +936,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : QString midiDevName = ConfigManager::inst()->value( "mixer", "mididev" ); - if( midiDevName.length() == 0 ) + if( m_midiInterfaces->findText(midiDevName) < 0 ) { midiDevName = Engine::mixer()->midiClientName(); ConfigManager::inst()->setValue( From 91ca660161dbaf5a18d6b1cd2d90328140b99728 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 13 Aug 2018 15:35:27 +0900 Subject: [PATCH 124/445] Fallback to default audio/MIDI backends if invalid one is set Also shows the setup dialog in case of invalid audio backends --- include/Mixer.h | 3 + src/core/Mixer.cpp | 128 +++++++++++++++++++++++++++++++++++++++++ src/gui/MainWindow.cpp | 4 +- 3 files changed, 134 insertions(+), 1 deletion(-) diff --git a/include/Mixer.h b/include/Mixer.h index 499205892..3063b0f2b 100644 --- a/include/Mixer.h +++ b/include/Mixer.h @@ -308,6 +308,9 @@ public: void requestChangeInModel(); void doneChangeInModel(); + static bool isAudioDevNameValid(QString name); + static bool isMidiDevNameValid(QString name); + signals: void qualitySettingsChanged(); diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index d5baa0a85..67736742d 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -829,14 +829,138 @@ void Mixer::runChangesInModel() } } +bool Mixer::isAudioDevNameValid(QString name) +{ +#ifdef LMMS_HAVE_SDL + if (name == AudioSdl::name()) + { + return true; + } +#endif +#ifdef LMMS_HAVE_ALSA + if (name == AudioAlsa::name()) + { + return true; + } +#endif + + +#ifdef LMMS_HAVE_PULSEAUDIO + if (name == AudioPulseAudio::name()) + { + return true; + } +#endif + + +#ifdef LMMS_HAVE_OSS + if (name == AudioOss::name()) + { + return true; + } +#endif + +#ifdef LMMS_HAVE_SNDIO + if (name == AudioSndio::name()) + { + return true; + } +#endif + +#ifdef LMMS_HAVE_JACK + if (name == AudioJack::name()) + { + return true; + } +#endif + + +#ifdef LMMS_HAVE_PORTAUDIO + if (name == AudioPortAudio::name()) + { + return true; + } +#endif + + +#ifdef LMMS_HAVE_SOUNDIO + if (name == AudioSoundIo::name()) + { + return true; + } +#endif + + if (name == AudioDummy::name()) + { + return true; + } + + return false; +} + +bool Mixer::isMidiDevNameValid(QString name) +{ +#ifdef LMMS_HAVE_ALSA + if (name == MidiAlsaSeq::name() || name == MidiAlsaRaw::name()) + { + return true; + } +#endif + +#ifdef LMMS_HAVE_JACK + if (name == MidiJack::name()) + { + return true; + } +#endif + +#ifdef LMMS_HAVE_OSS + if (name == MidiOss::name()) + { + return true; + } +#endif + +#ifdef LMMS_HAVE_SNDIO + if (name == MidiSndio::name()) + { + return true; + } +#endif + +#ifdef LMMS_BUILD_WIN32 + if (name == MidiWinMM::name()) + { + return true; + } +#endif + +#ifdef LMMS_BUILD_APPLE + if (name == MidiApple::name()) + { + return true; + } +#endif + + if (name == MidiDummy::name()) + { + return true; + } + + return false; +} AudioDevice * Mixer::tryAudioDevices() { bool success_ful = false; AudioDevice * dev = NULL; QString dev_name = ConfigManager::inst()->value( "mixer", "audiodev" ); + if( !isAudioDevNameValid( dev_name ) ) + { + dev_name = ""; + } m_audioDevStartFailed = false; @@ -980,6 +1104,10 @@ MidiClient * Mixer::tryMidiClients() { QString client_name = ConfigManager::inst()->value( "mixer", "mididev" ); + if( !isMidiDevNameValid( client_name ) ) + { + client_name = ""; + } #ifdef LMMS_HAVE_ALSA if( client_name == MidiAlsaSeq::name() || client_name == "" ) diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index c047bf96c..fa6958cef 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -590,7 +590,9 @@ void MainWindow::finalize() } // look whether mixer failed to start the audio device selected by the // user and is using AudioDummy as a fallback - else if( Engine::mixer()->audioDevStartFailed() ) + // or the audio device is set to invalid one + else if( Engine::mixer()->audioDevStartFailed() || !Mixer::isAudioDevNameValid( + ConfigManager::inst()->value( "mixer", "audiodev" ) ) ) { // if so, offer the audio settings section of the setup dialog SetupDialog sd( SetupDialog::AudioSettings ); From 153f15f4b4e702fc198611f2bc4a93a7e2e31228 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Sat, 15 Sep 2018 09:32:29 -0400 Subject: [PATCH 125/445] Add Carla support for MacOS (#4558) Add Carla support for MacOS --- .gitignore | 1 + .travis/osx..install.sh | 2 +- CMakeLists.txt | 6 +++- cmake/apple/install_apple.sh.in | 41 ++++++++++++++++++++----- cmake/modules/BuildPlugin.cmake | 6 +++- plugins/carlabase/CMakeLists.txt | 8 +++++ plugins/carlabase/carla.cpp | 28 ++++++----------- plugins/carlabase/carla.h | 18 +++++++++-- plugins/carlapatchbay/carlapatchbay.cpp | 4 +-- plugins/carlarack/carlarack.cpp | 4 +-- 10 files changed, 81 insertions(+), 37 deletions(-) diff --git a/.gitignore b/.gitignore index aa4f17ab8..771eba607 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /build /target .*.sw? +.DS_Store *~ /CMakeLists.txt.user /plugins/zynaddsubfx/zynaddsubfx/ExternalPrograms/Controller/Makefile diff --git a/.travis/osx..install.sh b/.travis/osx..install.sh index 45a6762d1..dfe1df4d1 100644 --- a/.travis/osx..install.sh +++ b/.travis/osx..install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -PACKAGES="cmake pkgconfig fftw libogg libvorbis lame libsndfile libsamplerate jack sdl libgig libsoundio stk fluid-synth portaudio node fltk" +PACKAGES="cmake pkgconfig fftw libogg libvorbis lame libsndfile libsamplerate jack sdl libgig libsoundio stk fluid-synth portaudio node fltk carla" if [ $QT5 ]; then PACKAGES="$PACKAGES qt5" diff --git a/CMakeLists.txt b/CMakeLists.txt index 8be2f701f..452c05c5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -231,7 +231,11 @@ ENDIF(WANT_TAP) # check for CARLA IF(WANT_CARLA) - PKG_CHECK_MODULES(CARLA carla-standalone>=1.9.5) + PKG_CHECK_MODULES(CARLA carla-native-plugin) + # look for carla under old name + IF(NOT CARLA_FOUND) + PKG_CHECK_MODULES(CARLA carla-standalone>=1.9.5) + ENDIF() IF(CARLA_FOUND) SET(LMMS_HAVE_CARLA TRUE) SET(STATUS_CARLA "OK") diff --git a/cmake/apple/install_apple.sh.in b/cmake/apple/install_apple.sh.in index 057cf5445..259734208 100644 --- a/cmake/apple/install_apple.sh.in +++ b/cmake/apple/install_apple.sh.in @@ -21,14 +21,7 @@ echo -e "$MSG_COLOR\n\nCreating App Bundle \"$APP\"...$COLOR_RESET" # Locate macdeployqt, assume homebrew & Qt5 which macdeployqt > /dev/null 2>&1 if [ $? -ne 0 ]; then - brew --prefix qt55 > /dev/null 2>&1 - if [ $? -eq 0 ]; then - # Prefer Qt 5.5 (QTBUG-53533) - export PATH=$PATH:$(brew --prefix qt55)/bin - else - # Fallback Qt 5.6+ - export PATH=$PATH:$(brew --prefix qt5)/bin - fi + export PATH=$PATH:$(brew --prefix qt)/bin fi # Remove any old .app bundles @@ -71,6 +64,17 @@ install_name_tool -change @rpath/libZynAddSubFxCore.dylib \ @loader_path/../../$zynfmk \ "$APP/Contents/$zynlib" +# Replace @rpath with @loader_path for Carla +# See also plugins/carlabase/CMakeLists.txt +# This MUST be done BEFORE calling macdeployqt +install_name_tool -change @rpath/libcarlabase.dylib \ + @loader_path/libcarlabase.dylib \ + "$APP/Contents/lib/lmms/libcarlapatchbay.so" + +install_name_tool -change @rpath/libcarlabase.dylib \ + @loader_path/libcarlabase.dylib \ + "$APP/Contents/lib/lmms/libcarlarack.so" + # Link lmms binary _executables="${_executables} -executable=$APP/Contents/$zynbin" _executables="${_executables} -executable=$APP/Contents/$zynfmk" @@ -90,6 +94,27 @@ done # Finalize .app macdeployqt "$APP" $_executables +# Carla is a standalone plugin. Remove library, look for it side-by-side LMMS.app +# This MUST be done AFTER calling macdeployqt +# +# For example: +# /Applications/LMMS.app +# /Applications/Carla.app +carlalibs=$(echo "@CARLA_LIBRARIES@"|tr ";" "\n") + +# Loop over all libcarlas, fix linking +for file in "$APP/Contents/lib/lmms/"libcarla*; do + _thisfile="$APP/Contents/lib/lmms/${file##*/}" + for lib in $carlalibs; do + _oldpath="../../Frameworks/lib${lib}.dylib" + _newpath="Carla.app/Contents/MacOS/lib${lib}.dylib" + install_name_tool -change @loader_path/$_oldpath \ + @executable_path/../../../$_newpath \ + "$_thisfile" + rm -f "$APP/Contents/Frameworks/lib${lib}.dylib" + done +done + # Cleanup rm -rf "$APP/Contents/bin" echo -e "\nFinished.\n\n" diff --git a/cmake/modules/BuildPlugin.cmake b/cmake/modules/BuildPlugin.cmake index f1dd95db6..25cca92af 100644 --- a/cmake/modules/BuildPlugin.cmake +++ b/cmake/modules/BuildPlugin.cmake @@ -73,7 +73,11 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) INSTALL(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION "${PLUGIN_DIR}") IF(LMMS_BUILD_APPLE) - SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LINK_FLAGS "-bundle_loader \"${CMAKE_BINARY_DIR}/lmms\"") + IF ("${PLUGIN_LINK}" STREQUAL "SHARED") + SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") + ELSE() + SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LINK_FLAGS "-bundle_loader \"${CMAKE_BINARY_DIR}/lmms\"") + ENDIF() ADD_DEPENDENCIES(${PLUGIN_NAME} lmms) ENDIF(LMMS_BUILD_APPLE) IF(LMMS_BUILD_WIN32) diff --git a/plugins/carlabase/CMakeLists.txt b/plugins/carlabase/CMakeLists.txt index 8fdde2ec5..4fa81a491 100644 --- a/plugins/carlabase/CMakeLists.txt +++ b/plugins/carlabase/CMakeLists.txt @@ -1,3 +1,11 @@ +# For MacOS, use "OLD" RPATH install_name behavior +# This can be changed to "NEW" safely if install_apple.sh.in +# is updated to relink libcarlabase.dylib. MacOS 10.8 uses +# cmake 3.9.6, so this can be done at any time. +IF(NOT CMAKE_VERSION VERSION_LESS 3.9) + CMAKE_POLICY(SET CMP0068 OLD) +ENDIF() + if(LMMS_HAVE_CARLA) INCLUDE(BuildPlugin) INCLUDE_DIRECTORIES(${CARLA_INCLUDE_DIRS}) diff --git a/plugins/carlabase/carla.cpp b/plugins/carlabase/carla.cpp index 9221ad4f2..b25677f5c 100644 --- a/plugins/carlabase/carla.cpp +++ b/plugins/carlabase/carla.cpp @@ -1,7 +1,7 @@ /* * carla.cpp - Carla for LMMS * - * Copyright (C) 2014 Filipe Coelho + * Copyright (C) 2014-2018 Filipe Coelho * * This file is part of LMMS - https://lmms.io * @@ -24,9 +24,6 @@ #include "carla.h" -#define REAL_BUILD // FIXME this shouldn't be needed -#include "CarlaHost.h" - #include "Engine.h" #include "Song.h" #include "gui_templates.h" @@ -132,14 +129,6 @@ static const char* host_ui_save_file(NativeHostHandle, bool isDir, const char* t // ----------------------------------------------------------------------- -CARLA_EXPORT -const NativePluginDescriptor* carla_get_native_patchbay_plugin(); - -CARLA_EXPORT -const NativePluginDescriptor* carla_get_native_rack_plugin(); - -// ----------------------------------------------------------------------- - CarlaInstrument::CarlaInstrument(InstrumentTrack* const instrumentTrack, const Descriptor* const descriptor, const bool isPatchbay) : Instrument(instrumentTrack, descriptor), kIsPatchbay(isPatchbay), @@ -161,8 +150,9 @@ CarlaInstrument::CarlaInstrument(InstrumentTrack* const instrumentTrack, const D path.cdUp(); resourcesPath = path.absolutePath() + "/share/carla/resources"; #elif defined(CARLA_OS_MAC) - // assume standard install location - resourcesPath = "/Applications/Carla.app/Contents/MacOS/resources"; + // parse prefix from dll filename + QDir path = QFileInfo(dllName).dir(); + resourcesPath = path.absolutePath() + "/resources"; #elif defined(CARLA_OS_WIN32) || defined(CARLA_OS_WIN64) // not yet supported #endif @@ -254,7 +244,7 @@ void CarlaInstrument::handleUiClosed() emit uiClosed(); } -intptr_t CarlaInstrument::handleDispatcher(const NativeHostDispatcherOpcode opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt) +intptr_t CarlaInstrument::handleDispatcher(const NativeHostDispatcherOpcode opcode, const int32_t, const intptr_t, void* const, const float) { intptr_t ret = 0; @@ -267,13 +257,10 @@ intptr_t CarlaInstrument::handleDispatcher(const NativeHostDispatcherOpcode opco qApp->processEvents(); break; default: - break; + break; } return ret; - - // unused for now - (void)index; (void)value; (void)ptr; (void)opt; } // ------------------------------------------------------------------- @@ -448,9 +435,12 @@ bool CarlaInstrument::handleMidiEvent(const MidiEvent& event, const MidiTime&, f PluginView* CarlaInstrument::instantiateView(QWidget* parent) { +// Disable plugin focus per https://bugreports.qt.io/browse/QTBUG-30181 +#ifndef CARLA_OS_MAC if (QWidget* const window = parent->window()) fHost.uiParentId = window->winId(); else +#endif fHost.uiParentId = 0; std::free((char*)fHost.uiName); diff --git a/plugins/carlabase/carla.h b/plugins/carlabase/carla.h index 6431e5300..fb54e2271 100644 --- a/plugins/carlabase/carla.h +++ b/plugins/carlabase/carla.h @@ -1,7 +1,7 @@ /* * carla.h - Carla for LMMS * - * Copyright (C) 2014 Filipe Coelho + * Copyright (C) 2014-2018 Filipe Coelho * * This file is part of LMMS - https://lmms.io * @@ -27,7 +27,19 @@ #include -#include "CarlaNative.h" +#define REAL_BUILD // FIXME this shouldn't be needed +#if CARLA_VERSION_HEX >= 0x010911 + #include "CarlaNativePlugin.h" +#else + #include "CarlaBackend.h" + #include "CarlaNative.h" + #include "CarlaUtils.h" + CARLA_EXPORT + const NativePluginDescriptor* carla_get_native_patchbay_plugin(); + + CARLA_EXPORT + const NativePluginDescriptor* carla_get_native_rack_plugin(); +#endif #include "Instrument.h" #include "InstrumentView.h" @@ -44,7 +56,7 @@ public: CarlaInstrument(InstrumentTrack* const instrumentTrack, const Descriptor* const descriptor, const bool isPatchbay); virtual ~CarlaInstrument(); - // CarlaNative functions + // Carla NativeHostDescriptor functions uint32_t handleGetBufferSize() const; double handleGetSampleRate() const; bool handleIsOffline() const; diff --git a/plugins/carlapatchbay/carlapatchbay.cpp b/plugins/carlapatchbay/carlapatchbay.cpp index ae6ca1906..42786d18a 100644 --- a/plugins/carlapatchbay/carlapatchbay.cpp +++ b/plugins/carlapatchbay/carlapatchbay.cpp @@ -1,7 +1,7 @@ /* * carlapatchbay.cpp - Carla for LMMS (Patchbay) * - * Copyright (C) 2014 Filipe Coelho + * Copyright (C) 2014-2018 Filipe Coelho * * This file is part of LMMS - https://lmms.io * @@ -36,7 +36,7 @@ Plugin::Descriptor PLUGIN_EXPORT carlapatchbay_plugin_descriptor = QT_TRANSLATE_NOOP( "pluginBrowser", "Carla Patchbay Instrument" ), "falkTX ", - 0x0195, + CARLA_VERSION_HEX, Plugin::Instrument, new PluginPixmapLoader( "logo" ), NULL, diff --git a/plugins/carlarack/carlarack.cpp b/plugins/carlarack/carlarack.cpp index 0a52c63c5..2149e6604 100644 --- a/plugins/carlarack/carlarack.cpp +++ b/plugins/carlarack/carlarack.cpp @@ -1,7 +1,7 @@ /* * carlarack.cpp - Carla for LMMS (Rack) * - * Copyright (C) 2014 Filipe Coelho + * Copyright (C) 2014-2018 Filipe Coelho * * This file is part of LMMS - https://lmms.io * @@ -36,7 +36,7 @@ Plugin::Descriptor PLUGIN_EXPORT carlarack_plugin_descriptor = QT_TRANSLATE_NOOP( "pluginBrowser", "Carla Rack Instrument" ), "falkTX ", - 0x0195, + CARLA_VERSION_HEX, Plugin::Instrument, new PluginPixmapLoader( "logo" ), NULL, From 767607e0c891ac3dae477bea3c0c782b96ec0114 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Tue, 4 Sep 2018 21:55:35 +0200 Subject: [PATCH 126/445] Spelling fixes in German locale --- data/locale/de.ts | 62 +++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/data/locale/de.ts b/data/locale/de.ts index a02cecd7c..e6a1dafd5 100644 --- a/data/locale/de.ts +++ b/data/locale/de.ts @@ -428,7 +428,7 @@ Wenn Sie daran interessiert sind LMMS in eine andere Sprache zu übersetzen oder 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. - Ein höherer Spannungswert erzeugt villeicht eine glattere Kurve aber schießt teilweise über. Ein niederer Spannungswert wird die Kurve über jeden Kontrollpunkt legen. + Ein höherer Spannungswert erzeugt vielleicht eine glattere Kurve aber schießt teilweise über. Ein niederer Spannungswert wird die Kurve über jeden Kontrollpunkt legen. 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. @@ -843,7 +843,7 @@ Wenn Sie daran interessiert sind LMMS in eine andere Sprache zu übersetzen oder USER CONTROLLER - BENUTZERDEFINIETER CONTROLLER + BENUTZERDEFINIERTER CONTROLLER MAPPING FUNCTION @@ -1580,7 +1580,7 @@ Ein Recktsklick öffnet ein Kontextmenü, in dem Sie die Reihenfolge der Effekte 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. - Benutzen Sie diesen Regler, um die Modulationsintensität des aktuellen LFOs einzustellen. Je größer der Wert, desto mehr wird die gewählte Größe (z.B. Lautstärke oder Cuttoff-Frequenz) von diesem LFO beeinflusst. + Benutzen Sie diesen Regler, um die Modulationsintensität des aktuellen LFOs einzustellen. Je größer der Wert, desto mehr wird die gewählte Größe (z.B. Lautstärke oder Cutoff-Frequenz) von diesem LFO beeinflusst. Click here for a sine-wave. @@ -2570,7 +2570,7 @@ Sie können FX Kanäle im Kontextmenü entfernen und verschieben, welches durch 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. - Ein Arpeggio ist eine Art, (vorallem gezupfte) Instrumente zu spielen, die die Musik viel lebendiger macht. Die Seiten von solchen Instrumenten (z.B. Harfen) werden wie Akkorde gezupft, der einzige Unterschied besteht darin, dass dies nacheinander geschieht. Die Noten werden also nicht zur gleichen Zeit gespielt. Typische Arpeggios sind Dur- oder Moll-Dreiklänge, aber es gibt noch viele andere Akkorde, die Sie auswählen können. + Ein Arpeggio ist eine Art, (vor allem gezupfte) Instrumente zu spielen, die die Musik viel lebendiger macht. Die Seiten von solchen Instrumenten (z.B. Harfen) werden wie Akkorde gezupft, der einzige Unterschied besteht darin, dass dies nacheinander geschieht. Die Noten werden also nicht zur gleichen Zeit gespielt. Typische Arpeggios sind Dur- oder Moll-Dreiklänge, aber es gibt noch viele andere Akkorde, die Sie auswählen können. RANGE @@ -2586,7 +2586,7 @@ Sie können FX Kanäle im Kontextmenü entfernen und verschieben, welches durch Use this knob for setting the arpeggio range in octaves. The selected arpeggio will be played within specified number of octaves. - Benutzen Sie diesen Regler, um den Arpeggio-Bereich in Oktaven zu setzen. Das gewähle Arpeggio wird innerhalb der angegebenen Anzahl von Oktaven abgespielt. + Benutzen Sie diesen Regler, um den Arpeggio-Bereich in Oktaven zu setzen. Das gewählte Arpeggio wird innerhalb der angegebenen Anzahl von Oktaven abgespielt. TIME @@ -3080,7 +3080,7 @@ Sie können FX Kanäle im Kontextmenü entfernen und verschieben, welches durch Use this knob for setting the chord range in octaves. The selected chord will be played within specified number of octaves. - Benutzen Sie diesen Regler, um den Akkord-Bereich in Oktaven zu setzen. Der gewähle Akkord wird innerhalb der angegebenen Anzahl von Oktaven abgespielt. + Benutzen Sie diesen Regler, um den Akkord-Bereich in Oktaven zu setzen. Der gewählte Akkord wird innerhalb der angegebenen Anzahl von Oktaven abgespielt. STACKING @@ -3485,7 +3485,7 @@ Sie können FX Kanäle im Kontextmenü entfernen und verschieben, welches durch Save current instrument track settings in a preset file - Aktuelle Instrumentenspur-Einstelungen in einer Presetdatei speichern + Aktuelle Instrumentenspur-Einstellungen in einer Presetdatei speichern 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. @@ -3680,7 +3680,7 @@ Sie können FX Kanäle im Kontextmenü entfernen und verschieben, welches durch 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. - Benutzen Sie diesen Regler, um die Modulationsintensität des LFOs einzustellen. Je größer der Wert, desto mehr wird die gewählte Größe (z.B. Lautstärke oder Cuttoff-Frequenz) von diesem LFO beeinflusst. + Benutzen Sie diesen Regler, um die Modulationsintensität des LFOs einzustellen. Je größer der Wert, desto mehr wird die gewählte Größe (z.B. Lautstärke oder Cutoff-Frequenz) von diesem LFO beeinflusst. PHS @@ -3998,7 +3998,7 @@ Bitte besuchen Sie http://lmms.sf.net/wiki für Dokumentationen über LMMS. Project recovery - Project wiederherstellen + Projekt wiederherstellen 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? @@ -4026,11 +4026,11 @@ Bitte besuchen Sie http://lmms.sf.net/wiki für Dokumentationen über LMMS. Preparing file browsers - Dateimanger vorbereiten + Dateimanager vorbereiten Root directory - Grundverzeichniss + Grundverzeichnis Loading background artwork @@ -4289,7 +4289,7 @@ Please make sure you have write permission to the file and the directory contain Osc 1 Pulse width - Oszilator 1 Pulsweite + Oszillator 1 Pulsweite Osc 1 Sync send on rise @@ -4649,7 +4649,7 @@ Please make sure you have write permission to the file and the directory contain Bandlimited Triangle wave - Bandlimittierte Dreieckwelle + Bandlimitierte Dreieckwelle Bandlimited Saw wave @@ -4816,11 +4816,11 @@ Jedes Modulationsziel hat 4 Regler, einen für jeden Modulator. Standardmäßig Hard sync: Every time the oscillator receives a sync signal from oscillator 1, its phase is reset to 0 + whatever its phase offset is. - Hard sync: Jedes Mal, wenn der Oszillator ein sync-Signal von Oszillator 1 empfäng, wird die Phase auf 0 zurückgesetzt, egal was die Phasendifferenz ist. + Hard sync: Jedes Mal, wenn der Oszillator ein sync-Signal von Oszillator 1 empfängt, wird die Phase auf 0 zurückgesetzt, egal was die Phasendifferenz ist. Reverse sync: Every time the oscillator receives a sync signal from oscillator 1, the amplitude of the oscillator gets inverted. - Reverse sync: Jedes Mal, wenn der Oszillator ein sync-Signal von Oszillator 1 empfäng, wird die Amplitude des Oszillators invertiert. + Reverse sync: Jedes Mal, wenn der Oszillator ein sync-Signal von Oszillator 1 empfängt, wird die Amplitude des Oszillators invertiert. Choose waveform for oscillator 2. @@ -4912,7 +4912,7 @@ PM bedeutet Phasen-Modulation: Die Phase von Oszillator 3 wird durch Oszillator 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. - SUS, oder Dauerpegel, kontrolliert den Dauerpgel der Hüllkurve. Die Abfall-Phase geht nicht unter diesen Pegel, solange die Note gehalten wird. + SUS, oder Dauerpegel, kontrolliert den Dauerpegel der Hüllkurve. Die Abfall-Phase geht nicht unter diesen Pegel, solange die Note gehalten wird. 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. @@ -5436,7 +5436,7 @@ PM bedeutet Phasen-Modulation: Die Phase von Oszillator 3 wird durch Oszillator 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. - Aufgrud eines Fehlers in einer älteren Version von LMMS, sind die Peak Controller möglicherweise nicht richtig verbunden. Bitte stellen Sie sicher, dass die Peak Controller richtig verbunden sind und speichern Sie die Datei erneut. Entschuldigung für jegliche verursachte Unannehmlichkeiten. + Aufgrund eines Fehlers in einer älteren Version von LMMS, sind die Peak Controller möglicherweise nicht richtig verbunden. Bitte stellen Sie sicher, dass die Peak Controller richtig verbunden sind und speichern Sie die Datei erneut. Entschuldigung für jegliche verursachte Unannehmlichkeiten. @@ -6376,19 +6376,19 @@ Latenz: %2 ms Themes directory - Themen Verzeichniss + Themen Verzeichnis GIG directory - GIG Verzeichniss + GIG Verzeichnis SF2 directory - SF2 Verzeichniss + SF2 Verzeichnis LADSPA plugin directories - LADSPA Plugin Verzeichniss + LADSPA Plugin Verzeichnisse Auto save @@ -7515,19 +7515,19 @@ Bitte stellen Sie sicher, dass Sie Leserechte auf diese Datei sowie das Verzeich WatsynView Select oscillator A1 - Oszilator A1 auswählen + Oszillator A1 auswählen Select oscillator A2 - Oszilator A2 auswählen + Oszillator A2 auswählen Select oscillator B1 - Oszilator B1 auswählen + Oszillator B1 auswählen Select oscillator B2 - Oszilator B2 auswählen + Oszillator B2 auswählen Mix output of A2 to A1 @@ -8570,7 +8570,7 @@ Doppelklicken auf eines der Plugins zeigt Informaitonen über die Ports an. Bandlimited triangle wave - Bandlimittierte Dreieckwelle + Bandlimitierte Dreieckwelle Click here for bandlimited triangle wave. @@ -8909,7 +8909,7 @@ Doppelklicken auf eines der Plugins zeigt Informaitonen über die Ports an. Op 1 Level - Op 1 Strärke + Op 1 Stärke Op 1 Level Scaling @@ -8961,7 +8961,7 @@ Doppelklicken auf eines der Plugins zeigt Informaitonen über die Ports an. Op 2 Level - Op 2 Strärke + Op 2 Stärke Op 2 Level Scaling @@ -9867,7 +9867,7 @@ Dieser Chip wurde in Commodore 64 Computern genutzt. 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. - Wenn gefilter an ist, wird Stimme %1 durch den Filter verarbeitet. Wenn gefiltert aus ist, wird Stimme %1 direckt an die Ausgabe weitergeleitet und der Filter hat keine Auswirkung darauf. + Wenn gefilter an ist, wird Stimme %1 durch den Filter verarbeitet. Wenn gefiltert aus ist, wird Stimme %1 direkt an die Ausgabe weitergeleitet und der Filter hat keine Auswirkung darauf. Test @@ -10064,7 +10064,7 @@ Dieser Chip wurde in Commodore 64 Computern genutzt. Octave - Okatve + Oktave 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. @@ -10312,4 +10312,4 @@ Die LED rechts unterhalb der Wellenform gibt an, ob die Saite aktiviert ist.Ausgabeverstärkung - \ No newline at end of file + From 20e4668d85711ea67d1341b9cbd7db78b721ecd2 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Tue, 4 Sep 2018 22:49:08 +0200 Subject: [PATCH 127/445] Replace deprecated `QDrag::start` by `QDrag::exec` --- src/gui/StringPairDrag.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/StringPairDrag.cpp b/src/gui/StringPairDrag.cpp index f754e2d39..b2b3b0c4a 100644 --- a/src/gui/StringPairDrag.cpp +++ b/src/gui/StringPairDrag.cpp @@ -53,7 +53,7 @@ StringPairDrag::StringPairDrag( const QString & _key, const QString & _value, QMimeData * m = new QMimeData(); m->setData( mimeType(), txt.toUtf8() ); setMimeData( m ); - start( Qt::IgnoreAction ); + exec( Qt::LinkAction, Qt::LinkAction ); } From dd7b0865fbb212e5df178048f5c271d2fbaa5cdf Mon Sep 17 00:00:00 2001 From: Karmo Rosental Date: Mon, 17 Sep 2018 17:49:25 +0300 Subject: [PATCH 128/445] Update UI 60 times per second (#4570) * Update UI 60 times per second * Adjust falloff values --- plugins/Eq/EqFader.h | 6 +++--- plugins/Eq/EqSpectrumView.cpp | 2 +- src/gui/FxMixerView.cpp | 6 +++--- src/gui/MainWindow.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/Eq/EqFader.h b/plugins/Eq/EqFader.h index 6f9b26615..c588c2b92 100644 --- a/plugins/Eq/EqFader.h +++ b/plugins/Eq/EqFader.h @@ -80,7 +80,7 @@ private slots: { const float opl = getPeak_L(); const float opr = getPeak_R(); - const float fall_off = 1.2; + const float fallOff = 1.07; if( *m_lPeak > opl ) { setPeak_L( *m_lPeak ); @@ -88,7 +88,7 @@ private slots: } else { - setPeak_L( opl/fall_off ); + setPeak_L( opl/fallOff ); } if( *m_rPeak > opr ) @@ -98,7 +98,7 @@ private slots: } else { - setPeak_R( opr/fall_off ); + setPeak_R( opr/fallOff ); } update(); } diff --git a/plugins/Eq/EqSpectrumView.cpp b/plugins/Eq/EqSpectrumView.cpp index d44e01ece..677c896fb 100644 --- a/plugins/Eq/EqSpectrumView.cpp +++ b/plugins/Eq/EqSpectrumView.cpp @@ -224,7 +224,7 @@ void EqSpectrumView::paintEvent(QPaintEvent *event) float peak; m_path.moveTo( 0, height() ); m_peakSum = 0; - float fallOff = 1.2; + const float fallOff = 1.07; for( int x = 0; x < MAX_BANDS; ++x, ++bands ) { peak = ( fh * 2.0 / 3.0 * ( 20 * ( log10( *bands / energy ) ) - LOWER_Y ) / ( - LOWER_Y ) ); diff --git a/src/gui/FxMixerView.cpp b/src/gui/FxMixerView.cpp index 8da1cb4e0..edeaceb54 100644 --- a/src/gui/FxMixerView.cpp +++ b/src/gui/FxMixerView.cpp @@ -579,7 +579,7 @@ void FxMixerView::updateFaders() { const float opl = m_fxChannelViews[i]->m_fader->getPeak_L(); const float opr = m_fxChannelViews[i]->m_fader->getPeak_R(); - const float fall_off = 1.2; + const float fallOff = 1.07; if( m->effectChannel(i)->m_peakLeft > opl ) { m_fxChannelViews[i]->m_fader->setPeak_L( m->effectChannel(i)->m_peakLeft ); @@ -587,7 +587,7 @@ void FxMixerView::updateFaders() } else { - m_fxChannelViews[i]->m_fader->setPeak_L( opl/fall_off ); + m_fxChannelViews[i]->m_fader->setPeak_L( opl/fallOff ); } if( m->effectChannel(i)->m_peakRight > opr ) @@ -597,7 +597,7 @@ void FxMixerView::updateFaders() } else { - m_fxChannelViews[i]->m_fader->setPeak_R( opr/fall_off ); + m_fxChannelViews[i]->m_fader->setPeak_R( opr/fallOff ); } } } diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index fa6958cef..d82d5befe 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -209,7 +209,7 @@ MainWindow::MainWindow() : vbox->addWidget( w ); setCentralWidget( main_widget ); - m_updateTimer.start( 1000 / 20, this ); // 20 fps + m_updateTimer.start( 1000 / 60, this ); // 60 fps if( ConfigManager::inst()->value( "ui", "enableautosave" ).toInt() ) { From 78142cee3d4085f21f94318762bc9cdb43950580 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 18 Sep 2018 09:56:09 +0900 Subject: [PATCH 129/445] Update ZynAddSubFX submodule --- plugins/zynaddsubfx/zynaddsubfx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/zynaddsubfx/zynaddsubfx b/plugins/zynaddsubfx/zynaddsubfx index 9cd29e224..c22acd61e 160000 --- a/plugins/zynaddsubfx/zynaddsubfx +++ b/plugins/zynaddsubfx/zynaddsubfx @@ -1 +1 @@ -Subproject commit 9cd29e224320c40b00343b7e49e586ef25733a71 +Subproject commit c22acd61eb5d074988acea5fc1b6930151345c42 From 00cc6dc22ba857243de64340ac77969716244534 Mon Sep 17 00:00:00 2001 From: Z3R0C <32363130+Z3R0C@users.noreply.github.com> Date: Tue, 18 Sep 2018 04:21:45 +0200 Subject: [PATCH 130/445] Fix sample track playback crash (#4586) Fixes double-freeing `AudioPort` which is a regression in #4310. Co-authored-by: Shmuel H Co-authored-by: Hyunjin Song --- include/SamplePlayHandle.h | 5 +++-- src/core/SamplePlayHandle.cpp | 14 ++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/include/SamplePlayHandle.h b/include/SamplePlayHandle.h index 9a051ec7b..d10c44837 100644 --- a/include/SamplePlayHandle.h +++ b/include/SamplePlayHandle.h @@ -1,8 +1,9 @@ + /* * SamplePlayHandle.h - play-handle for playing a sample * * Copyright (c) 2005-2014 Tobias Doerffel - * + * * This file is part of LMMS - https://lmms.io * * This program is free software; you can redistribute it and/or @@ -38,7 +39,7 @@ class AudioPort; class SamplePlayHandle : public PlayHandle { public: - SamplePlayHandle( SampleBuffer* sampleBuffer ); + SamplePlayHandle( SampleBuffer* sampleBuffer , bool ownAudioPort = true ); SamplePlayHandle( const QString& sampleFile ); SamplePlayHandle( SampleTCO* tco ); virtual ~SamplePlayHandle(); diff --git a/src/core/SamplePlayHandle.cpp b/src/core/SamplePlayHandle.cpp index 549a6c3a5..cae2f3cde 100644 --- a/src/core/SamplePlayHandle.cpp +++ b/src/core/SamplePlayHandle.cpp @@ -32,35 +32,37 @@ -SamplePlayHandle::SamplePlayHandle( SampleBuffer* sampleBuffer ) : +SamplePlayHandle::SamplePlayHandle( SampleBuffer* sampleBuffer , bool ownAudioPort ) : PlayHandle( TypeSamplePlayHandle ), m_sampleBuffer( sharedObject::ref( sampleBuffer ) ), m_doneMayReturnTrue( true ), m_frame( 0 ), - m_ownAudioPort( true ), + m_ownAudioPort( ownAudioPort ), m_defaultVolumeModel( DefaultVolume, MinVolume, MaxVolume, 1 ), m_volumeModel( &m_defaultVolumeModel ), m_track( NULL ), m_bbTrack( NULL ) { - setAudioPort( new AudioPort( "SamplePlayHandle", false ) ); + if (ownAudioPort) + { + setAudioPort( new AudioPort( "SamplePlayHandle", false ) ); + } } SamplePlayHandle::SamplePlayHandle( const QString& sampleFile ) : - SamplePlayHandle( new SampleBuffer( sampleFile ) ) + SamplePlayHandle( new SampleBuffer( sampleFile ) , true) { sharedObject::unref( m_sampleBuffer ); - setAudioPort( new AudioPort( "SamplePlayHandle", false ) ); } SamplePlayHandle::SamplePlayHandle( SampleTCO* tco ) : - SamplePlayHandle( tco->sampleBuffer() ) + SamplePlayHandle( tco->sampleBuffer() , false) { m_track = tco->getTrack(); setAudioPort( ( (SampleTrack *)tco->getTrack() )->audioPort() ); From 9fe74c273098c006045d9ebd58adc0f9a36651ce Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 19 Sep 2018 19:52:08 +0900 Subject: [PATCH 131/445] Specify infinte timeout in tryLock on export Ensures remote plugins always process sound on export. Follow-up of 408b72c798cddb6d837cd09d83f3369f9f3b98f1. --- plugins/VstEffect/VstEffect.cpp | 2 +- plugins/vestige/vestige.cpp | 3 ++- plugins/zynaddsubfx/ZynAddSubFx.cpp | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/VstEffect/VstEffect.cpp b/plugins/VstEffect/VstEffect.cpp index 05cc7a070..10005d744 100644 --- a/plugins/VstEffect/VstEffect.cpp +++ b/plugins/VstEffect/VstEffect.cpp @@ -95,7 +95,7 @@ bool VstEffect::processAudioBuffer( sampleFrame * _buf, const fpp_t _frames ) sampleFrame * buf = new sampleFrame[_frames]; #endif memcpy( buf, _buf, sizeof( sampleFrame ) * _frames ); - if (m_pluginMutex.tryLock()) + if (m_pluginMutex.tryLock(Engine::getSong()->isExporting() ? -1 : 0)) { m_plugin->process( buf, buf ); m_pluginMutex.unlock(); diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index b958e8ddf..c31611626 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -47,6 +47,7 @@ #include "GuiApplication.h" #include "PixmapButton.h" #include "SampleBuffer.h" +#include "Song.h" #include "StringPairDrag.h" #include "TextFloat.h" #include "ToolTip.h" @@ -360,7 +361,7 @@ void vestigeInstrument::loadFile( const QString & _file ) void vestigeInstrument::play( sampleFrame * _buf ) { - if (!m_pluginMutex.tryLock()) {return;} + if (!m_pluginMutex.tryLock(Engine::getSong()->isExporting() ? -1 : 0)) {return;} const fpp_t frames = Engine::mixer()->framesPerPeriod(); diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index 49a97d35e..a0f381971 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -40,6 +40,7 @@ #include "InstrumentPlayHandle.h" #include "InstrumentTrack.h" #include "gui_templates.h" +#include "Song.h" #include "StringPairDrag.h" #include "RemoteZynAddSubFx.h" #include "LocalZynAddSubFx.h" @@ -325,7 +326,7 @@ QString ZynAddSubFxInstrument::nodeName() const void ZynAddSubFxInstrument::play( sampleFrame * _buf ) { - if (!m_pluginMutex.tryLock()) {return;} + if (!m_pluginMutex.tryLock(Engine::getSong()->isExporting() ? -1 : 0)) {return;} if( m_remotePlugin ) { m_remotePlugin->process( NULL, _buf ); From 222b28a71e67f7319cebb02351431bf14922197f Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Fri, 21 Sep 2018 10:32:38 +0900 Subject: [PATCH 132/445] Add '-Wno-misleading-indentation' only for GCC >= 6 --- plugins/zynaddsubfx/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/zynaddsubfx/CMakeLists.txt b/plugins/zynaddsubfx/CMakeLists.txt index bdc10bf32..e083a30a9 100644 --- a/plugins/zynaddsubfx/CMakeLists.txt +++ b/plugins/zynaddsubfx/CMakeLists.txt @@ -20,7 +20,11 @@ IF(LMMS_HOST_X86 OR LMMS_HOST_X86_64) ENDIF(LMMS_HOST_X86 OR LMMS_HOST_X86_64) # build ZynAddSubFX with full optimizations -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wno-misleading-indentation -Wno-write-strings -Wno-deprecated-declarations -fpermissive") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wno-write-strings -Wno-deprecated-declarations -fpermissive") + +IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND NOT "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "6.0.0") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-misleading-indentation") +ENDIF() IF(LMMS_BUILD_WIN32) # link system-libraries From 93dc557c56269243b7bd3c7d9f75880fb74a17a8 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz <1042576+JohannesLorenz@users.noreply.github.com> Date: Mon, 24 Sep 2018 03:17:39 +0200 Subject: [PATCH 133/445] Add bash completion (#4534) (#4604) * Add bash completion (#4534) --- cmake/modules/BashCompletion.cmake | 92 ++++++++ doc/CMakeLists.txt | 3 + doc/bash-completion/CMakeLists.txt | 4 + doc/bash-completion/lmms | 334 +++++++++++++++++++++++++++++ 4 files changed, 433 insertions(+) create mode 100644 cmake/modules/BashCompletion.cmake create mode 100644 doc/bash-completion/CMakeLists.txt create mode 100644 doc/bash-completion/lmms diff --git a/cmake/modules/BashCompletion.cmake b/cmake/modules/BashCompletion.cmake new file mode 100644 index 000000000..0dc016178 --- /dev/null +++ b/cmake/modules/BashCompletion.cmake @@ -0,0 +1,92 @@ +# A wrapper around pkg-config-provided and cmake-provided bash completion that +# will have dynamic behavior at INSTALL() time to allow both root-level +# INSTALL() as well as user-level INSTALL(). +# +# See also https://github.com/scop/bash-completion +# +# Copyright (c) 2018, Tres Finocchiaro, +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# +# Usage: +# INCLUDE(BashCompletion) +# BASHCOMP_INSTALL(foo) +# ... where "foo" is a shell script adjacent to the CMakeLists.txt +# +# How it determines BASHCOMP_PKG_PATH, in order: +# 1. Uses BASHCOMP_PKG_PATH if already set (e.g. -DBASHCOMP_PKG_PATH=...) +# a. If not, uses pkg-config's PKG_CHECK_MODULES to determine path +# b. Fallback to cmake's FIND_PACKAGE(bash-completion) path +# c. Fallback to hard-coded /usr/share/bash-completion/completions +# 2. Final fallback to ${CMAKE_INSTALL_PREFIX}/share/bash-completion/completions if +# detected path is unwritable. + +# - Windows does not support bash completion +# - macOS support should eventually be added for Homebrew (TODO) +IF(WIN32) + MESSAGE(STATUS "Bash competion is not supported on this platform.") +ELSEIF(APPLE) + MESSAGE(STATUS "Bash completion is not yet implemented for this platform.") +ELSE() + INCLUDE(FindUnixCommands) + # Honor manual override if provided + IF(NOT BASHCOMP_PKG_PATH) + # First, use pkg-config, which is the most reliable + FIND_PACKAGE(PkgConfig QUIET) + IF(PKGCONFIG_FOUND) + PKG_CHECK_MODULES(BASH_COMPLETION bash-completion) + PKG_GET_VARIABLE(BASHCOMP_PKG_PATH bash-completion completionsdir) + ELSE() + # Second, use cmake (preferred but less common) + FIND_PACKAGE(bash-completion QUIET) + IF(BASH_COMPLETION_FOUND) + SET(BASHCOMP_PKG_PATH "${BASH_COMPLETION_COMPLETIONSDIR}") + ENDIF() + ENDIF() + + # Third, use a hard-coded fallback value + IF("${BASHCOMP_PKG_PATH}" STREQUAL "") + SET(BASHCOMP_PKG_PATH "/usr/share/bash-completion/completions") + ENDIF() + ENDIF() + + # Always provide a fallback for non-root INSTALL() + SET(BASHCOMP_USER_PATH "${CMAKE_INSTALL_PREFIX}/share/bash-completion/completions") + + # Cmake doesn't allow easy use of conditional logic at INSTALL() time + # this is a problem because ${BASHCOMP_PKG_PATH} may not be writable and we + # need sane fallback behavior for bundled INSTALL() (e.g. .AppImage, etc). + # + # The reason this can't be detected by cmake is that it's fairly common to + # run "cmake" as a one user (i.e. non-root) and "make install" as another user + # (i.e. root). + # + # - Creates a script called "install_${SCRIPT_NAME}_completion.sh" into the + # working binary directory and invokes this script at install. + # - Script handles INSTALL()-time conditional logic for sane ballback behavior + # when ${BASHCOMP_PKG_PATH} is unwritable (i.e. non-root); Something cmake + # can't handle on its own at INSTALL() time) + MACRO(BASHCOMP_INSTALL SCRIPT_NAME) + # A shell script for wrapping conditionl logic + SET(BASHCOMP_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/install_${SCRIPT_NAME}_completion.sh") + + 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\ +fi\n\ +echo -e \"\\nInstalling bash completion...\\n\"\n\ +mkdir -p \"\$BASHCOMP_PKG_PATH\"\n\ +cp \"${CMAKE_CURRENT_SOURCE_DIR}/${SCRIPT_NAME}\" \"\$BASHCOMP_PKG_PATH\"\n\ +chmod a+r \"\$BASHCOMP_PKG_PATH/${SCRIPT_NAME}\"\n\ +echo -e \"Bash completion for ${SCRIPT_NAME} has been installed to \$BASHCOMP_PKG_PATH/${SCRIPT_NAME}\"\n\ +") + INSTALL(CODE "EXECUTE_PROCESS(COMMAND chmod u+x \"install_${SCRIPT_NAME}_completion.sh\" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} )") + INSTALL(CODE "EXECUTE_PROCESS(COMMAND \"./install_${SCRIPT_NAME}_completion.sh\" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} )") + + MESSAGE(STATUS "Bash completion script for ${SCRIPT_NAME} will be installed to ${BASHCOMP_PKG_PATH} or fallback to ${BASHCOMP_USER_PATH} if unwritable.") + ENDMACRO() +ENDIF() + diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 7aca74d87..859c5f2c6 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -15,3 +15,6 @@ if(DOXYGEN_FOUND) COMMENT "Generating API documentation with Doxygen" SOURCES Doxyfile.in) endif(DOXYGEN_FOUND) + +ADD_SUBDIRECTORY(bash-completion) + diff --git a/doc/bash-completion/CMakeLists.txt b/doc/bash-completion/CMakeLists.txt new file mode 100644 index 000000000..783e13a71 --- /dev/null +++ b/doc/bash-completion/CMakeLists.txt @@ -0,0 +1,4 @@ +INCLUDE(BashCompletion) +IF(COMMAND BASHCOMP_INSTALL) + BASHCOMP_INSTALL(lmms) +ENDIF() diff --git a/doc/bash-completion/lmms b/doc/bash-completion/lmms new file mode 100644 index 000000000..19fbf4723 --- /dev/null +++ b/doc/bash-completion/lmms @@ -0,0 +1,334 @@ +# lmms(1) completion -*- shell-script -*- +# use shellcheck: "shellcheck -e bash " + +_lmms_array_contains () +{ + local e match="$1" + shift + for e; do [[ "$e" == "$match" ]] && return 0; done + return 1 +} + +_lmms_long_param_of() +{ + case "$1" in + -a) + echo "float" + ;; + -b) + echo "bitrate" + ;; + -c) + echo "config" + ;; + -f) + echo "format" + ;; + -i) + echo "interpolation" + ;; + -l) + echo "loop" + ;; + -m) + echo "mode" + ;; + -o) + echo "output" + ;; + -p) + echo "profile" + ;; + -s) + echo "samplerate" + ;; + -x) + echo "oversampling" + ;; + *) + echo "" + ;; + esac +} + +_lmms_conv_old_action () +{ + case "$1" in + -d|--dump) + echo "dump" + ;; + -r|--render) + echo "render" + ;; + --rendertracks) + echo "rendertracks" + ;; + -u|--upgrade) + echo "upgrade" + ;; + *) + echo "" + ;; + esac +} + +_lmms() +{ + local cword=$COMP_CWORD + local cur="${COMP_WORDS[COMP_CWORD]}" + + # call routine provided by bash-completion + _init_completion || return + + local params filemode filetypes + local i # counter variable + local pars_global pars_noaction pars_render actions shortargs + pars_global=(--allowroot --config --help --version) + pars_noaction=(--geometry --import) + pars_render=(--float --bitrate --format --interpolation) + pars_render+=(--loop --mode --output --profile) + pars_render+=(--samplerate --oversampling) + actions=(dump render rendertracks upgrade) + actions_old=(-d --dump -r --render --rendertracks -u --upgrade) + shortargs+=(-a -b -c -f -h -i -l -m -o -p -s -v -x) + + local prev prev2 + if [ "$cword" -gt 1 ] + then + prev=${COMP_WORDS[cword-1]} + fi + if [ "$cword" -gt 2 ] + then + prev2=${COMP_WORDS[cword-2]} + fi + + # don't show shortargs, but complete them when entered + if [[ $cur =~ ^-[^-]$ ]] + then + if _lmms_array_contains "$cur" "${shortargs[@]}" + then + COMPREPLY=( "$cur" ) + fi + return + fi + + # + # please keep those in order like def_pars_args above + # + case $prev in + --bitrate|-b) + params="64 96 128 160 192 256 320" + ;; + --config|-c) + filetypes='xml' + filemode='existing_files' + ;; + --format|-f) + params='wav ogg mp3' + ;; + --geometry) + # we can not name all possibilities, but this helps the user + # by showing them how the format is + params='0x0+0+0' + ;; + --interpolation|-i) + params='linear sincfastest sincmedium sincbest' + ;; + --import) + filetypes='mid|midi|MID|MIDI|rmi|RMI|h2song|H2SONG' + filemode='existing_files' + ;; + --mode|-m) + params='s j m' + ;; + --output|-o) + # default assumption: could be both + local render=1 rendertracks=1 + for i in "${!COMP_WORDS[@]}" + do + if [[ ${COMP_WORDS[i]} =~ ^(render|-r|--render)$ ]] + then + rendertracks= + elif [[ ${COMP_WORDS[i]} =~ ^(rendertracks|--rendertracks)$ ]] + then + render= + fi + done + if [ "$rendertracks" ] + then + filemode='existing_directories' + fi + if [ "$render" ] + then + # filemode files is a superset of "existing directories" + # so it's OK to overwrite the filemode='existing_directories' + # from above + filetypes='wav|ogg|mp3' + filemode='files' + fi + ;; + --profile|-p) + filemode='files' + ;; + --samplerate|-s) + # these are the ones suggested for zyn + # if you think more are required, + # remove this comment and write a justification + params='44100 48000 96000 192000' + ;; + --oversampling|-x) + params='1 2 4 8' + ;; + *) + local action_found + + # Is an action specified? + if [ "$cword" -gt 1 ] + then + local wrd + for wrd in "${COMP_WORDS[@]}" + do + # action named explicitly? + if _lmms_array_contains "$wrd" "${actions[@]}" + then + action_found=$wrd + break + # deprecated action name? + elif _lmms_array_contains "$wrd" "${actions_old[@]}" + then + action_found="$(_lmms_conv_old_action "$wrd")" + break + # no-action params found? + elif _lmms_array_contains "$wrd" "${pars_noaction[@]}" + then + action_found=none + break + fi + done + fi + + if [[ $prev =~ -e|--help|-h|-version|-v ]] + then + # the -e flag (from --import) and help/version + # always mark the end of arguments + return + fi + + if [[ "$action_found" =~ dump|none|^$ ]] && [[ $prev =~ \.mmpz? ]] + then + # mmp(z) mark the end of arguments for those actions + return + fi + + local savefiletypes='mmpz|mmp' + local params_array + + # find parameters/filetypes/dirtypes depending on actions + if ! [ "$action_found" ] + then + params_array=( "${actions[@]}" "${pars_global[@]}" "${pars_noaction[@]}") + filemode="existing_files" + filetypes="$savefiletypes" + elif [ "$action_found" == "none" ] + then + params_array=( "${pars_noaction[@]}" ) + filemode="existing_files" + filetypes="$savefiletypes" + elif [ "$action_found" == "dump" ] + then + filemode="existing_files" + filetypes="mmpz" + elif [ "$action_found" == "upgrade" ] + then + if [ "$prev" == "upgrade" ] + then + filemode="existing_files" + filetypes="$savefiletypes" + elif [ "$prev2" == "upgrade" ] + then + filemode="files" + filetypes="$savefiletypes" + fi + elif [[ "$action_found" =~ render(tracks)? ]] + then + if [[ "$prev" =~ render(tracks)? ]] + then + filemode="existing_files" + filetypes="$savefiletypes" + else + params_array=( "${pars_render[@]}" ) + fi + fi + + # add params_array to params, but also check the history of comp words + local param + for param in "${params_array[@]}" + do + local do_append=1 + for i in "${!COMP_WORDS[@]}" + do + if [ "$i" -ne 0 ] && [ "$i" -ne "$cword" ] + then + # disallow double long parameters + if [ "${COMP_WORDS[$i]}" == "$param" ] + then + do_append= + # disallow double short parameters + elif [ "--$(_lmms_long_param_of "${COMP_WORDS[$i]}")" == "$param" ] + then + do_append= + # --help or --version must be the first parameters + elif [ "$cword" -gt 1 ] && [[ $param =~ --help|--version ]] + then + do_append= + fi + fi + done + if [ "$do_append" ] + then + params+="$param " + fi + done + ;; + esac + + case $filemode in + + # use completion routine provided by bash-completion + # to fill $COMPREPLY + + existing_files) + _filedir "@($filetypes)" + ;; + + existing_directories) + _filedir -d + ;; + + files) + + # non existing files complete like directories... + _filedir -d + + # ...except for non-completing files with the right file type + if [ ${#COMPREPLY[@]} -eq 0 ] + then + if ! [[ "$cur" =~ /$ ]] && [ "$filetypes" ] && [[ "$cur" =~ \.($filetypes)$ ]] + then + # file ending fits, we seem to be done + COMPREPLY=( "$cur" ) + fi + fi + ;; + + esac + + if [ "$params" ] + then + # none of our parameters contain spaces, so deactivate shellcheck's warning + # shellcheck disable=SC2207 + COMPREPLY+=( $(compgen -W "${params}" -- "${cur}") ) + fi +} + +complete -F _lmms lmms From 8154f886ed0d06f1915be179291507b6f1625443 Mon Sep 17 00:00:00 2001 From: Umcaruje Date: Mon, 24 Sep 2018 11:09:49 +0200 Subject: [PATCH 134/445] Update the LMMS logo and mimetypes (#4519) * Update the LMMS logo and mimetypes * fix bmp for nsis installer * Update window and About icons, rename icons, change the file association logic * Fix NSIS * Revert nsh patch * Fix small icon * Always write DefaultIcon in the registry * Fix file permissions * Fix nsis branding * Fix nsis branding #2 * update the icon windows and linux * Update apple icon, add windows visual manifest * try to fix windows installation * typo * typo 2 * Set small logo to conform to 48x48 grid --- cmake/apple/CMakeLists.txt | 2 +- cmake/apple/icon.icns | Bin 0 -> 44942 bytes cmake/apple/lmms.icns | Bin 280023 -> 0 bytes cmake/apple/project.icns | Bin 205223 -> 29340 bytes cmake/linux/CMakeLists.txt | 3 +- cmake/linux/icons/128x128/apps/lmms.png | Bin 0 -> 4499 bytes .../mimetypes/application-x-lmms-project.png | Bin 0 -> 2744 bytes cmake/linux/icons/128x128@2/apps/lmms.png | Bin 0 -> 8656 bytes .../mimetypes/application-x-lmms-project.png | Bin 0 -> 5331 bytes cmake/linux/icons/16x16/apps/lmms.png | Bin 0 -> 549 bytes .../mimetypes/application-x-lmms-project.png | Bin 0 -> 446 bytes cmake/linux/icons/16x16@2/apps/lmms.png | Bin 0 -> 934 bytes .../mimetypes/application-x-lmms-project.png | Bin 0 -> 771 bytes cmake/linux/icons/24x24/apps/lmms.png | Bin 0 -> 799 bytes .../mimetypes/application-x-lmms-project.png | Bin 0 -> 681 bytes cmake/linux/icons/24x24@2/apps/lmms.png | Bin 0 -> 1449 bytes .../mimetypes/application-x-lmms-project.png | Bin 0 -> 1160 bytes cmake/linux/icons/32x32/apps/lmms.png | Bin 0 -> 1045 bytes .../mimetypes/application-x-lmms-project.png | Bin 0 -> 836 bytes cmake/linux/icons/32x32@2/apps/lmms.png | Bin 0 -> 1857 bytes .../mimetypes/application-x-lmms-project.png | Bin 0 -> 1326 bytes cmake/linux/icons/48x48/apps/lmms.png | Bin 0 -> 1298 bytes .../mimetypes/application-x-lmms-project.png | Bin 0 -> 1206 bytes cmake/linux/icons/48x48@2/apps/lmms.png | Bin 0 -> 2075 bytes .../mimetypes/application-x-lmms-project.png | Bin 0 -> 2106 bytes cmake/linux/icons/64x64/apps/lmms.png | Bin 0 -> 1703 bytes .../mimetypes/application-x-lmms-project.png | Bin 0 -> 1540 bytes cmake/linux/icons/64x64@2/apps/lmms.png | Bin 0 -> 3112 bytes .../mimetypes/application-x-lmms-project.png | Bin 0 -> 2744 bytes cmake/linux/icons/scalable/apps/lmms.svg | 142 ++ .../mimetypes/application-x-lmms-project.svg | 173 ++ cmake/linux/lmms.png | Bin 95342 -> 0 bytes cmake/linux/lmms.svg | 1540 ------------- cmake/linux/project.svg | 1912 ----------------- cmake/nsis/CMakeLists.txt | 4 +- cmake/nsis/FileAssociation.nsh | 1 + cmake/nsis/assets/Logo.png | Bin 0 -> 5220 bytes cmake/nsis/assets/SmallLogo.png | Bin 0 -> 1743 bytes cmake/nsis/icon.ico | Bin 0 -> 410598 bytes cmake/nsis/lmms.VisualElementsManifest.xml | 9 + cmake/nsis/lmms.ico | Bin 137750 -> 0 bytes cmake/nsis/lmms.rc.in | 3 +- cmake/nsis/nsis_branding.bmp | Bin 9742 -> 9744 bytes cmake/nsis/project.ico | Bin 0 -> 410598 bytes data/themes/classic/icon_small.png | Bin 0 -> 2121 bytes data/themes/default/icon.png | Bin 95342 -> 2525 bytes data/themes/default/icon_small.png | Bin 0 -> 828 bytes src/core/main.cpp | 2 +- src/gui/MainWindow.cpp | 4 +- 49 files changed, 335 insertions(+), 3460 deletions(-) create mode 100644 cmake/apple/icon.icns delete mode 100644 cmake/apple/lmms.icns create mode 100644 cmake/linux/icons/128x128/apps/lmms.png create mode 100644 cmake/linux/icons/128x128/mimetypes/application-x-lmms-project.png create mode 100644 cmake/linux/icons/128x128@2/apps/lmms.png create mode 100644 cmake/linux/icons/128x128@2/mimetypes/application-x-lmms-project.png create mode 100644 cmake/linux/icons/16x16/apps/lmms.png create mode 100644 cmake/linux/icons/16x16/mimetypes/application-x-lmms-project.png create mode 100644 cmake/linux/icons/16x16@2/apps/lmms.png create mode 100644 cmake/linux/icons/16x16@2/mimetypes/application-x-lmms-project.png create mode 100644 cmake/linux/icons/24x24/apps/lmms.png create mode 100644 cmake/linux/icons/24x24/mimetypes/application-x-lmms-project.png create mode 100644 cmake/linux/icons/24x24@2/apps/lmms.png create mode 100644 cmake/linux/icons/24x24@2/mimetypes/application-x-lmms-project.png create mode 100644 cmake/linux/icons/32x32/apps/lmms.png create mode 100644 cmake/linux/icons/32x32/mimetypes/application-x-lmms-project.png create mode 100644 cmake/linux/icons/32x32@2/apps/lmms.png create mode 100644 cmake/linux/icons/32x32@2/mimetypes/application-x-lmms-project.png create mode 100644 cmake/linux/icons/48x48/apps/lmms.png create mode 100644 cmake/linux/icons/48x48/mimetypes/application-x-lmms-project.png create mode 100644 cmake/linux/icons/48x48@2/apps/lmms.png create mode 100644 cmake/linux/icons/48x48@2/mimetypes/application-x-lmms-project.png create mode 100644 cmake/linux/icons/64x64/apps/lmms.png create mode 100644 cmake/linux/icons/64x64/mimetypes/application-x-lmms-project.png create mode 100644 cmake/linux/icons/64x64@2/apps/lmms.png create mode 100644 cmake/linux/icons/64x64@2/mimetypes/application-x-lmms-project.png create mode 100644 cmake/linux/icons/scalable/apps/lmms.svg create mode 100644 cmake/linux/icons/scalable/mimetypes/application-x-lmms-project.svg delete mode 100644 cmake/linux/lmms.png delete mode 100644 cmake/linux/lmms.svg delete mode 100644 cmake/linux/project.svg create mode 100644 cmake/nsis/assets/Logo.png create mode 100644 cmake/nsis/assets/SmallLogo.png create mode 100644 cmake/nsis/icon.ico create mode 100644 cmake/nsis/lmms.VisualElementsManifest.xml delete mode 100644 cmake/nsis/lmms.ico create mode 100644 cmake/nsis/project.ico create mode 100644 data/themes/classic/icon_small.png create mode 100644 data/themes/default/icon_small.png diff --git a/cmake/apple/CMakeLists.txt b/cmake/apple/CMakeLists.txt index ff1a8ea46..835d886b9 100644 --- a/cmake/apple/CMakeLists.txt +++ b/cmake/apple/CMakeLists.txt @@ -1,4 +1,4 @@ -SET(MACOSX_BUNDLE_ICON_FILE "lmms.icns") +SET(MACOSX_BUNDLE_ICON_FILE "icon.icns") SET(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_NAME_UCASE}") SET(MACOSX_BUNDLE_LONG_VERSION_STRING "${VERSION}") SET(MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_NAME_UCASE}") diff --git a/cmake/apple/icon.icns b/cmake/apple/icon.icns new file mode 100644 index 0000000000000000000000000000000000000000..3ee7857f44f5e8ada46c6d95ebef809082a988e4 GIT binary patch literal 44942 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 literal 0 HcmV?d00001 diff --git a/cmake/apple/lmms.icns b/cmake/apple/lmms.icns deleted file mode 100644 index e54187b5cee34c3ca5baa21e4c68910901548dea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 280023 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 k^W=54Lojx|o`bayipv~abwwFBU5g6_^PtPmnJ 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 literal 205223 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

0pmfA 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°|{!@z1ZL%rAtAxL?!($Nu8n^=hQh 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 VS_VERSION_INFO VERSIONINFO diff --git a/cmake/nsis/nsis_branding.bmp b/cmake/nsis/nsis_branding.bmp index a7e75e3c1a7a7e22126690fa289216e794f959a8..939f2ebabf099b623b75124bbc048b4e520e118d 100644 GIT binary patch literal 9744 zcmeI2ziR7d9ERUQ2Sb;tpdmvDT}tspbIht7&IqCfI&+#1Q@g?Lx4dWG6Wd3B}0HgJ2C_q*a;sp7=#IS`Hz|F zf(!u$&B+j8(2@)R2Cc~uV9=B(3}hb z1}(`DV9=Tj0S0Zz5Ma=j3;_o1$Pi$V$q?YIjRj_S7!TTD(3}hb1}(`DV9=Tj0S0Zz z5Ma=j3;_o1$PnPHZQ9`bdtm8bU#z6k^Z#L9A^$}rYeDA6GRxi5-D+|E%xSTD?0&5tYjd}b z{q7cL>9eP^#fym@^IG-LO4GAd$07Dwb|oYPl|SN-)?R>_1CGt znicWc^qKKQegC_wW_?}OuDRv4ZTRcgW6LUYEbmd7{oZ+SubXCHmFecGLr3wNyeUQ6 z%Qut4Y!t7yO+BByvL0w&@9X{3ZlC(=)L%snbS%E?df%?8dLFaB+K(KSSCWkB#q(pO zQg88WIi{C=lXjRTY5r`Po9%4}zdxG$cFQbz4fk#OW<#CF<`^q0vtp_W3$Mpjxq3LS^sE|VWeWN5us$F}wtA0vK(91?8e`?B z?Dn!*SdFpSpk8U(EVEp%n3aW9oXCN_+GSRnRfRQ{SF6nSVzt5=&8uBzcB8OH^lFw_ ztFT7(s>fkJ`Z;pX&)plt g$nq}QXL;=T(Y?N>@M2m=-}mivj4!!Q_C1mR0kh?D{Qv*} literal 9742 zcmchc3tW>`AIE>1y=g?*3*rT@paQ1kHJPP(0};6jB7q7F1>}x$)sgcOhNuJvlLQ-> z%BA514FMH($S^C(3XsrdOuPcQklR>$&ok)r`i^akUdHqJJZwAX;W^*^&hPo3^Z#$T z&70F9JKh@x7?XD?mjKo7NpPv9oFFsH-*ldPcLrQ9{0sDAAgGAU*Li)|Uwj48dDGxnI12HH4`NmENNhPb9_!B; zAT)Oo{Lf89@L6Mcd@}(~MdQH8pMm70!>}!y3ad+F;96*mt;J*ESo$^+lMlkH*bqs{ zN8ogIG#oCPAhc{4e6Q+Y$2VpOyljA&;+fcf*$~dW37}t{4EO80NJ(X3!&MXbm+8Z| zbQb7W7GO)65$F{Yu%~n${BG(YfHx1vzD!4Og(1>1jw0sD2iSbm5Psjz2Kz(?f^JPh zIv8Qe=4*%+i zoe#`VSbPCVzpcmTzuRDUlPM1U?ucDaKE$Ofm+{#HXCyVa;A7De9C_r5Yu9;5ezFne zH~84sZh_QhPkjD|4|YqI8f$1dlItwF*|QGw##4i z4?ipBl04t6XPe38T`nnZ5{aJG?b6rUbmN8mBiE5O^=;qq`1ttPyN@3?RA-vLJ};|r zfJ~;Ct7VyS0_QTXq$H2x5{VvFxeN{bQ*KD{w&6~USb`H3`bz*(A@^xy(K|io)vQdR+Z|=tvE78Dw&D_vMk}ETxw~AQUX^&1FH4 zVlXJOI5Llq?^jnhBxs!LSV`Wo#Jwle371eHAZQA?V&e&!jH{u#`u=0hbLk%?T4l4C zac7?j1kWhRlyJqzhcm+C?p9Y*k_`e^VqV_K^z`G5u&PIt@s)5Tr%?7{_!U$Ws=?qg zNF-FLDKVGMQ}N1y!=s|I zziSv2y_hMan*v(WHM99REEoGUt!ow0Mb9D7>C z91)jJ$TZJIqqqbDLD?{Mxbhc9vzW&T*kJgJ+IBUm%f(8MW3kdxHSe!Vfq<+)YIE&9 zc{2SFi=}bBOe&tr45qGLgo}_dtu!4cOe$pCLACW_ojgszSejmkp40j{k0eJqy_dzJ zYj}Mm>yRwnP*<1dLDb?gs^PbxmLwX)G>l8^;28T=ZOpq~j zXMJDA5J|@u#vhYBg-oTUxte8qkvMVU6}@{(a!dvoAa(}M>&BsnMk${Pf(|LzNG14zm6 zs)CvuDHdkU85POqvN?Hq++&HHLE!p(A6-XQqlcAib;j(x+4#RDLs_wKv@@I3eb^jQ z`N`uXCejTXRao)mN4T%|O6pAi{!~_#5Q!)*5h)oidR5M5Vp1&BU71-(s!aG z8gI~Sy-@tQxl4tRLXvTjEl)*={>wJ&>S*3MbyC<-Qc}EJQo^CQI7huld)4=~iR??K zzxx&IC6zXBqlHi<6B!rv1PCevbh|6l67oaBi~Kp0A`^-@Y&MUO5iTw}Z0wqg%JYD~ z$5Z!J8JARA{%j5CbYz~ibXLJJ71` zplV#FoJ-nyaowWQvZuoCOj7uWve`Q$K1}<$X0zVP%pyKNm&fPvO4#he+#UA%iV{pU z##eTU3NER%HO+kSnM%rLlwRb|Gr=wct%*9O30ywEoZ{jWvYZ|6qurDwn97Fjvt1<@ zWizAgRkAIjjEf|dWiAsu3J6p=pU);({Gyy4#w+p%&R9LfeQ=TVkl2ih8Qomu2@rf$ zP*6}_-osV+$r6*@Dih2;rBQf6UtChkW|pPGCW=e820Xh`US3d8NWgOVMVX%Cf*vTm z@&DP_Hy5$l0rM@DRYI~;q)K8GS2@3+;97ZZPS^yu+XEEf<-UhHTvF+iAX-3aRd=OT z##LT^EhjU~cy-o5#dkR@sd`*e$!)ipGMn}2RbF0{xoXPp7Wvx^*k?7lq|%Q3)i!0+ z(j?RC+Ls;!xacVOHfnQ8r7gQZ2&jBWaa}72n`C!gGsfy+><5=r`XGpQxK>zPNEV$m zHOeUpWKg@QUtCi0O}F_OpV=F2d#?5X|M0^8aY?1^S*wS5^;r`8hcGYwTYtHT&FXvo Mp#0MP2I?*FAJ0=Ung9R* diff --git a/cmake/nsis/project.ico b/cmake/nsis/project.ico new file mode 100644 index 0000000000000000000000000000000000000000..4b994f3215b476fe37b58e8ee6352eaa58dde5b4 GIT binary patch literal 410598 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 literal 0 HcmV?d00001 diff --git a/data/themes/default/icon.png b/data/themes/default/icon.png index ae9fe6a2a9f329fb005f8a5bedcf55874bba3b92..ec881aacfba7148378a677279f1423a450da1a76 100644 GIT binary patch literal 2525 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 U&9n^i#Q*>R07*qoM6N<$f@CRPtN;K2 diff --git a/data/themes/default/icon_small.png b/data/themes/default/icon_small.png new file mode 100644 index 0000000000000000000000000000000000000000..fd74011f9dbe295cc7bb0e2a5ac97176ee439576 GIT binary patch literal 828 zcmV-C1H=4@P)x?r8{}y$|%XsuC zr#AVn=6wG<-}{{ZoAb{M{O=M=u8QngsFVV3Ai?CU0H6@&A+LwOL<1Drvk2owkYsZ3 zQb}e|snQ@Ukp-1f1W9Qwd%B~@wcBE|+RV&V1EHY5rN4W$ZwM@$2W|kwEb_Pk9EIkG z16UHQHb-Gj9sq*;NPUqfK{Fa@m}%R_W!D)2P~ZDRehdCs8zM1Y>z%j~fFZ@l#8K=x z!a3J55g%&>V1K4dH1@rajsBN}=ELjiw=RG~skv0R&kB2T`cf#1m9o53;;5s5+e(vc zAL}s}K-+FlcK)h9dvZFpo^sJP^uhR8R$E+YyETmmCh@+1Bt!Em)q9FXTH@BonkPHo z@K|&K^tKzI+26&j-X=K_o(7=AS0gX%Iw?*&ix%JwjwNQrDp2bwj|v|TOmg+reR)l3 zh=c=7s{y=yk7ae+T{${CzT`dHSoCsq0hX)T-$jY9Mz(%ebUp23J(T!r=Vtc<$Ddxx*AJA6X`W@{5b7vQ4rrtBP!{sK`(2B>VU zi#qAn>(`|F6m(C1rs~aI>Hf5nvYZnF;K9ddQkfVu#lI3j07y^+q2S`*h04Sr6`l2l z&-T^)>g-(b&&wIDws-^zfWM``TMdMQm@IX6F6eLV@BV!y-f8uP=lP&L3(G(FV**oH zXPr5eIIJRl= 0x050000) && (QT_VERSION < 0x050600)) help_menu->addSeparator(); #endif - help_menu->addAction( embed::getIconPixmap( "icon" ), tr( "About" ), + help_menu->addAction( embed::getIconPixmap( "icon_small" ), tr( "About" ), this, SLOT( aboutLMMS() ) ); // create tool-buttons From 27fd8d04606eb5818e364ed14ae620e7bb0d62df Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Mon, 24 Sep 2018 11:04:51 -0400 Subject: [PATCH 135/445] Add wiki as clonable submodule (#4588) * Add wiki as clonable submodule per #4578 --- .gitmodules | 3 +++ INSTALL.txt | 66 +++++++++++++++++++++++++++++++++++------------------ doc/wiki | 1 + 3 files changed, 48 insertions(+), 22 deletions(-) create mode 160000 doc/wiki diff --git a/.gitmodules b/.gitmodules index 3f4859b56..28d6c5d46 100644 --- a/.gitmodules +++ b/.gitmodules @@ -31,3 +31,6 @@ [submodule "src/3rdparty/mingw-std-threads"] path = src/3rdparty/mingw-std-threads url = https://github.com/meganz/mingw-std-threads.git +[submodule "doc/wiki"] + path = doc/wiki + url = https://github.com/lmms/lmms.wiki.git diff --git a/INSTALL.txt b/INSTALL.txt index fd5392d52..ac5160af6 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -1,16 +1,28 @@ -Building LMMS got quite simple since 0.4.0 as everything is managed -by cmake now. Therefore make sure you have CMake (>= 2.6.0 recommended) and -then run +This project uses git submodules and several are required for a successful +build. If this tarball was NOT provided with submodules (default), some source +dependencies will need to be manually added to src/3rdparty. +If this project WAS provided with submodules, there are detailed dependencies +(e.g. supported compilers, cmake requirements, cross-compilation) at +doc/wiki/Compiling.md including platform-specific build instructions (e.g. +apt-get, dnf, pacman, etc). -mkdir build -cd build -cmake ../ -make -sudo make install +Online documentation: -If your system does not have "sudo", become root with your preferred mechanism -and run the "make install" command. + https://github.com/LMMS/lmms/wiki/ + +Live online chat via Discord (similar to IRC): + + https://lmms.io/chat, Channel #programming + +Basic build steps: + + mkdir build + cd build + cmake ../ + make + sudo make install + # or alternately: su -c 'make install' With the above commands an out-of-tree build is performed. You can also run "cmake ." directly in the root of source tree although this is not recommended. @@ -25,21 +37,31 @@ that are going to be built into LMMS or built as plugins. Install the according libraries and development files if a certain feature is not enabled. Then remove CMakeCache.txt and run cmake again. -If you want to supply an install prefix to cmake, add the flag: +For non-root installs, or to install to a non-standard location, provide an +install prefix to cmake, using the flag: --DCMAKE_INSTALL_PREFIX= + -DCMAKE_INSTALL_PREFIX= -Where can be /usr, /usr/local, /opt, etc. The default is /usr/local. - - - -Building with QT5 - -First of all please note that CMake >= 2.8.11 is required for building with -Qt5 support. +The Compilation tutorial (see docs/wiki/Compilation.md) +specifically uses as "../target" for all non-root installations. This +is strongly recommended if developing a patch or a feature. For root +installations, can be /usr, /usr/local, /opt, etc. For most systems, +the default is /usr/local. If your Qt5 installation does not reside in standard installation paths, -additionally pass e.g. +additionally pass: --DCMAKE_PREFIX_PATH=/opt/qt53/ + -DCMAKE_PREFIX_PATH= +Where is the location to Qt5 installation, usually /opt/qt5/, etc. + +Important wiki sections: + +doc/wiki/Compiling.md: + Dependencies Detailed + - Build Toolchain (cmake) + - Compiler (gcc, clang) + - Libraries (required and optional dependencies) + +doc/wiki/Dependencies-.md + Platform-specific dependencies (Windows, Ubuntu, Fedora, macOS, etc.) diff --git a/doc/wiki b/doc/wiki new file mode 160000 index 000000000..42193f98f --- /dev/null +++ b/doc/wiki @@ -0,0 +1 @@ +Subproject commit 42193f98f37d6b69f47edbdfd50a20090193e70a From a2685c1cca3ef20e317d69eccb915f9d7b05e349 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 25 Sep 2018 16:46:44 +0900 Subject: [PATCH 136/445] Bump version to 1.2.0-rc7 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 452c05c5f..e42c48456 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 "rc6") +SET(VERSION_STAGE "rc7") SET(VERSION_BUILD "0") SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE}") IF(VERSION_STAGE) From bd3f40933c76507d4d1d5d425ac2750164ed36a6 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 26 Sep 2018 15:36:53 +0900 Subject: [PATCH 137/445] Fix compilation on non-x86 platforms --- src/core/MixerWorkerThread.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/MixerWorkerThread.cpp b/src/core/MixerWorkerThread.cpp index 9632d22c7..52041d76e 100644 --- a/src/core/MixerWorkerThread.cpp +++ b/src/core/MixerWorkerThread.cpp @@ -24,7 +24,6 @@ #include "MixerWorkerThread.h" -#include #include #include #include @@ -33,6 +32,10 @@ #include "ThreadableJob.h" #include "Mixer.h" +#if defined(LMMS_HOST_X86) || defined(LMMS_HOST_X86_64) +#include +#endif + MixerWorkerThread::JobQueue MixerWorkerThread::globalJobQueue; QWaitCondition * MixerWorkerThread::queueReadyWaitCond = NULL; QList MixerWorkerThread::workerThreads; From 0dc1bdbb68003e4508c1006bcd9bd5aacd7ab8bf Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Sun, 30 Sep 2018 21:30:56 -0400 Subject: [PATCH 138/445] Minor cmake fixes (#4636) Minor cmake fixes --- cmake/modules/CheckSubmodules.cmake | 2 +- data/locale/CMakeLists.txt | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cmake/modules/CheckSubmodules.cmake b/cmake/modules/CheckSubmodules.cmake index 55c0381b8..38717f18e 100644 --- a/cmake/modules/CheckSubmodules.cmake +++ b/cmake/modules/CheckSubmodules.cmake @@ -18,7 +18,7 @@ # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # Files which confirm a successful clone -SET(VALID_CRUMBS "CMakeLists.txt;Makefile;Makefile.in;Makefile.am;configure.ac;configure.py;autogen.sh;.gitignore") +SET(VALID_CRUMBS "CMakeLists.txt;Makefile;Makefile.in;Makefile.am;configure.ac;configure.py;autogen.sh;.gitignore;LICENSE;Home.md") # Try and use the specified shallow clone on submodules, if supported SET(DEPTH_VALUE 100) diff --git a/data/locale/CMakeLists.txt b/data/locale/CMakeLists.txt index 9a7726406..9cb25f426 100644 --- a/data/locale/CMakeLists.txt +++ b/data/locale/CMakeLists.txt @@ -2,12 +2,13 @@ SET(QT_LUPDATE_EXECUTABLE "${Qt5_LUPDATE_EXECUTABLE}") SET(QT_LRELEASE_EXECUTABLE "${Qt5_LRELEASE_EXECUTABLE}") IF(QT_LUPDATE_EXECUTABLE STREQUAL "") - EXECUTE_PROCESS(COMMAND "lupdate" "--help" RESULT_VARIABLE LUPDATE_FALLBACK OUTPUT_QUIET) + EXECUTE_PROCESS(COMMAND "lupdate" "-help" RESULT_VARIABLE LUPDATE_FALLBACK OUTPUT_QUIET) IF(LUPDATE_FALLBACK EQUAL 0) SET(QT_LUPDATE_EXECUTABLE lupdate) SET(QT_LRELEASE_EXECUTABLE lrelease) ELSE() - MESSAGE(FATAL_ERROR "Cannot generate locales") + MESSAGE(WARNING "Cannot generate locales") + RETURN() ENDIF() ENDIF() From 9799f3ca1c0c0a23565863a6c197149819320937 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Thu, 4 Oct 2018 14:24:52 +0900 Subject: [PATCH 139/445] Fix Carla detection in AppImage launcher script Fixes a typo which hardcodes Carla path at the packaging time. --- 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 99c5aebc1..9ff251e51 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -98,7 +98,7 @@ cat >"${APPDIR}usr/bin/lmms" < /dev/null 2>&1; then - CARLAPATH="$(which carla)" + CARLAPATH="\$(which carla)" CARLAPREFIX="\${CARLAPATH%/bin*}" echo "Carla appears to be installed on this system at \$CARLAPREFIX/lib[64]/carla so we'll use it." export LD_LIBRARY_PATH=\$CARLAPREFIX/lib/carla:\$CARLAPREFIX/lib64/carla:\$LD_LIBRARY_PATH From a0737a4efc301d80d32d1a2d46b32327c2bc2a0e Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 22 Sep 2018 11:14:07 +0200 Subject: [PATCH 140/445] Add `AutomatableModel` nodename attribute (#4578) * Save `AutomatableModel` nodename in attribute if it must be quoted * Loading an `AutomatableModel` with name now means it - either must be `QDomElement::nodeName()` (as before) *and* must not have a `nodename` attribute (new) - or must have a `nodename` attribute with value --- src/core/AutomatableModel.cpp | 58 +++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index da5a2d15b..cb8aa7046 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -96,10 +96,16 @@ void AutomatableModel::saveSettings( QDomDocument& doc, QDomElement& element, co // automation needs tuple of data (name, id, value) // scale type also needs an extra value // => it must be appended as a node - QDomElement me = doc.createElement( name ); + + 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 ); me.setAttribute( "scale_type", m_scaleType == Logarithmic ? "log" : "linear" ); + if(mustQuote) { + me.setAttribute( "nodename", name ); + } element.appendChild( me ); } else @@ -177,22 +183,48 @@ void AutomatableModel::loadSettings( const QDomElement& element, const QString& // // // element => there is automation data, or scaletype information - node = element.namedItem( name ); + + node = element.namedItem( name ); // maybe we have luck? + + // either: no node with name "name" found + // => look for nodes with attribute name="nodename" + // or: element with namedItem() "name" was found, but it's real nodename + // is given as attribute and does not match + // => look for the right node + if(node.isNull() || + ( node.isElement() && + node.toElement().hasAttribute("nodename") && + node.toElement().attribute("nodename") != name)) + { + for(QDomElement othernode = element.firstChildElement(); + !othernode.isNull(); + othernode = othernode.nextSiblingElement()) + { + if((!othernode.hasAttribute("nodename") && + othernode.nodeName() == name) || + othernode.attribute("nodename") == name) + { + node = othernode; + break; + } + } + } if( node.isElement() ) { - changeID( node.toElement().attribute( "id" ).toInt() ); - setValue( LocaleHelper::toFloat( node.toElement().attribute( "value" ) ) ); - if( node.toElement().hasAttribute( "scale_type" ) ) + QDomElement nodeElement = node.toElement(); + changeID( nodeElement.attribute( "id" ).toInt() ); + setValue( LocaleHelper::toFloat( nodeElement.attribute( "value" ) ) ); + if( nodeElement.hasAttribute( "scale_type" ) ) + { + if( nodeElement.attribute( "scale_type" ) == "linear" ) { - if( node.toElement().attribute( "scale_type" ) == "linear" ) - { - setScaleType( Linear ); - } - else if( node.toElement().attribute( "scale_type" ) == "log" ) - { - setScaleType( Logarithmic ); - } + setScaleType( Linear ); } + else if( nodeElement.attribute( "scale_type" ) == "log" ) + { + setScaleType( Logarithmic ); + } + } } else { From fb5c8f510a6cba94fc5e32e6654d67fa0f2abc9d Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 7 Aug 2018 10:34:27 +0900 Subject: [PATCH 141/445] Fix VST track cloning in Beat/Bassline editor --- src/core/BBTrackContainer.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/BBTrackContainer.cpp b/src/core/BBTrackContainer.cpp index e9af1f621..e349c7b02 100644 --- a/src/core/BBTrackContainer.cpp +++ b/src/core/BBTrackContainer.cpp @@ -95,10 +95,13 @@ tact_t BBTrackContainer::lengthOfBB( int _bb ) const MidiTime max_length = MidiTime::ticksPerTact(); const TrackList & tl = tracks(); - for( TrackList::const_iterator it = tl.begin(); it != tl.end(); ++it ) + for (Track* t : tl) { - max_length = qMax( max_length, - ( *it )->getTCO( _bb )->length() ); + // Don't create TCOs here if not exist + if (_bb < t->numOfTCOs()) + { + max_length = qMax(max_length, t->getTCO( _bb )->length()); + } } return max_length.nextFullTact(); From 5a921057356c767c42a2a322793178cc4e9293e4 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Thu, 4 Oct 2018 20:16:12 +0900 Subject: [PATCH 142/445] Don't always treat empty long patterns as BB patterns Due to the wrong condition for GUI handling, empty patterns longer than 1 bar was treated as BB patterns though they don't really look like. This commit drops the erroneous check and fixes related GUI issues. --- src/tracks/Pattern.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/tracks/Pattern.cpp b/src/tracks/Pattern.cpp index 01d51fbae..26cc1c9ec 100644 --- a/src/tracks/Pattern.cpp +++ b/src/tracks/Pattern.cpp @@ -713,8 +713,7 @@ void PatternView::mousePressEvent( QMouseEvent * _me ) { if( _me->button() == Qt::LeftButton && m_pat->m_patternType == Pattern::BeatPattern && - ( fixedTCOs() || pixelsPerTact() >= 96 || - m_pat->m_steps != MidiTime::stepsPerTact() ) && + ( fixedTCOs() || pixelsPerTact() >= 96 ) && _me->y() > height() - s_stepBtnOff->height() ) // when mouse button is pressed in beat/bassline -mode @@ -784,8 +783,7 @@ void PatternView::mouseDoubleClickEvent(QMouseEvent *_me) void PatternView::wheelEvent( QWheelEvent * _we ) { if( m_pat->m_patternType == Pattern::BeatPattern && - ( fixedTCOs() || pixelsPerTact() >= 96 || - m_pat->m_steps != MidiTime::stepsPerTact() ) && + ( fixedTCOs() || pixelsPerTact() >= 96 ) && _we->y() > height() - s_stepBtnOff->height() ) { // get the step number that was wheeled on and @@ -969,8 +967,7 @@ void PatternView::paintEvent( QPaintEvent * ) } // beat pattern paint event - else if( beatPattern && ( fixedTCOs() || ppt >= 96 - || m_pat->m_steps != MidiTime::stepsPerTact() ) ) + else if( beatPattern && ( fixedTCOs() || ppt >= 96 ) ) { QPixmap stepon0; QPixmap stepon200; From 43b700d23cfabc45e924bf134ede9c7093ac973a Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Thu, 4 Oct 2018 20:24:15 +0900 Subject: [PATCH 143/445] Ensure correct TCOs after cloning tracks into the BB editor Previously BBTrackContainerView::dropEvent always deleted the TCOs of dropped tracks. It made dropped tracks unusable. As of this commit, the function checks for correct TCOs. If incorrect TCOs exist, the function remove them and add empty ones. --- src/gui/editors/BBEditor.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/gui/editors/BBEditor.cpp b/src/gui/editors/BBEditor.cpp index 699ff2524..577f8fe6a 100644 --- a/src/gui/editors/BBEditor.cpp +++ b/src/gui/editors/BBEditor.cpp @@ -258,7 +258,25 @@ void BBTrackContainerView::dropEvent(QDropEvent* de) DataFile dataFile( value.toUtf8() ); Track * t = Track::create( dataFile.content().firstChild().toElement(), model() ); - t->deleteTCOs(); + // Ensure BB TCOs exist + bool hasValidBBTCOs = false; + if (t->getTCOs().size() == m_bbtc->numOfBBs()) + { + hasValidBBTCOs = true; + for (int i = 0; i < t->getTCOs().size(); ++i) + { + if (t->getTCOs()[i]->startPosition() != MidiTime(i, 0)) + { + hasValidBBTCOs = false; + break; + } + } + } + if (!hasValidBBTCOs) + { + t->deleteTCOs(); + t->createTCOsForBB(m_bbtc->numOfBBs() - 1); + } m_bbtc->updateAfterTrackAdd(); de->accept(); From 7aeddc648a476ade87b3ad3b382d3924e89ab3b2 Mon Sep 17 00:00:00 2001 From: Hyunin Song Date: Thu, 5 Oct 2017 13:55:52 +0900 Subject: [PATCH 144/445] Fix unit tests for automation Cherry-picked from 'master'. Orignal commit: 0a6a6d1a7706350b47bce4e95d7d6dc258955a19 --- tests/src/tracks/AutomationTrackTest.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/src/tracks/AutomationTrackTest.cpp b/tests/src/tracks/AutomationTrackTest.cpp index ef204963d..f9f77fac4 100644 --- a/tests/src/tracks/AutomationTrackTest.cpp +++ b/tests/src/tracks/AutomationTrackTest.cpp @@ -162,11 +162,10 @@ private slots: auto song = Engine::getSong(); auto bbContainer = Engine::getBBTrackContainer(); BBTrack bbTrack(song); - AutomationTrack automationTrack(bbContainer); - bbTrack.createTCOsForBB(bbTrack.index()); + Track* automationTrack = Track::create(Track::AutomationTrack, bbContainer); - QVERIFY(automationTrack.numOfTCOs()); - AutomationPattern* p1 = dynamic_cast(automationTrack.getTCO(0)); + QVERIFY(automationTrack->numOfTCOs()); + AutomationPattern* p1 = dynamic_cast(automationTrack->getTCO(0)); QVERIFY(p1); FloatModel model; @@ -182,7 +181,6 @@ private slots: QCOMPARE(bbContainer->automatedValuesAt(50, bbTrack.index())[&model], 1.0f); BBTrack bbTrack2(song); - bbTrack.createTCOsForBB(bbTrack2.index()); QCOMPARE(bbContainer->automatedValuesAt(5, bbTrack.index())[&model], 0.5f); QVERIFY(! bbContainer->automatedValuesAt(5, bbTrack2.index()).size()); From fbdd09dbf56f0912ed8750cc72dda8403f5a01ca Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Thu, 11 Oct 2018 19:28:41 +0200 Subject: [PATCH 145/445] Fix german locale (' + Mittelklick') --- data/locale/de.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data/locale/de.ts b/data/locale/de.ts index 10f37d009..16f3d2873 100644 --- a/data/locale/de.ts +++ b/data/locale/de.ts @@ -507,7 +507,7 @@ Wenn Sie daran interessiert sind LMMS in eine andere Sprache zu übersetzen oder AutomationPattern Drag a control while pressing <%1> - Ein Steuerelement mit <Strg> hier her ziehen + Ein Steuerelement mit <%1> hier her ziehen @@ -5977,7 +5977,7 @@ Grund: »%2« Mute/unmute (<%1> + middle click) - Stumm/Laut schalten (<Strg> + Mittelklick) + Stumm/Laut schalten (<%1> + Mittelklick) @@ -6808,7 +6808,7 @@ Bitte stellen Sie sicher, dass Sie Leserechte auf diese Datei sowie das Verzeich Mute/unmute (<%1> + middle click) - Stumm/Laut schalten (<Strg> + Mittelklick) + Stumm/Laut schalten (<%1> + Mittelklick) @@ -10017,4 +10017,4 @@ Die LED rechts unterhalb der Wellenform gibt an, ob die Saite aktiviert ist.Ausgabeverstärkung - \ No newline at end of file + From 4babbe25c5f2c7ce9b0cb84d024ea183e0dd0fd1 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 22 Sep 2018 13:22:36 +0200 Subject: [PATCH 146/445] Enable compiled-in XPM pixmaps (#4578) --- include/embed.h | 30 +++++++++++++++++++++++------- src/gui/embed.cpp | 31 ++++++++++++++++++++----------- 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/include/embed.h b/include/embed.h index 40ce8faed..a99c35c0a 100644 --- a/include/embed.h +++ b/include/embed.h @@ -35,7 +35,17 @@ namespace embed { -QPixmap LMMS_EXPORT getIconPixmap( const QString& _name, int _w = -1, int _h = -1 ); +/** + * Return an image for the icon pixmap cache. + * + * @param _name Identifier for the pixmap. If it is not in the icon pixmap + * cache, it will be loaded from the artwork QDir search paths (exceptions are + * compiled-in XPMs, you need to provide @p xpm for loading them). + * @param xpm Must be XPM data if the source should be raw XPM data instead of + * a file + */ +QPixmap LMMS_EXPORT getIconPixmap( const QString& _name, + int _w = -1, int _h = -1 , const char** xpm = nullptr ); QString LMMS_EXPORT getText( const char * _name ); } @@ -45,9 +55,10 @@ QString LMMS_EXPORT getText( const char * _name ); namespace PLUGIN_NAME { -inline QPixmap getIconPixmap( const QString& _name, int _w = -1, int _h = -1 ) +inline QPixmap getIconPixmap( const QString& _name, + int _w = -1, int _h = -1, const char** xpm = nullptr ) { - return embed::getIconPixmap(QString("%1/%2").arg(STRINGIFY(PLUGIN_NAME), _name), _w, _h); + return embed::getIconPixmap(QString("%1/%2").arg(STRINGIFY(PLUGIN_NAME), _name), _w, _h, xpm); } //QString getText( const char * _name ); @@ -60,12 +71,15 @@ class PixmapLoader { public: PixmapLoader( const PixmapLoader * _ref ) : - m_name( _ref != NULL ? _ref->m_name : QString() ) + m_name( _ref != NULL ? _ref->m_name : QString() ), + m_xpm( _ref->m_xpm ) { } - PixmapLoader( const QString & _name = QString() ) : - m_name( _name ) + PixmapLoader( const QString & _name = QString(), + const char** xpm = nullptr ) : + m_name( _name ), + m_xpm(xpm) { } @@ -73,7 +87,8 @@ public: { if( !m_name.isEmpty() ) { - return( embed::getIconPixmap( m_name.toLatin1().constData() ) ); + return( embed::getIconPixmap( + m_name.toLatin1().constData(), -1, -1, m_xpm )); } return( QPixmap() ); } @@ -89,6 +104,7 @@ public: protected: QString m_name; + const char** m_xpm = nullptr; } ; diff --git a/src/gui/embed.cpp b/src/gui/embed.cpp index af298bec3..6ce4b5bd7 100644 --- a/src/gui/embed.cpp +++ b/src/gui/embed.cpp @@ -31,8 +31,8 @@ namespace embed { - -QPixmap getIconPixmap(const QString& pixmapName, int width, int height ) +QPixmap getIconPixmap(const QString& pixmapName, + int width, int height, const char** xpm ) { QString cacheName; if (width > 0 && height > 0) @@ -50,19 +50,28 @@ QPixmap getIconPixmap(const QString& pixmapName, int width, int height ) { return pixmap; } - QImageReader reader(QString("artwork:%1").arg(pixmapName)); - if (width > 0 && height > 0) + if(xpm) { - reader.setScaledSize(QSize(width, height)); + pixmap = QPixmap(xpm); } - - pixmap = QPixmap::fromImageReader(&reader); - if (pixmap.isNull()) + else { - qWarning().nospace() << "Error loading icon pixmap " << pixmapName << ": " << - reader.errorString().toLocal8Bit().data(); - return QPixmap(1,1); + QImageReader reader(QString("artwork:%1").arg(pixmapName)); + + if (width > 0 && height > 0) + { + reader.setScaledSize(QSize(width, height)); + } + + pixmap = QPixmap::fromImageReader(&reader); + + if (pixmap.isNull()) + { + qWarning().nospace() << "Error loading icon pixmap " << pixmapName << ": " << + reader.errorString().toLocal8Bit().data(); + return QPixmap(1,1); + } } // Save to cache and return From 811188bb7a536a01164b6f5aeebccf3d280af52d Mon Sep 17 00:00:00 2001 From: Tobias Junghans Date: Sun, 21 Oct 2018 18:17:15 +0200 Subject: [PATCH 147/445] Update name in mailmap [ci skip] --- .mailmap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index 0ff7c15dd..7628795f9 100644 --- a/.mailmap +++ b/.mailmap @@ -1,5 +1,5 @@ Alexandre Almeida -Tobias Doerffel +Tobias Junghans Dave French Paul Giblock Paul Giblock From 1ab1280843793f16f17d709a3bc47b8c2f5d4e30 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 23 Oct 2018 12:43:25 +0900 Subject: [PATCH 148/445] Don't quit CLI rendering when failed to load sample files Per https://github.com/LMMS/lmms/pull/3293#discussion_r225765957 --- src/core/SampleBuffer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/SampleBuffer.cpp b/src/core/SampleBuffer.cpp index 86f8fd55c..a364be4b8 100644 --- a/src/core/SampleBuffer.cpp +++ b/src/core/SampleBuffer.cpp @@ -297,7 +297,6 @@ void SampleBuffer::update( bool _keep_settings ) else { fprintf( stderr, "%s\n", message.toUtf8().constData() ); - exit( EXIT_FAILURE ); } } } From 5c362e51ac22fd7c8f7682df7542e6d5100dea1c Mon Sep 17 00:00:00 2001 From: Johannes Lorenz <1042576+JohannesLorenz@users.noreply.github.com> Date: Wed, 24 Oct 2018 22:23:21 +0200 Subject: [PATCH 149/445] Fix not saving some automations (#4632) (#4667) Save automation of * Track::muted * Track::solo * EffectChain::enabled --- src/core/EffectChain.cpp | 4 ++-- src/core/Track.cpp | 14 ++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/core/EffectChain.cpp b/src/core/EffectChain.cpp index efadca525..cdb9ad7f1 100644 --- a/src/core/EffectChain.cpp +++ b/src/core/EffectChain.cpp @@ -53,7 +53,7 @@ EffectChain::~EffectChain() void EffectChain::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - _this.setAttribute( "enabled", m_enabledModel.value() ); + m_enabledModel.saveSettings( _doc, _this, "enabled" ); _this.setAttribute( "numofeffects", m_effects.count() ); for( Effect* effect : m_effects) @@ -80,7 +80,7 @@ void EffectChain::loadSettings( const QDomElement & _this ) // TODO This method should probably also lock the mixer - m_enabledModel.setValue( _this.attribute( "enabled" ).toInt() ); + m_enabledModel.loadSettings( _this, "enabled" ); const int plugin_cnt = _this.attribute( "numofeffects" ).toInt(); diff --git a/src/core/Track.cpp b/src/core/Track.cpp index fa500da33..bf10a10a0 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -2063,8 +2063,9 @@ void Track::saveSettings( QDomDocument & doc, QDomElement & element ) } element.setAttribute( "type", type() ); element.setAttribute( "name", name() ); - element.setAttribute( "muted", isMuted() ); - element.setAttribute( "solo", isSolo() ); + m_mutedModel.saveSettings( doc, element, "muted" ); + m_soloModel.saveSettings( doc, element, "solo" ); + if( m_height >= MINIMAL_TRACK_HEIGHT ) { element.setAttribute( "height", m_height ); @@ -2116,8 +2117,8 @@ void Track::loadSettings( const QDomElement & element ) setName( element.hasAttribute( "name" ) ? element.attribute( "name" ) : element.firstChild().toElement().attribute( "name" ) ); - setMuted( element.attribute( "muted" ).toInt() ); - setSolo( element.attribute( "solo" ).toInt() ); + m_mutedModel.loadSettings( element, "muted" ); + m_soloModel.loadSettings( element, "solo" ); if( m_simpleSerializingMode ) { @@ -2150,8 +2151,9 @@ void Track::loadSettings( const QDomElement & element ) { loadTrackSpecificSettings( node.toElement() ); } - else if( - !node.toElement().attribute( "metadata" ).toInt() ) + else if( node.nodeName() != "muted" + && node.nodeName() != "solo" + && !node.toElement().attribute( "metadata" ).toInt() ) { TrackContentObject * tco = createTCO( MidiTime( 0 ) ); From 1f7cd3ed5af6640c0e38a2dc2d9be5a9ae036dc8 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Sun, 28 Oct 2018 10:31:33 +0900 Subject: [PATCH 150/445] Allow building SF2 player with FluidSynth 2.x (#4678) Resolves the incompatibility between FluidSynth 1.x and 2.x due to some API changes by shimming some functions. Note that 1.x and 2.x are not binary compatible. --- plugins/sf2_player/fluidsynthshims.h | 88 +++++++++++++++++++++++++++ plugins/sf2_player/patches_dialog.cpp | 44 ++++++++------ plugins/sf2_player/patches_dialog.h | 2 +- plugins/sf2_player/sf2_player.cpp | 43 ++++++++++--- plugins/sf2_player/sf2_player.h | 2 +- 5 files changed, 152 insertions(+), 27 deletions(-) create mode 100644 plugins/sf2_player/fluidsynthshims.h diff --git a/plugins/sf2_player/fluidsynthshims.h b/plugins/sf2_player/fluidsynthshims.h new file mode 100644 index 000000000..4302256ba --- /dev/null +++ b/plugins/sf2_player/fluidsynthshims.h @@ -0,0 +1,88 @@ +/* + * fluidsynthshims.h - a shim header for FluidSynth 2.0 API changes + * + * Copyright (c) 2018 Hyunjin Song + * + * 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 FLUIDSYNTHSHIMS_H +#define FLUIDSYNTHSHIMS_H + +#include + +#if FLUIDSYNTH_VERSION_MAJOR < 2 + +inline const char* fluid_preset_get_name(fluid_preset_t* preset) +{ + return preset->get_name(preset); +} + +inline int fluid_preset_get_banknum(fluid_preset_t* preset) +{ + return preset->get_banknum(preset); +} + +inline int fluid_preset_get_num(fluid_preset_t* preset) +{ + return preset->get_num(preset); +} + +inline fluid_sfont_t* fluid_preset_get_sfont(fluid_preset_t* preset) +{ + return preset->sfont; +} + +inline char* fluid_sfont_get_name(fluid_sfont_t* sfont) +{ + return sfont->get_name(sfont); +} + +inline void fluid_sfont_iteration_start(fluid_sfont_t* sfont) +{ + sfont->iteration_start(sfont); +} + +// Due to the API change, we can't simply shim the 'fluid_sfont_iteration_next' function +inline fluid_preset_t* fluid_sfont_iteration_next_wrapper(fluid_sfont_t* sfont, fluid_preset_t* preset) +{ + return sfont->iteration_next(sfont, preset) ? preset : nullptr; +} + +#else // FLUIDSYNTH_VERSION_MAJOR < 2 + +#define FLUID_REVERB_DEFAULT_ROOMSIZE 0.2f +#define FLUID_REVERB_DEFAULT_DAMP 0.0f +#define FLUID_REVERB_DEFAULT_WIDTH 0.5f +#define FLUID_REVERB_DEFAULT_LEVEL 0.9f + +#define FLUID_CHORUS_DEFAULT_N 3 +#define FLUID_CHORUS_DEFAULT_LEVEL 2.0f +#define FLUID_CHORUS_DEFAULT_SPEED 0.3f +#define FLUID_CHORUS_DEFAULT_DEPTH 8.0f + +inline fluid_preset_t* fluid_sfont_iteration_next_wrapper(fluid_sfont_t* sfont, fluid_preset_t*) +{ + return fluid_sfont_iteration_next(sfont); +} + +#endif // FLUIDSYNTH_VERSION_MAJOR < 2 + +#endif // FLUIDSYNTHSHIMS_H diff --git a/plugins/sf2_player/patches_dialog.cpp b/plugins/sf2_player/patches_dialog.cpp index 6ae791c15..189d996f3 100644 --- a/plugins/sf2_player/patches_dialog.cpp +++ b/plugins/sf2_player/patches_dialog.cpp @@ -143,7 +143,6 @@ void patchesDialog::setup ( fluid_synth_t * pSynth, int iChan, m_iChan = iChan; - fluid_preset_t preset; QTreeWidgetItem *pBankItem = NULL; // For all soundfonts (in reversed stack order) fill the available banks... int cSoundFonts = ::fluid_synth_sfcount(m_pSynth); @@ -151,11 +150,17 @@ void patchesDialog::setup ( fluid_synth_t * pSynth, int iChan, fluid_sfont_t *pSoundFont = ::fluid_synth_get_sfont(m_pSynth, i); if (pSoundFont) { #ifdef CONFIG_FLUID_BANK_OFFSET - int iBankOffset = ::fluid_synth_get_bank_offset(m_pSynth, pSoundFont->id); + int iBankOffset = ::fluid_synth_get_bank_offset(m_pSynth, fluid_sfont_get_id(pSoundFont)); #endif - pSoundFont->iteration_start(pSoundFont); - while (pSoundFont->iteration_next(pSoundFont, &preset)) { - int iBank = preset.get_banknum(&preset); + fluid_sfont_iteration_start(pSoundFont); +#if FLUIDSYNTH_VERSION_MAJOR < 2 + fluid_preset_t preset; + fluid_preset_t *pCurPreset = &preset; +#else + fluid_preset_t *pCurPreset; +#endif + while ((pCurPreset = fluid_sfont_iteration_next_wrapper(pSoundFont, pCurPreset))) { + int iBank = fluid_preset_get_banknum(pCurPreset); #ifdef CONFIG_FLUID_BANK_OFFSET iBank += iBankOffset; #endif @@ -173,9 +178,9 @@ void patchesDialog::setup ( fluid_synth_t * pSynth, int iChan, m_iBank = 0; fluid_preset_t *pPreset = ::fluid_synth_get_channel_preset(m_pSynth, m_iChan); if (pPreset) { - m_iBank = pPreset->get_banknum(pPreset); + m_iBank = fluid_preset_get_banknum(pPreset); #ifdef CONFIG_FLUID_BANK_OFFSET - m_iBank += ::fluid_synth_get_bank_offset(m_pSynth, (pPreset->sfont)->id); + m_iBank += ::fluid_synth_get_bank_offset(m_pSynth, fluid_sfont_get_id(fluid_preset_get_sfont(sfont))); #endif } @@ -186,7 +191,7 @@ void patchesDialog::setup ( fluid_synth_t * pSynth, int iChan, // Set the selected program. if (pPreset) - m_iProg = pPreset->get_num(pPreset); + m_iProg = fluid_preset_get_num(pPreset); QTreeWidgetItem *pProgItem = findProgItem(m_iProg); m_progListView->setCurrentItem(pProgItem); m_progListView->scrollToItem(pProgItem); @@ -312,7 +317,6 @@ void patchesDialog::bankChanged (void) // Clear up the program listview. m_progListView->setSortingEnabled(false); m_progListView->clear(); - fluid_preset_t preset; QTreeWidgetItem *pProgItem = NULL; // For all soundfonts (in reversed stack order) fill the available programs... int cSoundFonts = ::fluid_synth_sfcount(m_pSynth); @@ -320,23 +324,29 @@ void patchesDialog::bankChanged (void) fluid_sfont_t *pSoundFont = ::fluid_synth_get_sfont(m_pSynth, i); if (pSoundFont) { #ifdef CONFIG_FLUID_BANK_OFFSET - int iBankOffset = ::fluid_synth_get_bank_offset(m_pSynth, pSoundFont->id); + int iBankOffset = ::fluid_synth_get_bank_offset(m_pSynth, fluid_sfont_get_id(pSoundFont)); #endif - pSoundFont->iteration_start(pSoundFont); - while (pSoundFont->iteration_next(pSoundFont, &preset)) { - int iBank = preset.get_banknum(&preset); + fluid_sfont_iteration_start(pSoundFont); +#if FLUIDSYNTH_VERSION_MAJOR < 2 + fluid_preset_t preset; + fluid_preset_t *pCurPreset = &preset; +#else + fluid_preset_t *pCurPreset; +#endif + while ((pCurPreset = fluid_sfont_iteration_next_wrapper(pSoundFont, pCurPreset))) { + int iBank = fluid_preset_get_banknum(pCurPreset); #ifdef CONFIG_FLUID_BANK_OFFSET iBank += iBankOffset; #endif - int iProg = preset.get_num(&preset); + int iProg = fluid_preset_get_num(pCurPreset); if (iBank == iBankSelected && !findProgItem(iProg)) { pProgItem = new patchItem(m_progListView, pProgItem); if (pProgItem) { pProgItem->setText(0, QString::number(iProg)); - pProgItem->setText(1, preset.get_name(&preset)); - //pProgItem->setText(2, QString::number(pSoundFont->id)); + pProgItem->setText(1, fluid_preset_get_name(pCurPreset)); + //pProgItem->setText(2, QString::number(fluid_sfont_get_id(pSoundFont))); //pProgItem->setText(3, QFileInfo( - // pSoundFont->get_name(pSoundFont)).baseName()); + // fluid_sfont_get_name(pSoundFont).baseName()); } } } diff --git a/plugins/sf2_player/patches_dialog.h b/plugins/sf2_player/patches_dialog.h index f4523ff90..a2c88a79d 100644 --- a/plugins/sf2_player/patches_dialog.h +++ b/plugins/sf2_player/patches_dialog.h @@ -29,7 +29,7 @@ #include "ui_patches_dialog.h" #include "LcdSpinBox.h" -#include +#include "fluidsynthshims.h" #include #include diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index 742f5fb8e..f7a09f01e 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -127,6 +127,29 @@ sf2Instrument::sf2Instrument( InstrumentTrack * _instrument_track ) : // everytime we load a new soundfont. m_synth = new_fluid_synth( m_settings ); +#if FLUIDSYNTH_VERSION_MAJOR >= 2 + // Get the default values from the setting + double settingVal; + + fluid_settings_getnum_default(m_settings, "synth.reverb.room-size", &settingVal); + m_reverbRoomSize.setInitValue(settingVal); + fluid_settings_getnum_default(m_settings, "synth.reverb.damping", &settingVal); + m_reverbDamping.setInitValue(settingVal); + fluid_settings_getnum_default(m_settings, "synth.reverb.width", &settingVal); + m_reverbWidth.setInitValue(settingVal); + fluid_settings_getnum_default(m_settings, "synth.reverb.level", &settingVal); + m_reverbLevel.setInitValue(settingVal); + + fluid_settings_getnum_default(m_settings, "synth.chorus.nr", &settingVal); + m_chorusNum.setInitValue(settingVal); + fluid_settings_getnum_default(m_settings, "synth.chorus.level", &settingVal); + m_chorusLevel.setInitValue(settingVal); + fluid_settings_getnum_default(m_settings, "synth.chorus.speed", &settingVal); + m_chorusSpeed.setInitValue(settingVal); + fluid_settings_getnum_default(m_settings, "synth.chorus.depth", &settingVal); + m_chorusDepth.setInitValue(settingVal); +#endif + loadFile( ConfigManager::inst()->defaultSoundfont() ); updateSampleRate(); @@ -392,7 +415,6 @@ QString sf2Instrument::getCurrentPatchName() int iBankSelected = m_bankNum.value(); int iProgSelected = m_patchNum.value(); - fluid_preset_t preset; // For all soundfonts (in reversed stack order) fill the available programs... int cSoundFonts = ::fluid_synth_sfcount( m_synth ); for( int i = 0; i < cSoundFonts; i++ ) @@ -403,21 +425,26 @@ QString sf2Instrument::getCurrentPatchName() #ifdef CONFIG_FLUID_BANK_OFFSET int iBankOffset = fluid_synth_get_bank_offset( - m_synth, pSoundFont->id ); + m_synth, fluid_sfont_get_id(pSoundFont) ); #endif - pSoundFont->iteration_start( pSoundFont ); - while( pSoundFont->iteration_next( pSoundFont, - &preset ) ) + fluid_sfont_iteration_start( pSoundFont ); +#if FLUIDSYNTH_VERSION_MAJOR < 2 + fluid_preset_t preset; + fluid_preset_t *pCurPreset = &preset; +#else + fluid_preset_t *pCurPreset; +#endif + while ((pCurPreset = fluid_sfont_iteration_next_wrapper(pSoundFont, pCurPreset))) { - int iBank = preset.get_banknum( &preset ); + int iBank = fluid_preset_get_banknum( pCurPreset ); #ifdef CONFIG_FLUID_BANK_OFFSET iBank += iBankOffset; #endif - int iProg = preset.get_num( &preset ); + int iProg = fluid_preset_get_num( pCurPreset ); if( iBank == iBankSelected && iProg == iProgSelected ) { - return preset.get_name( &preset ); + return fluid_preset_get_name( pCurPreset ); } } } diff --git a/plugins/sf2_player/sf2_player.h b/plugins/sf2_player/sf2_player.h index 0d29c27e1..eed7e24ab 100644 --- a/plugins/sf2_player/sf2_player.h +++ b/plugins/sf2_player/sf2_player.h @@ -36,7 +36,7 @@ #include "Knob.h" #include "LcdSpinBox.h" #include "LedCheckbox.h" -#include "fluidsynth.h" +#include "fluidsynthshims.h" #include "MemoryManager.h" class sf2InstrumentView; From d8fb07ff52ee87a290ad7e69d0851cfb1c20d261 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 29 Oct 2018 16:17:41 +0900 Subject: [PATCH 151/445] Fix minor glitches with sample tracks (#4666) Switches some signal-slot connections to Qt::DirectConnection. Now LMMS can handle loop points correctly and export samples without glitches. Also tweaks some Mixer-related code to avoid related deadlocks on export. --- include/Mixer.h | 5 +++-- src/core/Mixer.cpp | 10 ++++++---- src/core/ProjectRenderer.cpp | 5 ++++- src/core/Song.cpp | 4 +--- src/tracks/SampleTrack.cpp | 9 ++++++--- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/include/Mixer.h b/include/Mixer.h index 3063b0f2b..757a08d49 100644 --- a/include/Mixer.h +++ b/include/Mixer.h @@ -171,10 +171,11 @@ public: return m_audioDevStartFailed; } - void setAudioDevice( AudioDevice * _dev ); + void setAudioDevice( AudioDevice * _dev , bool startNow ); void setAudioDevice( AudioDevice * _dev, const struct qualitySettings & _qs, - bool _needs_fifo ); + bool _needs_fifo, + bool startNow ); void storeAudioDevice(); void restoreAudioDevice(); inline AudioDevice * audioDev() diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index 67736742d..fae7b35db 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -575,7 +575,8 @@ void Mixer::changeQuality( const struct qualitySettings & _qs ) -void Mixer::setAudioDevice( AudioDevice * _dev ) +void Mixer::setAudioDevice( AudioDevice * _dev, + bool startNow ) { stopProcessing(); @@ -592,7 +593,7 @@ void Mixer::setAudioDevice( AudioDevice * _dev ) emit sampleRateChanged(); - startProcessing(); + if (startNow) {startProcessing();} } @@ -600,7 +601,8 @@ void Mixer::setAudioDevice( AudioDevice * _dev ) void Mixer::setAudioDevice( AudioDevice * _dev, const struct qualitySettings & _qs, - bool _needs_fifo ) + bool _needs_fifo, + bool startNow ) { // don't delete the audio-device stopProcessing(); @@ -621,7 +623,7 @@ void Mixer::setAudioDevice( AudioDevice * _dev, emit qualitySettingsChanged(); emit sampleRateChanged(); - startProcessing( _needs_fifo ); + if (startNow) {startProcessing( _needs_fifo );} } diff --git a/src/core/ProjectRenderer.cpp b/src/core/ProjectRenderer.cpp index 3e3004db7..95ed1bd8d 100644 --- a/src/core/ProjectRenderer.cpp +++ b/src/core/ProjectRenderer.cpp @@ -146,7 +146,7 @@ void ProjectRenderer::startProcessing() // make slots connected to sampleRateChanged()-signals being // called immediately Engine::mixer()->setAudioDevice( m_fileDev, - m_qualitySettings, false ); + m_qualitySettings, false, false ); start( #ifndef LMMS_BUILD_WIN32 @@ -185,6 +185,9 @@ void ProjectRenderer::run() 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 diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 1ebc684c1..f715c8319 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -356,9 +356,7 @@ void Song::processNextBuffer() m_vstSyncController.setAbsolutePosition( ticks ); m_vstSyncController.setPlaybackJumped( true ); - } - else if( m_playPos[m_playMode] == tl->loopEnd() - 1 ) - { + emit updateSampleTracks(); } } diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 63efa4d26..fd9a92a23 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -72,13 +72,16 @@ SampleTCO::SampleTCO( Track * _track ) : connect( timeLine, SIGNAL( positionMarkerMoved() ), this, SLOT( playbackPositionChanged() ) ); } //playbutton clicked or space key / on Export Song set isPlaying to false - connect( Engine::getSong(), SIGNAL( playbackStateChanged() ), this, SLOT( playbackPositionChanged() ) ); + connect( Engine::getSong(), SIGNAL( playbackStateChanged() ), + this, SLOT( playbackPositionChanged() ), Qt::DirectConnection ); //care about loops - connect( Engine::getSong(), SIGNAL( updateSampleTracks() ), this, SLOT( playbackPositionChanged() ) ); + connect( Engine::getSong(), SIGNAL( updateSampleTracks() ), + this, SLOT( playbackPositionChanged() ), Qt::DirectConnection ); //care about mute TCOs connect( this, SIGNAL( dataChanged() ), this, SLOT( playbackPositionChanged() ) ); //care about mute track - connect( getTrack()->getMutedModel(), SIGNAL( dataChanged() ),this, SLOT( playbackPositionChanged() ) ); + connect( getTrack()->getMutedModel(), SIGNAL( dataChanged() ), + this, SLOT( playbackPositionChanged() ), Qt::DirectConnection ); //care about TCO position connect( this, SIGNAL( positionChanged() ), this, SLOT( updateTrackTcos() ) ); From 86f9a75d98a0389c60975eade7b88944f8e82907 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 7 Nov 2018 13:41:03 +0900 Subject: [PATCH 152/445] 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 153/445] 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 154/445] 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 155/445] 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 156/445] 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 d9b91338ea96c3658669bdb175164bc0d6e33b6b Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 13 Nov 2018 19:30:59 +0900 Subject: [PATCH 157/445] Fix finding pkg-config on cross compile Switch back to `ENV{PKG_CONFIG}` to ensure that FindPkgConfig doesn't overwrite `PKG_CONFIG_EXECUTABLE`. Since CMake 3.3 supports the environment variable, it's safe to use that. --- cmake/toolchains/common/Ubuntu-MinGW-W64.cmake | 2 +- cmake/toolchains/common/Ubuntu-MinGW-X-Trusty.cmake | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/toolchains/common/Ubuntu-MinGW-W64.cmake b/cmake/toolchains/common/Ubuntu-MinGW-W64.cmake index acb2cbf91..2f78a441e 100644 --- a/cmake/toolchains/common/Ubuntu-MinGW-W64.cmake +++ b/cmake/toolchains/common/Ubuntu-MinGW-W64.cmake @@ -6,7 +6,7 @@ set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) -SET(PKG_CONFIG_EXECUTABLE /usr/bin/${TOOLCHAIN_PREFIX}-pkg-config) +SET(ENV{PKG_CONFIG} /usr/bin/${TOOLCHAIN_PREFIX}-pkg-config) IF(WIN64) SET(TOOLCHAIN_PREFIX32 ${CMAKE_SYSTEM_PROCESSOR32}-w64-mingw32) diff --git a/cmake/toolchains/common/Ubuntu-MinGW-X-Trusty.cmake b/cmake/toolchains/common/Ubuntu-MinGW-X-Trusty.cmake index 1dabc3555..686f4497f 100644 --- a/cmake/toolchains/common/Ubuntu-MinGW-X-Trusty.cmake +++ b/cmake/toolchains/common/Ubuntu-MinGW-X-Trusty.cmake @@ -19,7 +19,7 @@ SET(CMAKE_RC_COMPILER ${MINGW_TOOL_PREFIX}windres) # Mingw tools SET(STRIP ${MINGW_TOOL_PREFIX}strip) -SET(PKG_CONFIG_EXECUTABLE ${MINGW_TOOL_PREFIX}pkg-config) +SET(ENV{PKG_CONFIG} ${MINGW_TOOL_PREFIX}pkg-config) # For 32-bit vst support IF(WIN64) @@ -45,7 +45,7 @@ IF(NOT DEFINED ENV{MINGW_DEBUG_INFO}) MESSAGE("* CMAKE_C_COMPILER : ${CMAKE_C_COMPILER}") MESSAGE("* CMAKE_CXX_COMPILER : ${CMAKE_CXX_COMPILER}") MESSAGE("* CMAKE_RC_COMPILER : ${CMAKE_RC_COMPILER}") - MESSAGE("* PKG_CONFIG_EXECUTABLE : ${PKG_CONFIG_EXECUTABLE}") + MESSAGE("* ENV{PKG_CONFIG} : $ENV{PKG_CONFIG}") MESSAGE("* MINGW_TOOL_PREFIX32 : ${MINGW_TOOL_PREFIX32}") MESSAGE("* CMAKE_C_COMPILER32 : ${CMAKE_C_COMPILER32}") MESSAGE("* CMAKE_CXX_COMPILER32 : ${CMAKE_CXX_COMPILER32}") From 244b70b4c8bce27bfb3b5185759e6ab6d9b8bec5 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 13 Nov 2018 19:33:28 +0900 Subject: [PATCH 158/445] Fix building unit tests targetting windows Fixes MSVC's LNK4217 warnings and MinGW errors. --- .circleci/config.yml | 6 ++++++ .travis/script.sh | 4 +--- src/CMakeLists.txt | 9 ++++++--- tests/CMakeLists.txt | 3 +++ 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 95b98c595..54301863d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -54,6 +54,9 @@ jobs: ../cmake/build_win32.sh make lmms make + - run: + name: Build tests + command: cd build && make tests - *ccache_stats - *save_cache mingw64: @@ -71,6 +74,9 @@ jobs: mkdir build && cd build ../cmake/build_win64.sh make + - run: + name: Build tests + command: cd build && make tests - *ccache_stats - *save_cache linux.gcc: diff --git a/.travis/script.sh b/.travis/script.sh index 9f7e1081f..27e9ec7fb 100755 --- a/.travis/script.sh +++ b/.travis/script.sh @@ -24,12 +24,10 @@ else "$TRAVIS_BUILD_DIR/.travis/$TRAVIS_OS_NAME.$TARGET_OS.script.sh" make -j4 + make tests if [[ $TARGET_OS != win* ]]; then - - make tests tests/tests - fi # Package and upload non-tagged builds diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cd40ad747..37da8f414 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -116,12 +116,15 @@ TARGET_INCLUDE_DIRECTORIES(lmms PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ) -# GENERATE_EXPORT_HEADER doesn't do this automatically for OBJECT libraries +# CMake doesn't define target_EXPORTS for OBJECT libraries. +# See the documentation of DEFINE_SYMBOL for details. +# Also add LMMS_STATIC_DEFINE for targets linking against it. TARGET_COMPILE_DEFINITIONS(lmmsobjs PRIVATE -Dlmmsobjs_EXPORTS + INTERFACE -DLMMS_STATIC_DEFINE ) TARGET_COMPILE_DEFINITIONS(lmms - PRIVATE -Dlmmsobjs_EXPORTS + PRIVATE $ ) # Set Visual Studio startup project to lmms @@ -389,4 +392,4 @@ ELSE(NOT MSVC) # "${VCPKG_ROOT}/bin/libsoundio.dll" # DESTINATION .) #ENDIF() -ENDIF(NOT MSVC) \ No newline at end of file +ENDIF(NOT MSVC) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 249e38191..c39f8e56e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -19,5 +19,8 @@ ADD_EXECUTABLE(tests src/tracks/AutomationTrackTest.cpp ) +TARGET_COMPILE_DEFINITIONS(tests + PRIVATE $ +) TARGET_LINK_LIBRARIES(tests ${QT_LIBRARIES} ${QT_QTTEST_LIBRARY}) TARGET_LINK_LIBRARIES(tests ${LMMS_REQUIRED_LIBS}) From 187fbf419167c2e7998c1dea183c8564c4d4a39e Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 21 Nov 2018 17:39:40 +0900 Subject: [PATCH 159/445] AppVeyor: don't specify any patch version of Qt Fixes broken build due to the upgraded Qt version in the AppVeyor image. --- .appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index 350e4351f..3cb5d9a93 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -16,7 +16,7 @@ build_script: - cd build - ps: $env:CMAKE_PLATFORM="$(if ($env:PLATFORM -eq 'x64') { 'x64' } else { '' })" - ps: $env:QT_SUFFIX="$(if ($env:PLATFORM -eq 'x64') { '_64' } else { '' })" - - cmake -DUSE_COMPILE_CACHE=ON -DCACHE_TOOL=%APPVEYOR_BUILD_FOLDER%/clcache.4.1.0/clcache-4.1.0/clcache.exe -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_PREFIX_PATH=c:/Qt/5.9.5/msvc2015%QT_SUFFIX%;c:/tools/vcpkg/installed/%PLATFORM%-windows -DCMAKE_GENERATOR_PLATFORM="%CMAKE_PLATFORM%" .. + - cmake -DUSE_COMPILE_CACHE=ON -DCACHE_TOOL=%APPVEYOR_BUILD_FOLDER%/clcache.4.1.0/clcache-4.1.0/clcache.exe -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_PREFIX_PATH=c:/Qt/5.9/msvc2015%QT_SUFFIX%;c:/tools/vcpkg/installed/%PLATFORM%-windows -DCMAKE_GENERATOR_PLATFORM="%CMAKE_PLATFORM%" .. - cmake --build . -- /maxcpucount:4 - cmake --build . --target tests cache: From 3922d25b5022b36feb4a6f8697659090370d7dc0 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 21 Nov 2018 17:45:20 +0900 Subject: [PATCH 160/445] Fix CircleCI builds I don't know why, but it fails to fetch submodules... --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 54301863d..4174ba1ef 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -28,6 +28,8 @@ shared: name: Initialize command: | mkdir -p /tmp/artifacts + # Workaround for failing submodule fetching + git config --global --unset url."ssh://git@github.com".insteadOf || true # Commmon environment variables common_environment: &common_environment From cf3d7950b10975d41998db29f9a9aac441fd95ef Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 1 Dec 2018 10:16:25 +0100 Subject: [PATCH 161/445] Refactor SetupDialog --- src/gui/SetupDialog.cpp | 424 ++++++++++------------------------------ 1 file changed, 105 insertions(+), 319 deletions(-) diff --git a/src/gui/SetupDialog.cpp b/src/gui/SetupDialog.cpp index 857261eb1..13392439f 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -203,126 +203,45 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : const int HeaderSize = 30; int labelNumber = 0; + auto addLedCheckBox = [&misc_tw, &labelNumber, this]( + const char* ledText, + bool initialState, + const char* toggledSlot + ){ + LedCheckBox * checkBox = new LedCheckBox(tr(ledText), misc_tw); + labelNumber++; + checkBox->move(XDelta, YDelta*labelNumber); + checkBox->setChecked(initialState); + connect(checkBox, SIGNAL(toggled(bool)), this, toggledSlot); + }; - LedCheckBox * enable_tooltips = new LedCheckBox( - tr( "Enable tooltips" ), - misc_tw ); - labelNumber++; - enable_tooltips->move( XDelta, YDelta*labelNumber ); - enable_tooltips->setChecked( m_toolTips ); - connect( enable_tooltips, SIGNAL( toggled( bool ) ), - this, SLOT( toggleToolTips( bool ) ) ); - - - LedCheckBox * restart_msg = new LedCheckBox( - tr( "Show restart warning after changing settings" ), - misc_tw ); - labelNumber++; - restart_msg->move( XDelta, YDelta*labelNumber ); - restart_msg->setChecked( m_warnAfterSetup ); - connect( restart_msg, SIGNAL( toggled( bool ) ), - this, SLOT( toggleWarnAfterSetup( bool ) ) ); - - - LedCheckBox * dbfs = new LedCheckBox( tr( "Display volume as dBFS " ), - misc_tw ); - labelNumber++; - dbfs->move( XDelta, YDelta*labelNumber ); - dbfs->setChecked( m_displaydBFS ); - connect( dbfs, SIGNAL( toggled( bool ) ), - this, SLOT( toggleDisplaydBFS( bool ) ) ); - - - LedCheckBox * mmpz = new LedCheckBox( - tr( "Compress project files per default" ), - misc_tw ); - labelNumber++; - mmpz->move( XDelta, YDelta*labelNumber ); - mmpz->setChecked( m_MMPZ ); - connect( mmpz, SIGNAL( toggled( bool ) ), - this, SLOT( toggleMMPZ( bool ) ) ); - - LedCheckBox * oneitw = new LedCheckBox( - tr( "One instrument track window mode" ), - misc_tw ); - labelNumber++; - oneitw->move( XDelta, YDelta*labelNumber ); - oneitw->setChecked( m_oneInstrumentTrackWindow ); - connect( oneitw, SIGNAL( toggled( bool ) ), - this, SLOT( toggleOneInstrumentTrackWindow( bool ) ) ); - - LedCheckBox * hqaudio = new LedCheckBox( - tr( "HQ-mode for output audio-device" ), - misc_tw ); - labelNumber++; - hqaudio->move( XDelta, YDelta*labelNumber ); - hqaudio->setChecked( m_hqAudioDev ); - connect( hqaudio, SIGNAL( toggled( bool ) ), - this, SLOT( toggleHQAudioDev( bool ) ) ); - - LedCheckBox * compacttracks = new LedCheckBox( - tr( "Compact track buttons" ), - misc_tw ); - labelNumber++; - compacttracks->move( XDelta, YDelta*labelNumber ); - compacttracks->setChecked( m_compactTrackButtons ); - connect( compacttracks, SIGNAL( toggled( bool ) ), - this, SLOT( toggleCompactTrackButtons( bool ) ) ); - - - LedCheckBox * syncVST = new LedCheckBox( - tr( "Sync VST plugins to host playback" ), - misc_tw ); - labelNumber++; - syncVST->move( XDelta, YDelta*labelNumber ); - syncVST->setChecked( m_syncVSTPlugins ); - connect( syncVST, SIGNAL( toggled( bool ) ), - this, SLOT( toggleSyncVSTPlugins( bool ) ) ); - - LedCheckBox * noteLabels = new LedCheckBox( - tr( "Enable note labels in piano roll" ), - misc_tw ); - labelNumber++; - noteLabels->move( XDelta, YDelta*labelNumber ); - noteLabels->setChecked( m_printNoteLabels ); - connect( noteLabels, SIGNAL( toggled( bool ) ), - this, SLOT( toggleNoteLabels( bool ) ) ); - - LedCheckBox * displayWaveform = new LedCheckBox( - tr( "Enable waveform display by default" ), - misc_tw ); - labelNumber++; - displayWaveform->move( XDelta, YDelta*labelNumber ); - displayWaveform->setChecked( m_displayWaveform ); - connect( displayWaveform, SIGNAL( toggled( bool ) ), - this, SLOT( toggleDisplayWaveform( bool ) ) ); - - LedCheckBox * disableAutoquit = new LedCheckBox( - tr( "Keep effects running even without input" ), - misc_tw ); - labelNumber++; - disableAutoquit->move( XDelta, YDelta*labelNumber ); - disableAutoquit->setChecked( m_disableAutoQuit ); - connect( disableAutoquit, SIGNAL( toggled( bool ) ), - this, SLOT( toggleDisableAutoquit( bool ) ) ); - - LedCheckBox * disableBackup = new LedCheckBox( - tr( "Create backup file when saving a project" ), - misc_tw ); - labelNumber++; - disableBackup->move( XDelta, YDelta*labelNumber ); - disableBackup->setChecked( m_disableBackup ); - connect( disableBackup, SIGNAL( toggled( bool ) ), - this, SLOT( toggleDisableBackup( bool ) ) ); - - LedCheckBox * openLastProject = new LedCheckBox( - tr( "Reopen last project on start" ), - misc_tw ); - labelNumber++; - openLastProject->move( XDelta, YDelta*labelNumber ); - openLastProject->setChecked( m_openLastProject ); - connect( openLastProject, SIGNAL( toggled( bool ) ), - this, SLOT( toggleOpenLastProject( bool ) ) ); + addLedCheckBox("Enable tooltips", + m_toolTips, SLOT(toggleToolTips(bool))); + addLedCheckBox("Show restart warning after changing settings", + m_warnAfterSetup, SLOT(toggleWarnAfterSetup(bool))); + addLedCheckBox("Display volume as dBFS ", + m_displaydBFS, SLOT(toggleDisplaydBFS(bool))); + addLedCheckBox("Compress project files per default", + m_MMPZ, SLOT(toggleMMPZ(bool))); + addLedCheckBox("One instrument track window mode", + m_oneInstrumentTrackWindow, + SLOT(toggleOneInstrumentTrackWindow(bool))); + addLedCheckBox("HQ-mode for output audio-device", + m_hqAudioDev, SLOT(toggleHQAudioDev(bool))); + addLedCheckBox("Compact track buttons", + m_compactTrackButtons, SLOT(toggleCompactTrackButtons(bool))); + addLedCheckBox("Sync VST plugins to host playback", + m_syncVSTPlugins, SLOT(toggleSyncVSTPlugins(bool))); + addLedCheckBox("Enable note labels in piano roll", + m_printNoteLabels, SLOT(toggleNoteLabels(bool))); + addLedCheckBox("Enable waveform display by default", + m_displayWaveform, SLOT(toggleDisplayWaveform(bool))); + addLedCheckBox("Keep effects running even without input", + m_disableAutoQuit, SLOT(toggleDisableAutoquit(bool))); + addLedCheckBox("Create backup file when saving a project", + m_disableBackup, SLOT(toggleDisableBackup(bool))); + addLedCheckBox("Reopen last project on start", + m_openLastProject, SLOT(toggleOpenLastProject(bool))); misc_tw->setFixedHeight( YDelta*labelNumber + HeaderSize ); @@ -432,216 +351,83 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : const int btnStart = 297; - // working-dir - TabWidget * lmms_wd_tw = new TabWidget( tr( - "LMMS working directory" ).toUpper(), - pathSelectors ); - lmms_wd_tw->setFixedHeight( 48 ); + auto addPathEntry = [&](const char* caption, + const QString& content, + const char* setSlot, + const char* openSlot, + QLineEdit*& lineEdit, + QWidget* twParent, + const char* pixmap = "project_open") + { + TabWidget * newTw = new TabWidget(tr(caption).toUpper(), + twParent); + newTw->setFixedHeight(48); - m_wdLineEdit = new QLineEdit( m_workingDir, lmms_wd_tw ); - m_wdLineEdit->setGeometry( 10, 20, txtLength, 16 ); - connect( m_wdLineEdit, SIGNAL( textChanged( const QString & ) ), this, - SLOT( setWorkingDir( const QString & ) ) ); + lineEdit = new QLineEdit(content, newTw); + lineEdit->setGeometry(10, 20, txtLength, 16); + connect(lineEdit, SIGNAL(textChanged(const QString &)), + this, setSlot); - QPushButton * workingdir_select_btn = new QPushButton( - embed::getIconPixmap( "project_open", 16, 16 ), - "", lmms_wd_tw ); - workingdir_select_btn->setFixedSize( 24, 24 ); - workingdir_select_btn->move( btnStart, 16 ); - connect( workingdir_select_btn, SIGNAL( clicked() ), this, - SLOT( openWorkingDir() ) ); - - - // artwork-dir - TabWidget * artwork_tw = new TabWidget( tr( - "Themes directory" ).toUpper(), - pathSelectors ); - artwork_tw->setFixedHeight( 48 ); - - m_adLineEdit = new QLineEdit( m_artworkDir, artwork_tw ); - m_adLineEdit->setGeometry( 10, 20, txtLength, 16 ); - connect( m_adLineEdit, SIGNAL( textChanged( const QString & ) ), this, - SLOT( setArtworkDir( const QString & ) ) ); - - QPushButton * artworkdir_select_btn = new QPushButton( - embed::getIconPixmap( "project_open", 16, 16 ), - "", artwork_tw ); - artworkdir_select_btn->setFixedSize( 24, 24 ); - artworkdir_select_btn->move( btnStart, 16 ); - connect( artworkdir_select_btn, SIGNAL( clicked() ), this, - SLOT( openArtworkDir() ) ); - - - - // background artwork file - TabWidget * backgroundArtwork_tw = new TabWidget( tr( - "Background artwork" ).toUpper(), paths ); - backgroundArtwork_tw->setFixedHeight( 48 ); - - m_baLineEdit = new QLineEdit( m_backgroundArtwork, - backgroundArtwork_tw ); - m_baLineEdit->setGeometry( 10, 20, txtLength, 16 ); - connect( m_baLineEdit, SIGNAL( textChanged( const QString & ) ), this, - SLOT( setBackgroundArtwork( const QString & ) ) ); - - QPushButton * backgroundartworkdir_select_btn = new QPushButton( - embed::getIconPixmap( "project_open", 16, 16 ), - "", backgroundArtwork_tw ); - backgroundartworkdir_select_btn->setFixedSize( 24, 24 ); - backgroundartworkdir_select_btn->move( btnStart, 16 ); - connect( backgroundartworkdir_select_btn, SIGNAL( clicked() ), this, - SLOT( openBackgroundArtwork() ) ); - - // vst-dir - TabWidget * vst_tw = new TabWidget( tr( - "VST-plugin directory" ).toUpper(), - pathSelectors ); - vst_tw->setFixedHeight( 48 ); - - m_vdLineEdit = new QLineEdit( m_vstDir, vst_tw ); - m_vdLineEdit->setGeometry( 10, 20, txtLength, 16 ); - connect( m_vdLineEdit, SIGNAL( textChanged( const QString & ) ), this, - SLOT( setVSTDir( const QString & ) ) ); - - QPushButton * vstdir_select_btn = new QPushButton( - embed::getIconPixmap( "project_open", 16, 16 ), - "", vst_tw ); - vstdir_select_btn->setFixedSize( 24, 24 ); - vstdir_select_btn->move( btnStart, 16 ); - connect( vstdir_select_btn, SIGNAL( clicked() ), this, - SLOT( openVSTDir() ) ); - - // gig-dir - TabWidget * gig_tw = new TabWidget( tr( - "GIG directory" ).toUpper(), - pathSelectors ); - gig_tw->setFixedHeight( 48 ); - - m_gigLineEdit = new QLineEdit( m_gigDir, gig_tw ); - m_gigLineEdit->setGeometry( 10, 20, txtLength, 16 ); - connect( m_gigLineEdit, SIGNAL( textChanged( const QString & ) ), this, - SLOT( setGIGDir( const QString & ) ) ); - - QPushButton * gigdir_select_btn = new QPushButton( - embed::getIconPixmap( "project_open", 16, 16 ), - "", gig_tw ); - gigdir_select_btn->setFixedSize( 24, 24 ); - gigdir_select_btn->move( btnStart, 16 ); - connect( gigdir_select_btn, SIGNAL( clicked() ), this, - SLOT( openGIGDir() ) ); - - // sf2-dir - TabWidget * sf2_tw = new TabWidget( tr( - "SF2 directory" ).toUpper(), - pathSelectors ); - sf2_tw->setFixedHeight( 48 ); - - m_sf2LineEdit = new QLineEdit( m_sf2Dir, sf2_tw ); - m_sf2LineEdit->setGeometry( 10, 20, txtLength, 16 ); - connect( m_sf2LineEdit, SIGNAL( textChanged( const QString & ) ), this, - SLOT( setSF2Dir( const QString & ) ) ); - - QPushButton * sf2dir_select_btn = new QPushButton( - embed::getIconPixmap( "project_open", 16, 16 ), - "", sf2_tw ); - sf2dir_select_btn->setFixedSize( 24, 24 ); - sf2dir_select_btn->move( btnStart, 16 ); - connect( sf2dir_select_btn, SIGNAL( clicked() ), this, - SLOT( openSF2Dir() ) ); - - - - // LADSPA-dir - TabWidget * lad_tw = new TabWidget( tr( - "LADSPA plugin directories" ).toUpper(), - paths ); - lad_tw->setFixedHeight( 48 ); - - m_ladLineEdit = new QLineEdit( m_ladDir, lad_tw ); - m_ladLineEdit->setGeometry( 10, 20, txtLength, 16 ); - connect( m_ladLineEdit, SIGNAL( textChanged( const QString & ) ), this, - SLOT( setLADSPADir( const QString & ) ) ); - - QPushButton * laddir_select_btn = new QPushButton( - embed::getIconPixmap( "add_folder", 16, 16 ), - "", lad_tw ); - laddir_select_btn->setFixedSize( 24, 24 ); - laddir_select_btn->move( btnStart, 16 ); - connect( laddir_select_btn, SIGNAL( clicked() ), this, - SLOT( openLADSPADir() ) ); + QPushButton * selectBtn = new QPushButton( + embed::getIconPixmap(pixmap, 16, 16), + "", newTw); + selectBtn->setFixedSize(24, 24); + selectBtn->move(btnStart, 16); + connect(selectBtn, SIGNAL(clicked()), this, openSlot); + pathSelectorLayout->addWidget(newTw); + pathSelectorLayout->addSpacing(10); + }; + addPathEntry("LMMS working directory", m_workingDir, + SLOT(setWorkingDir(const QString &)), + SLOT(openWorkingDir()), + m_wdLineEdit, pathSelectors); + addPathEntry("GIG directory", m_gigDir, + SLOT(setGIGDir(const QString &)), + SLOT(openGIGDir()), + m_gigLineEdit, pathSelectors); + addPathEntry("SF2 directory", m_sf2Dir, + SLOT(setSF2Dir(const QString &)), + SLOT(openSF2Dir()), + m_sf2LineEdit, pathSelectors); + addPathEntry("VST-plugin directory", m_vstDir, + SLOT(setVSTDir(const QString &)), + SLOT(openVSTDir()), + m_vdLineEdit, pathSelectors); + addPathEntry("LADSPA plugin directories", m_ladDir, + SLOT(setLADSPADir(const QString &)), + SLOT(openLADSPADir()), + m_ladLineEdit, paths, + "add_folder"); #ifdef LMMS_HAVE_STK - // STK-dir - TabWidget * stk_tw = new TabWidget( tr( - "STK rawwave directory" ).toUpper(), - paths ); - stk_tw->setFixedHeight( 48 ); - - m_stkLineEdit = new QLineEdit( m_stkDir, stk_tw ); - m_stkLineEdit->setGeometry( 10, 20, txtLength, 16 ); - connect( m_stkLineEdit, SIGNAL( textChanged( const QString & ) ), this, - SLOT( setSTKDir( const QString & ) ) ); - - QPushButton * stkdir_select_btn = new QPushButton( - embed::getIconPixmap( "project_open", 16, 16 ), - "", stk_tw ); - stkdir_select_btn->setFixedSize( 24, 24 ); - stkdir_select_btn->move( btnStart, 16 ); - connect( stkdir_select_btn, SIGNAL( clicked() ), this, - SLOT( openSTKDir() ) ); + addPathEntry("STK rawwave directory", m_stkDir, + SLOT(setSTKDir(const QString &)), + SLOT(openSTKDir()), + m_stkLineEdit, paths); #endif - #ifdef LMMS_HAVE_FLUIDSYNTH - // Soundfont - TabWidget * sf_tw = new TabWidget( tr( - "Default Soundfont File" ).toUpper(), paths ); - sf_tw->setFixedHeight( 48 ); - - m_sfLineEdit = new QLineEdit( m_defaultSoundfont, sf_tw ); - m_sfLineEdit->setGeometry( 10, 20, txtLength, 16 ); - connect( m_sfLineEdit, SIGNAL( textChanged( const QString & ) ), this, - SLOT( setDefaultSoundfont( const QString & ) ) ); - - QPushButton * sf_select_btn = new QPushButton( - embed::getIconPixmap( "project_open", 16, 16 ), - "", sf_tw ); - sf_select_btn->setFixedSize( 24, 24 ); - sf_select_btn->move( btnStart, 16 ); - connect( sf_select_btn, SIGNAL( clicked() ), this, - SLOT( openDefaultSoundfont() ) ); -#endif - - pathSelectors->setLayout( pathSelectorLayout ); - - pathSelectorLayout->addWidget( lmms_wd_tw ); - pathSelectorLayout->addSpacing( 10 ); - pathSelectorLayout->addWidget( gig_tw ); - pathSelectorLayout->addSpacing( 10 ); - pathSelectorLayout->addWidget( sf2_tw ); - pathSelectorLayout->addSpacing( 10 ); - pathSelectorLayout->addWidget( vst_tw ); - pathSelectorLayout->addSpacing( 10 ); - pathSelectorLayout->addWidget( lad_tw ); -#ifdef LMMS_HAVE_STK - pathSelectorLayout->addSpacing( 10 ); - pathSelectorLayout->addWidget( stk_tw ); -#endif -#ifdef LMMS_HAVE_FLUIDSYNTH - pathSelectorLayout->addSpacing( 10 ); - pathSelectorLayout->addWidget( sf_tw ); -#endif - pathSelectorLayout->addSpacing( 10 ); - pathSelectorLayout->addWidget( artwork_tw ); - pathSelectorLayout->addSpacing( 10 ); + addPathEntry("Default Soundfont File", m_defaultSoundfont, + SLOT(setDefaultSoundfont(const QString &)), + SLOT(openDefaultSoundfont()), + m_sfLineEdit, paths); +#endif + addPathEntry("Themes directory", m_artworkDir, + SLOT(setArtworkDir(const QString &)), + SLOT(openArtwortDir()), + m_adLineEdit, pathSelectors); pathSelectorLayout->addStretch(); - pathSelectorLayout->addWidget( backgroundArtwork_tw ); - pathSelectorLayout->addSpacing( 10 ); + addPathEntry("Background artwork", m_backgroundArtwork, + SLOT(setBackgroundArtwork(const QString &)), + SLOT(openBackgroundArtwork()), + m_baLineEdit, paths); + pathSelectors->setLayout(pathSelectorLayout); - dir_layout->addWidget( pathSelectors ); - pathScroll->setWidget( pathSelectors ); - pathScroll->setWidgetResizable( true ); + dir_layout->addWidget(pathSelectors); + + pathScroll->setWidget(pathSelectors); + pathScroll->setWidgetResizable(true); From 277e8b64443001d0adca0afa379f1fd6ba8c55cc Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Sun, 25 Nov 2018 15:42:14 +0000 Subject: [PATCH 162/445] 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 163/445] 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 164/445] 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 165/445] 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 166/445] 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 05128b9a334ad88155f6f72d14e1807874a65415 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Wed, 12 Dec 2018 17:10:54 +0100 Subject: [PATCH 167/445] Fix error in SetupDialog This adds constants into a lambda capture list. Unnecessary, says the C++14 standard, but this fixes the MSVC C++11 error. --- 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 13392439f..678f5bff9 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -203,7 +203,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : const int HeaderSize = 30; int labelNumber = 0; - auto addLedCheckBox = [&misc_tw, &labelNumber, this]( + auto addLedCheckBox = [&XDelta, &YDelta, &misc_tw, &labelNumber, this]( const char* ledText, bool initialState, const char* toggledSlot From 642b5e7d0484f1b67e5310518afd92774dd54e4e Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Wed, 19 Dec 2018 12:45:33 +0100 Subject: [PATCH 168/445] 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 169/445] 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 170/445] 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 171/445] 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 a1b355828e347b8e7fca8118873fc834953c1d67 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Thu, 27 Dec 2018 18:43:13 +0100 Subject: [PATCH 172/445] Allow sub plugins for instruments aswell * Move m_key member of Effect into Plugin * Pass key to Instrument ctors and instantiaters * Add pluginKeys to all plugin selector widgets, and let them pass the keys when instantiating the instruments; or, if the keys must be passed over threads, pass the keys to the Engine using `Engine::setDndPluginKey()` * As instrument plugin libraries now also need to get their key passed, their second argument, which was always the same as the first, is now used to pass the sub plugin keys. This affects *all* instrument plugins. * Plugin.h: Add more virtuals to `SubPluginFeatures` in order to draw logos and images into instrument selector widgets * LadspaSubPluginFeatures: Implement the `displayName` virtual because the new behaviour to resolve displayNames is to first look at the SubPluginFeatures, which, without override, returns the superior plugin's name (Plugin.cpp) Additional: * PluginFactory.h: Allow setting up search paths without discovering plugins yet * Plugin.h: Add full documentation (should be checked) --- include/Effect.h | 7 - include/Engine.h | 4 + include/Instrument.h | 15 +- include/InstrumentTrack.h | 5 +- include/Ladspa2LMMS.h | 2 + include/Plugin.h | 169 +++++++++++++++--- include/PluginBrowser.h | 5 +- include/PluginFactory.h | 24 ++- plugins/FreeBoy/FreeBoy.cpp | 4 +- plugins/GigPlayer/GigPlayer.cpp | 4 +- .../LadspaEffect/LadspaSubPluginFeatures.cpp | 10 ++ .../LadspaEffect/LadspaSubPluginFeatures.h | 12 +- plugins/OpulenZ/OpulenZ.cpp | 4 +- plugins/Xpressive/Xpressive.cpp | 4 +- .../audio_file_processor.cpp | 5 +- plugins/bit_invader/bit_invader.cpp | 4 +- plugins/carlapatchbay/carlapatchbay.cpp | 4 +- plugins/carlarack/carlarack.cpp | 4 +- plugins/kicker/kicker.cpp | 4 +- plugins/lb302/lb302.cpp | 4 +- plugins/monstro/Monstro.cpp | 4 +- plugins/nes/Nes.cpp | 4 +- plugins/organic/organic.cpp | 4 +- plugins/patman/patman.cpp | 4 +- plugins/sf2_player/sf2_player.cpp | 4 +- plugins/sfxr/sfxr.cpp | 4 +- plugins/sid/sid_instrument.cpp | 5 +- plugins/stk/mallets/mallets.cpp | 4 +- .../triple_oscillator/TripleOscillator.cpp | 4 +- plugins/vestige/vestige.cpp | 4 +- plugins/vibed/vibed.cpp | 4 +- plugins/watsyn/Watsyn.cpp | 4 +- plugins/zynaddsubfx/ZynAddSubFx.cpp | 5 +- src/core/Effect.cpp | 5 +- src/core/Engine.cpp | 21 +++ src/core/Instrument.cpp | 27 ++- src/core/LadspaManager.cpp | 2 +- src/core/Plugin.cpp | 137 +++++++++++++- src/core/PluginFactory.cpp | 109 +++++++---- src/core/PresetPreviewPlayHandle.cpp | 4 +- src/gui/EffectSelectDialog.cpp | 100 +++++------ src/gui/FileBrowser.cpp | 11 +- src/gui/InstrumentView.cpp | 2 +- src/gui/PluginBrowser.cpp | 44 +++-- src/gui/TrackContainerView.cpp | 8 +- src/gui/widgets/TrackLabelButton.cpp | 8 +- src/tracks/InstrumentTrack.cpp | 31 +++- 47 files changed, 612 insertions(+), 245 deletions(-) diff --git a/include/Effect.h b/include/Effect.h index d6aa04d97..3d765fdc0 100644 --- a/include/Effect.h +++ b/include/Effect.h @@ -148,11 +148,6 @@ public: m_noRun = _state; } - inline const Descriptor::SubPluginFeatures::Key & key() const - { - return m_key; - } - EffectChain * effectChain() const { return m_parent; @@ -201,8 +196,6 @@ private: sampleFrame * _dst_buf, sample_rate_t _dst_sr, const f_cnt_t _frames ); - Descriptor::SubPluginFeatures::Key m_key; - ch_cnt_t m_processors; bool m_okay; diff --git a/include/Engine.h b/include/Engine.h index fc2547996..18960ec8f 100644 --- a/include/Engine.h +++ b/include/Engine.h @@ -111,6 +111,9 @@ public: return s_instanceOfMe; } + static void setDndPluginKey(void* newKey); + static void* pickDndPluginKey(); + signals: void initProgress(const QString &msg); @@ -137,6 +140,7 @@ private: static DummyTrackContainer * s_dummyTC; static Ladspa2LMMS * s_ladspaManager; + static void* s_dndPluginKey; // even though most methods are static, an instance is needed for Qt slots/signals static LmmsCore * s_instanceOfMe; diff --git a/include/Instrument.h b/include/Instrument.h index a373ae4ac..c3df04729 100644 --- a/include/Instrument.h +++ b/include/Instrument.h @@ -55,8 +55,9 @@ public: Q_DECLARE_FLAGS(Flags, Flag); - Instrument( InstrumentTrack * _instrument_track, - const Descriptor * _descriptor ); + Instrument(InstrumentTrack * _instrument_track, + const Descriptor * _descriptor, + const Descriptor::SubPluginFeatures::Key * key = nullptr); virtual ~Instrument() = default; // -------------------------------------------------------------------- @@ -113,10 +114,12 @@ public: // provided functions: // -------------------------------------------------------------------- - // instantiate instrument-plugin with given name or return NULL - // on failure - static Instrument * instantiate( const QString & _plugin_name, - InstrumentTrack * _instrument_track ); + //! instantiate instrument-plugin with given name or return NULL + //! on failure + static Instrument * instantiate(const QString & _plugin_name, + InstrumentTrack * _instrument_track, + const Plugin::Descriptor::SubPluginFeatures::Key* key, + bool keyFromDnd = false); virtual bool isFromTrack( const Track * _track ) const; diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index fb12e825a..dd78b2f9a 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -36,6 +36,7 @@ #include "Piano.h" #include "PianoView.h" #include "Pitch.h" +#include "Plugin.h" #include "Track.h" @@ -146,7 +147,9 @@ public: // load instrument whose name matches given one - Instrument * loadInstrument( const QString & _instrument_name ); + Instrument * loadInstrument(const QString & _instrument_name, + const Plugin::Descriptor::SubPluginFeatures::Key* key = nullptr, + bool keyFromDnd = false); AudioPort * audioPort() { diff --git a/include/Ladspa2LMMS.h b/include/Ladspa2LMMS.h index 14899487c..28fa25b89 100644 --- a/include/Ladspa2LMMS.h +++ b/include/Ladspa2LMMS.h @@ -30,6 +30,8 @@ #include "LadspaManager.h" +//! Class responsible for sorting found plugins (by LadspaManager) +//! into categories class LMMS_EXPORT Ladspa2LMMS : public LadspaManager { public: diff --git a/include/Plugin.h b/include/Plugin.h index a2cc7d696..034d8a06c 100644 --- a/include/Plugin.h +++ b/include/Plugin.h @@ -40,7 +40,27 @@ class PixmapLoader; class PluginView; class AutomatableModel; +/** + Abstract representation of a plugin + Such a plugin can be an Instrument, Effect, Tool plugin etc. + + Plugins have descriptors, containing meta info, which is used especially + by PluginFactory and friends. + + There are also Plugin keys (class Key, confusingly under + SubPluginFeatures), which contain pointers to the plugin descriptor. + + Some plugins have sub plugins, e.g. there is one CALF Plugin and for + each CALF effect, there is a CALF sub plugin. For those plugins, there + are keys for each sub plugin. These keys also link to the superior + Plugin::Descriptor. Additionally, they contain attributes that help the + superior Plugin saving them and recognizing them when loading. + + In case of sub plugins, the Descriptor has SubPluginFeatures. Those + are a bit like values to the sub plugins' keys (in terms of a key-value- + map). +*/ class LMMS_EXPORT Plugin : public Model, public JournallingObject { MM_OPERATORS @@ -59,9 +79,9 @@ public: Undefined = 255 } ; - // descriptor holds information about a plugin - every external plugin - // has to instantiate such a descriptor in an extern "C"-section so that - // the plugin-loader is able to access information about the plugin + //! Descriptor holds information about a plugin - every external plugin + //! has to instantiate such a Descriptor in an extern "C"-section so that + //! the plugin-loader is able to access information about the plugin struct Descriptor { const char * name; @@ -71,23 +91,49 @@ public: int version; PluginTypes type; const PixmapLoader * logo; - const char * supportedFileTypes; + const char * supportedFileTypes; //!< csv list of extensions inline bool supportsFileType( const QString& extension ) const { return QString( supportedFileTypes ).split( QChar( ',' ) ).contains( extension ); } + /** + Access to non-key-data of a sub plugin + + If you consider sub plugin keys as keys in a + key-value-map, this is the lookup for the corresponding + values. In order to have flexibility between different + plugin APIs, this is rather an array of fixed data, + but a bunch of virtual functions taking the key and + returning some values (or modifying objects of other + classes). + */ class LMMS_EXPORT SubPluginFeatures { public: + /** + Key reference a Plugin::Descriptor, and, + if the plugin has sub plugins, also reference + its sub plugin (using the attributes). + When keys are saved, those attributes are + written to XML in order to find the right sub + plugin when realoading. + + @note Any data that is not required to reference + the right Plugin or sub plugin should + not be here (but rather in + SubPluginFeatures, which are like values + in a key-value map). + */ struct Key { typedef QMap AttributeMap; inline Key( const Plugin::Descriptor * desc = NULL, - const QString & name = QString(), - const AttributeMap & am = AttributeMap() ) + const QString & name = QString(), + const AttributeMap & am = AttributeMap() + ) : desc( desc ), name( name ), @@ -101,12 +147,28 @@ public: inline bool isValid() const { - return desc != NULL && name.isNull() == false; + return desc != nullptr; } + //! Key to subplugin: reference to parent descriptor + //! Key to plugin: reference to its descriptor const Plugin::Descriptor* desc; + //! Descriptive name like "Calf Phaser". + //! Not required for key lookup and not saved + //! only used sometimes to temporary store descriptive names + //! @todo This is a bug, there should be a function + //! in SubPluginFeatures (to get the name) instead QString name; + //! Attributes that make up the key and identify + //! the sub plugin. They are being loaded and saved AttributeMap attributes; + + // helper functions to retrieve data that is + // not part of the key, but mapped via desc->subPluginFeatures + const char* additionalFileExtensions() const; + const char* displayName() const; + const char* description() const; + const PixmapLoader* logo() const; } ; typedef QList KeyList; @@ -125,11 +187,42 @@ public: { } + //! While PluginFactory only collects the plugins, + //! this function is used by widgets like EffectSelectDialog + //! to find all possible sub plugins virtual void listSubPluginKeys( const Plugin::Descriptor *, KeyList & ) const { } + private: + // You can add stuff values mapped by "Key" below + // The defaults are sane, i.e. redirect to sub plugins + // supererior descriptor + + virtual const char* additionalFileExtensions(const Key&) const + { + return nullptr; + } + + virtual const char* displayName(const Key& k) const + { + return k.isValid() + ? k.desc->displayName + : k.name.toUtf8().data(); + } + + virtual const char* description(const Key& k) const + { + return k.isValid() ? k.desc->description : ""; + } + + virtual const PixmapLoader* logo(const Key& k) const + { + Q_ASSERT(k.desc); + return k.desc->logo; + } + protected: const Plugin::PluginTypes m_type; } ; @@ -140,48 +233,66 @@ public: // typedef a list so we can easily work with list of plugin descriptors typedef QList DescriptorList; - // contructor of a plugin - Plugin( const Descriptor * descriptor, Model * parent ); + //! Constructor of a plugin + //! @param key Sub plugins must pass a key here, optional otherwise. + //! See the key() function + Plugin(const Descriptor * descriptor, Model * parent, + const Descriptor::SubPluginFeatures::Key *key = nullptr); virtual ~Plugin(); - // returns display-name out of descriptor - virtual QString displayName() const - { - return Model::displayName().isEmpty() - ? m_descriptor->displayName - : Model::displayName(); - } + //! Return display-name out of sub plugin or descriptor + virtual QString displayName() const; - // return plugin-type + //! Return logo out of sub plugin or descriptor + const PixmapLoader *logo() const; + + //! Return plugin type inline PluginTypes type( void ) const { return m_descriptor->type; } - // return plugin-descriptor for further information + //! Return plugin Descriptor inline const Descriptor * descriptor() const { return m_descriptor; } - // can be called if a file matching supportedFileTypes should be - // loaded/processed with the help of this plugin + //! Return the key referencing this plugin. If the Plugin has no + //! sub plugin features, the key is pretty useless. If it has, + //! this key will also contain the sub plugin attributes, and will be + //! a key to those SubPluginFeatures. + inline const Descriptor::SubPluginFeatures::Key & key() const + { + return m_key; + } + + //! Can be called if a file matching supportedFileTypes should be + //! loaded/processed with the help of this plugin virtual void loadFile( const QString & file ); - // Called if external source needs to change something but we cannot - // reference the class header. Should return null if not key not found. + //! Called if external source needs to change something but we cannot + //! reference the class header. Should return null if not key not found. virtual AutomatableModel* childModel( const QString & modelName ); - // returns an instance of a plugin whose name matches to given one - // if specified plugin couldn't be loaded, it creates a dummy-plugin - static Plugin * instantiate( const QString& pluginName, Model * parent, void * data ); + //! Overload if the argument passed to the plugin is a subPluginKey + //! If you can not pass the key and are aware that it's stored in + //! Engine::pickDndPluginKey(), use this function, too + static Plugin * instantiateWithKey(const QString& pluginName, Model * parent, + const Descriptor::SubPluginFeatures::Key *key, + bool keyFromDnd = false); - // create a view for the model + //! Return an instance of a plugin whose name matches to given one + //! if specified plugin couldn't be loaded, it creates a dummy-plugin + //! @param data Anything the plugin expects. If this is a pointer to a sub plugin key, + //! use instantiateWithKey instead + static Plugin * instantiate(const QString& pluginName, Model * parent, void *data); + + //! Create a view for the model PluginView * createView( QWidget * parent ); - protected: - // create a view for the model + //! Create a view for the model virtual PluginView* instantiateView( QWidget * ) = 0; void collectErrorForUI( QString errMsg ); @@ -189,6 +300,8 @@ protected: private: const Descriptor * m_descriptor; + Descriptor::SubPluginFeatures::Key m_key; + // pointer to instantiation-function in plugin typedef Plugin * ( * InstantiationHook )( Model * , void * ); diff --git a/include/PluginBrowser.h b/include/PluginBrowser.h index 75c7cd291..f7c46db72 100644 --- a/include/PluginBrowser.h +++ b/include/PluginBrowser.h @@ -60,7 +60,8 @@ class PluginDescWidget : public QWidget { Q_OBJECT public: - PluginDescWidget( const Plugin::Descriptor & _pd, QWidget * _parent ); + typedef Plugin::Descriptor::SubPluginFeatures::Key PluginKey; + PluginDescWidget( const PluginKey & _pk, QWidget * _parent ); protected: @@ -72,7 +73,7 @@ protected: private: constexpr static int DEFAULT_HEIGHT{24}; - const Plugin::Descriptor & m_pluginDescriptor; + PluginKey m_pluginKey; QPixmap m_logo; bool m_mouseOver; diff --git a/include/PluginFactory.h b/include/PluginFactory.h index 56d32c4e4..17b178108 100644 --- a/include/PluginFactory.h +++ b/include/PluginFactory.h @@ -26,10 +26,13 @@ #define PLUGINFACTORY_H #include +#include #include #include #include +#include +#include #include "lmms_export.h" #include "Plugin.h" @@ -41,12 +44,10 @@ class LMMS_EXPORT PluginFactory public: struct PluginInfo { - PluginInfo() : library(nullptr), descriptor(nullptr) {} - const QString name() const; QFileInfo file; - std::shared_ptr library; - Plugin::Descriptor* descriptor; + std::shared_ptr library = nullptr; + Plugin::Descriptor* descriptor = nullptr; bool isNull() const {return ! library;} }; @@ -56,6 +57,8 @@ public: PluginFactory(); ~PluginFactory(); + static void setupSearchPaths(); + /// Returns the singleton instance of PluginFactory. You won't need to call /// this directly, use pluginFactory instead. static PluginFactory* instance(); @@ -64,10 +67,17 @@ public: const Plugin::DescriptorList descriptors() const; const Plugin::DescriptorList descriptors(Plugin::PluginTypes type) const; + struct PluginInfoAndKey + { + PluginInfo info; + Plugin::Descriptor::SubPluginFeatures::Key key; + bool isNull() const { return info.isNull(); } + }; + /// Returns a list of all found plugins' PluginFactory::PluginInfo objects. const PluginInfoList& pluginInfos() const; /// Returns a plugin that support the given file extension - const PluginInfo pluginSupportingExtension(const QString& ext); + const PluginInfoAndKey pluginSupportingExtension(const QString& ext); /// Returns the PluginInfo object of the plugin with the given name. /// If the plugin is not found, an empty PluginInfo is returned (use @@ -84,7 +94,9 @@ public slots: private: DescriptorMap m_descriptors; PluginInfoList m_pluginInfos; - QMap m_pluginByExt; + + QMap m_pluginByExt; + QVector m_garbage; //!< cleaned up at destruction QHash m_errors; diff --git a/plugins/FreeBoy/FreeBoy.cpp b/plugins/FreeBoy/FreeBoy.cpp index dd05444a6..7e5252344 100644 --- a/plugins/FreeBoy/FreeBoy.cpp +++ b/plugins/FreeBoy/FreeBoy.cpp @@ -728,10 +728,10 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) { return( new FreeBoyInstrument( - static_cast( _data ) ) ); + static_cast( m ) ) ); } diff --git a/plugins/GigPlayer/GigPlayer.cpp b/plugins/GigPlayer/GigPlayer.cpp index bf5990252..200439dae 100644 --- a/plugins/GigPlayer/GigPlayer.cpp +++ b/plugins/GigPlayer/GigPlayer.cpp @@ -1390,9 +1390,9 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) { - return new GigInstrument( static_cast( _data ) ); + return new GigInstrument( static_cast( m ) ); } } diff --git a/plugins/LadspaEffect/LadspaSubPluginFeatures.cpp b/plugins/LadspaEffect/LadspaSubPluginFeatures.cpp index e9344e943..1b055fe73 100644 --- a/plugins/LadspaEffect/LadspaSubPluginFeatures.cpp +++ b/plugins/LadspaEffect/LadspaSubPluginFeatures.cpp @@ -44,6 +44,16 @@ LadspaSubPluginFeatures::LadspaSubPluginFeatures( Plugin::PluginTypes _type ) : +const char *LadspaSubPluginFeatures::displayName(const Plugin::Descriptor::SubPluginFeatures::Key &k) const +{ + const ladspa_key_t & lkey = subPluginKeyToLadspaKey(&k); + Ladspa2LMMS * lm = Engine::getLADSPAManager(); + return lm->getName(lkey).toUtf8().data(); +} + + + + void LadspaSubPluginFeatures::fillDescriptionWidget( QWidget * _parent, const Key * _key ) const { diff --git a/plugins/LadspaEffect/LadspaSubPluginFeatures.h b/plugins/LadspaEffect/LadspaSubPluginFeatures.h index 904c8133b..b7613827b 100644 --- a/plugins/LadspaEffect/LadspaSubPluginFeatures.h +++ b/plugins/LadspaEffect/LadspaSubPluginFeatures.h @@ -25,8 +25,8 @@ * */ -#ifndef _LADSPA_SUBPLUGIN_FEATURES_H -#define _LADSPA_SUBPLUGIN_FEATURES_H +#ifndef LADSPA_SUBPLUGIN_FEATURES_H +#define LADSPA_SUBPLUGIN_FEATURES_H #include "LadspaManager.h" #include "Plugin.h" @@ -37,11 +37,13 @@ class LadspaSubPluginFeatures : public Plugin::Descriptor::SubPluginFeatures public: LadspaSubPluginFeatures( Plugin::PluginTypes _type ); - virtual void fillDescriptionWidget( QWidget * _parent, - const Key * _key ) const; + const char* displayName(const Key& k) const override; + void fillDescriptionWidget( QWidget * _parent, + const Key * _key ) const override; virtual void listSubPluginKeys( const Plugin::Descriptor * _desc, - KeyList & _kl ) const; + KeyList & _kl ) const override; + static ladspa_key_t subPluginKeyToLadspaKey( const Key * _key ); diff --git a/plugins/OpulenZ/OpulenZ.cpp b/plugins/OpulenZ/OpulenZ.cpp index d8d5f3e26..8e5b7f098 100644 --- a/plugins/OpulenZ/OpulenZ.cpp +++ b/plugins/OpulenZ/OpulenZ.cpp @@ -79,9 +79,9 @@ Plugin::Descriptor PLUGIN_EXPORT opulenz_plugin_descriptor = }; // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) { - return( new OpulenzInstrument( static_cast( _data ) ) ); + return( new OpulenzInstrument( static_cast( m ) ) ); } } diff --git a/plugins/Xpressive/Xpressive.cpp b/plugins/Xpressive/Xpressive.cpp index cb0293710..f0154f75b 100644 --- a/plugins/Xpressive/Xpressive.cpp +++ b/plugins/Xpressive/Xpressive.cpp @@ -877,8 +877,8 @@ void XpressiveView::helpClicked() { extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main(Model *, void * _data) { - return (new Xpressive(static_cast(_data))); +PLUGIN_EXPORT Plugin * lmms_plugin_main(Model *m, void *) { + return (new Xpressive(static_cast(m))); } } diff --git a/plugins/audio_file_processor/audio_file_processor.cpp b/plugins/audio_file_processor/audio_file_processor.cpp index 6c080f7c9..ce14e1ac2 100644 --- a/plugins/audio_file_processor/audio_file_processor.cpp +++ b/plugins/audio_file_processor/audio_file_processor.cpp @@ -1277,10 +1277,9 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main(Model * model, void *) { - return new audioFileProcessor( - static_cast( _data ) ); + return new audioFileProcessor(static_cast(model)); } diff --git a/plugins/bit_invader/bit_invader.cpp b/plugins/bit_invader/bit_invader.cpp index ecc77be0b..c370c409c 100644 --- a/plugins/bit_invader/bit_invader.cpp +++ b/plugins/bit_invader/bit_invader.cpp @@ -584,9 +584,9 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) { - return( new bitInvader( static_cast( _data ) ) ); + return( new bitInvader( static_cast( m ) ) ); } diff --git a/plugins/carlapatchbay/carlapatchbay.cpp b/plugins/carlapatchbay/carlapatchbay.cpp index 69c71ce68..60e022156 100644 --- a/plugins/carlapatchbay/carlapatchbay.cpp +++ b/plugins/carlapatchbay/carlapatchbay.cpp @@ -43,9 +43,9 @@ Plugin::Descriptor PLUGIN_EXPORT carlapatchbay_plugin_descriptor = NULL } ; -PLUGIN_EXPORT Plugin* lmms_plugin_main(Model*, void* data) +PLUGIN_EXPORT Plugin* lmms_plugin_main(Model* m, void*) { - return new CarlaInstrument(static_cast(data), &carlapatchbay_plugin_descriptor, true); + return new CarlaInstrument(static_cast(m), &carlapatchbay_plugin_descriptor, true); } } diff --git a/plugins/carlarack/carlarack.cpp b/plugins/carlarack/carlarack.cpp index 8bc7d372d..d057eff83 100644 --- a/plugins/carlarack/carlarack.cpp +++ b/plugins/carlarack/carlarack.cpp @@ -43,9 +43,9 @@ Plugin::Descriptor PLUGIN_EXPORT carlarack_plugin_descriptor = NULL } ; -PLUGIN_EXPORT Plugin* lmms_plugin_main(Model*, void* data) +PLUGIN_EXPORT Plugin* lmms_plugin_main(Model* m, void*) { - return new CarlaInstrument(static_cast(data), &carlarack_plugin_descriptor, false); + return new CarlaInstrument(static_cast(m), &carlarack_plugin_descriptor, false); } } diff --git a/plugins/kicker/kicker.cpp b/plugins/kicker/kicker.cpp index 2087cf880..d204babab 100644 --- a/plugins/kicker/kicker.cpp +++ b/plugins/kicker/kicker.cpp @@ -367,9 +367,9 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model * m, void * ) { - return new kickerInstrument( static_cast( _data ) ); + return new kickerInstrument( static_cast( m ) ); } diff --git a/plugins/lb302/lb302.cpp b/plugins/lb302/lb302.cpp index d32f14e88..e556e42bf 100644 --- a/plugins/lb302/lb302.cpp +++ b/plugins/lb302/lb302.cpp @@ -1029,11 +1029,11 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model * m, void * ) { return( new lb302Synth( - static_cast( _data ) ) ); + static_cast( m ) ) ); } diff --git a/plugins/monstro/Monstro.cpp b/plugins/monstro/Monstro.cpp index baee242bb..fb089aa0c 100644 --- a/plugins/monstro/Monstro.cpp +++ b/plugins/monstro/Monstro.cpp @@ -1828,9 +1828,9 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) { - return new MonstroInstrument( static_cast( _data ) ); + return new MonstroInstrument( static_cast( m ) ); } diff --git a/plugins/nes/Nes.cpp b/plugins/nes/Nes.cpp index 5b34dcb1f..ba64edb06 100644 --- a/plugins/nes/Nes.cpp +++ b/plugins/nes/Nes.cpp @@ -918,9 +918,9 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * _data ) { - return( new NesInstrument( static_cast( _data ) ) ); + return( new NesInstrument( static_cast( m ) ) ); } diff --git a/plugins/organic/organic.cpp b/plugins/organic/organic.cpp index b6d45c8d3..63aee0dc6 100644 --- a/plugins/organic/organic.cpp +++ b/plugins/organic/organic.cpp @@ -636,9 +636,9 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) { - return( new organicInstrument( static_cast( _data ) ) ); + return( new organicInstrument( static_cast( m ) ) ); } diff --git a/plugins/patman/patman.cpp b/plugins/patman/patman.cpp index 6ab7adce7..0ea9968da 100644 --- a/plugins/patman/patman.cpp +++ b/plugins/patman/patman.cpp @@ -66,9 +66,9 @@ Plugin::Descriptor PLUGIN_EXPORT patman_plugin_descriptor = // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) { - return new patmanInstrument( static_cast( _data ) ); + return new patmanInstrument( static_cast( m ) ); } } diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index 4bf75777c..138e8165d 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -1150,9 +1150,9 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) { - return new sf2Instrument( static_cast( _data ) ); + return new sf2Instrument( static_cast( m ) ); } diff --git a/plugins/sfxr/sfxr.cpp b/plugins/sfxr/sfxr.cpp index c99f46f88..2718d66d7 100644 --- a/plugins/sfxr/sfxr.cpp +++ b/plugins/sfxr/sfxr.cpp @@ -1122,9 +1122,9 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model*, void* data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model* m, void* ) { - return new sfxrInstrument( static_cast( data ) ); + return new sfxrInstrument( static_cast( m ) ); } diff --git a/plugins/sid/sid_instrument.cpp b/plugins/sid/sid_instrument.cpp index 2eb46be56..024e9ae61 100644 --- a/plugins/sid/sid_instrument.cpp +++ b/plugins/sid/sid_instrument.cpp @@ -792,10 +792,9 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) { - return( new sidInstrument( - static_cast( _data ) ) ); + return( new sidInstrument( static_cast( m ) ) ); } diff --git a/plugins/stk/mallets/mallets.cpp b/plugins/stk/mallets/mallets.cpp index 7111bcdaa..ee1e1fbc3 100644 --- a/plugins/stk/mallets/mallets.cpp +++ b/plugins/stk/mallets/mallets.cpp @@ -756,9 +756,9 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model * m, void * ) { - return new malletsInstrument( static_cast( _data ) ); + return new malletsInstrument( static_cast( m ) ); } diff --git a/plugins/triple_oscillator/TripleOscillator.cpp b/plugins/triple_oscillator/TripleOscillator.cpp index 6b644fd46..a883f75fa 100644 --- a/plugins/triple_oscillator/TripleOscillator.cpp +++ b/plugins/triple_oscillator/TripleOscillator.cpp @@ -723,9 +723,9 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model* model, void * ) { - return new TripleOscillator( static_cast( _data ) ); + return new TripleOscillator( static_cast( model ) ); } } diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index 73ea33a51..fe91358b3 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -1167,9 +1167,9 @@ extern "C" { // necessary for getting instance out of shared lib -Q_DECL_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +Q_DECL_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) { - return new vestigeInstrument( static_cast( _data ) ); + return new vestigeInstrument( static_cast( m ) ); } diff --git a/plugins/vibed/vibed.cpp b/plugins/vibed/vibed.cpp index f33a90428..bde5c8917 100644 --- a/plugins/vibed/vibed.cpp +++ b/plugins/vibed/vibed.cpp @@ -682,9 +682,9 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) { - return( new vibed( static_cast( _data ) ) ); + return( new vibed( static_cast( m ) ) ); } diff --git a/plugins/watsyn/Watsyn.cpp b/plugins/watsyn/Watsyn.cpp index 0122b293a..2787e39b7 100644 --- a/plugins/watsyn/Watsyn.cpp +++ b/plugins/watsyn/Watsyn.cpp @@ -1279,9 +1279,9 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) { - return( new WatsynInstrument( static_cast( _data ) ) ); + return( new WatsynInstrument( static_cast( m ) ) ); } diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index ad8d9a78c..8235ad147 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -652,10 +652,9 @@ extern "C" { // necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data ) +PLUGIN_EXPORT Plugin * lmms_plugin_main(Model * m, void *) { - - return new ZynAddSubFxInstrument( static_cast( _data ) ); + return new ZynAddSubFxInstrument(static_cast(m)); } diff --git a/src/core/Effect.cpp b/src/core/Effect.cpp index 8cdcc9c60..c84297753 100644 --- a/src/core/Effect.cpp +++ b/src/core/Effect.cpp @@ -36,9 +36,8 @@ Effect::Effect( const Plugin::Descriptor * _desc, Model * _parent, const Descriptor::SubPluginFeatures::Key * _key ) : - Plugin( _desc, _parent ), + Plugin( _desc, _parent, _key ), m_parent( NULL ), - m_key( _key ? *_key : Descriptor::SubPluginFeatures::Key() ), m_processors( 1 ), m_okay( true ), m_noRun( false ), @@ -117,7 +116,7 @@ Effect * Effect::instantiate( const QString& pluginName, Model * _parent, Descriptor::SubPluginFeatures::Key * _key ) { - Plugin * p = Plugin::instantiate( pluginName, _parent, _key ); + Plugin * p = Plugin::instantiateWithKey( pluginName, _parent, _key ); // check whether instantiated plugin is an effect if( dynamic_cast( p ) != NULL ) { diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp index a53abbe5d..7f89c20f3 100644 --- a/src/core/Engine.cpp +++ b/src/core/Engine.cpp @@ -41,6 +41,7 @@ BBTrackContainer * LmmsCore::s_bbTrackContainer = NULL; Song * LmmsCore::s_song = NULL; ProjectJournal * LmmsCore::s_projectJournal = NULL; Ladspa2LMMS * LmmsCore::s_ladspaManager = NULL; +void* LmmsCore::s_dndPluginKey = nullptr; DummyTrackContainer * LmmsCore::s_dummyTC = NULL; @@ -112,4 +113,24 @@ void LmmsCore::updateFramesPerTick() DefaultTicksPerTact / s_song->getTempo(); } + + + +void LmmsCore::setDndPluginKey(void *newKey) +{ + assert(static_cast(newKey)); + s_dndPluginKey = newKey; +} + + + + +void *LmmsCore::pickDndPluginKey() +{ + return s_dndPluginKey; +} + + + + LmmsCore * LmmsCore::s_instanceOfMe = NULL; diff --git a/src/core/Instrument.cpp b/src/core/Instrument.cpp index 534bb783a..ba608da14 100644 --- a/src/core/Instrument.cpp +++ b/src/core/Instrument.cpp @@ -27,9 +27,10 @@ #include "DummyInstrument.h" -Instrument::Instrument( InstrumentTrack * _instrument_track, - const Descriptor * _descriptor ) : - Plugin( _descriptor, NULL/* _instrument_track*/ ), +Instrument::Instrument(InstrumentTrack * _instrument_track, + const Descriptor * _descriptor, + const Descriptor::SubPluginFeatures::Key *key) : + Plugin(_descriptor, NULL/* _instrument_track*/, key), m_instrumentTrack( _instrument_track ) { } @@ -56,19 +57,15 @@ f_cnt_t Instrument::beatLen( NotePlayHandle * ) const -Instrument * Instrument::instantiate( const QString & _plugin_name, - InstrumentTrack * _instrument_track ) +Instrument *Instrument::instantiate(const QString &_plugin_name, + InstrumentTrack *_instrument_track, const Descriptor::SubPluginFeatures::Key *key, bool keyFromDnd) { - Plugin * p = Plugin::instantiate( _plugin_name, _instrument_track, - _instrument_track ); - // check whether instantiated plugin is an instrument - if( dynamic_cast( p ) != NULL ) - { - // everything ok, so return pointer - return dynamic_cast( p ); - } - - // not quite... so delete plugin and return dummy instrument + if(keyFromDnd) + Q_ASSERT(!key); + // copy from above // TODO! common cleaner func + Plugin * p = Plugin::instantiateWithKey(_plugin_name, _instrument_track, key, keyFromDnd); + if(dynamic_cast(p)) + return dynamic_cast(p); delete p; return( new DummyInstrument( _instrument_track ) ); } diff --git a/src/core/LadspaManager.cpp b/src/core/LadspaManager.cpp index 4336e50a5..febbe5a91 100644 --- a/src/core/LadspaManager.cpp +++ b/src/core/LadspaManager.cpp @@ -40,7 +40,7 @@ LadspaManager::LadspaManager() { // Make sure plugin search paths are set up - PluginFactory::instance(); + PluginFactory::setupSearchPaths(); QStringList ladspaDirectories = QString( getenv( "LADSPA_PATH" ) ). split( LADSPA_PATH_SEPERATOR ); diff --git a/src/core/Plugin.cpp b/src/core/Plugin.cpp index b479d7d8d..e7f80b5ab 100644 --- a/src/core/Plugin.cpp +++ b/src/core/Plugin.cpp @@ -22,11 +22,15 @@ * */ +#include #include #include #include #include +// comment separator to prevent clang's header sorting +#include "lmmsconfig.h" + #include "Plugin.h" #include "embed.h" #include "Engine.h" @@ -53,10 +57,12 @@ static Plugin::Descriptor dummyPluginDescriptor = -Plugin::Plugin( const Descriptor * descriptor, Model * parent ) : - Model( parent ), +Plugin::Plugin(const Descriptor * descriptor, Model * parent, const + Descriptor::SubPluginFeatures::Key* key) : + Model(parent), JournallingObject(), - m_descriptor( descriptor ) + m_descriptor(descriptor), + m_key(key ? *key : Descriptor::SubPluginFeatures::Key(m_descriptor)) { if( m_descriptor == NULL ) { @@ -74,6 +80,87 @@ Plugin::~Plugin() +template +T use_this_or(T this_param, T or_param) +{ + return this_param ? this_param : or_param; +} + + + + +QString Plugin::displayName() const +{ + return Model::displayName().isEmpty() // currently always empty + ? (m_descriptor->subPluginFeatures && m_key.isValid()) + // get from sub plugin + ? m_key.displayName() + // get from plugin + : m_descriptor->displayName + : Model::displayName(); +} + + + + +const PixmapLoader* Plugin::logo() const +{ + return (m_descriptor->subPluginFeatures && m_key.isValid()) + ? m_key.logo() + : m_descriptor->logo; +} + + + + +const char *Plugin::Descriptor::SubPluginFeatures::Key::additionalFileExtensions() const +{ + Q_ASSERT(isValid()); + return desc->subPluginFeatures + // get from sub plugin + ? desc->subPluginFeatures->additionalFileExtensions(*this) + // get from plugin + : nullptr; +} + + + + +const char* Plugin::Descriptor::SubPluginFeatures::Key::displayName() const +{ + Q_ASSERT(isValid()); + return desc->subPluginFeatures + // get from sub plugin + ? use_this_or(desc->subPluginFeatures->displayName(*this), desc->displayName) + // get from plugin + : desc->displayName; +} + + + + +const PixmapLoader* Plugin::Descriptor::SubPluginFeatures::Key::logo() const +{ + Q_ASSERT(isValid()); + return desc->subPluginFeatures + ? use_this_or(desc->subPluginFeatures->logo(*this), desc->logo) + : desc->logo; +} + + + + +const char *Plugin::Descriptor::SubPluginFeatures::Key::description() const +{ + Q_ASSERT(isValid()); + return desc->subPluginFeatures + ? use_this_or(desc->subPluginFeatures->description(*this), desc->description) + : desc->description; +} + + + + void Plugin::loadFile( const QString & ) { } @@ -90,10 +177,37 @@ AutomatableModel * Plugin::childModel( const QString & ) #include "PluginFactory.h" -Plugin * Plugin::instantiate( const QString& pluginName, Model * parent, - void * data ) +Plugin * Plugin::instantiateWithKey(const QString& pluginName, Model * parent, + const Descriptor::SubPluginFeatures::Key *key, + bool keyFromDnd) +{ + if(keyFromDnd) + Q_ASSERT(!key); + const Descriptor::SubPluginFeatures::Key *keyPtr = keyFromDnd + ? static_cast(Engine::pickDndPluginKey()) + : key; + const PluginFactory::PluginInfo& pi = pluginFactory->pluginInfo(pluginName.toUtf8()); + if(keyPtr) + { + // descriptor is not yet set when loading - set it now + Descriptor::SubPluginFeatures::Key keyCopy = *keyPtr; + keyCopy.desc = pi.descriptor; + return Plugin::instantiate(pluginName, parent, &keyCopy); + } + else + return Plugin::instantiate(pluginName, parent, + // the keys are never touched anywhere + const_cast(keyPtr)); +} + + + + +Plugin * Plugin::instantiate(const QString& pluginName, Model * parent, + void *data) { const PluginFactory::PluginInfo& pi = pluginFactory->pluginInfo(pluginName.toUtf8()); + if( pi.isNull() ) { if( gui ) @@ -106,9 +220,15 @@ Plugin * Plugin::instantiate( const QString& pluginName, Model * parent, } return new DummyPlugin(); } + qDebug() << "Using PluginInfo for " << pluginName; - InstantiationHook instantiationHook = ( InstantiationHook ) pi.library->resolve( "lmms_plugin_main" ); - if( instantiationHook == NULL ) + Plugin* inst; + InstantiationHook instantiationHook; + if ((instantiationHook = ( InstantiationHook ) pi.library->resolve( "lmms_plugin_main" ))) + { + inst = instantiationHook(parent, data); + } + else { if( gui ) { @@ -120,7 +240,7 @@ Plugin * Plugin::instantiate( const QString& pluginName, Model * parent, return new DummyPlugin(); } - Plugin * inst = instantiationHook( parent, data ); + return inst; } @@ -181,4 +301,3 @@ QDomElement Plugin::Descriptor::SubPluginFeatures::Key::saveXML( } - diff --git a/src/core/PluginFactory.cpp b/src/core/PluginFactory.cpp index a87e49270..a25dca54a 100644 --- a/src/core/PluginFactory.cpp +++ b/src/core/PluginFactory.cpp @@ -28,8 +28,11 @@ #include #include #include +#include "lmmsconfig.h" #include "ConfigManager.h" +#include "Plugin.h" +#include "embed.h" #ifdef LMMS_BUILD_WIN32 QStringList nameFilters("*.dll"); @@ -45,6 +48,16 @@ qint64 qHash(const QFileInfo& fi) std::unique_ptr PluginFactory::s_instance; PluginFactory::PluginFactory() +{ + setupSearchPaths(); + discoverPlugins(); +} + +PluginFactory::~PluginFactory() +{ +} + +void PluginFactory::setupSearchPaths() { // Adds a search path relative to the main executable if the path exists. auto addRelativeIfExists = [](const QString & path) { @@ -76,12 +89,6 @@ PluginFactory::PluginFactory() QDir::addSearchPath("plugins", env_path); QDir::addSearchPath("plugins", ConfigManager::inst()->workingDir() + "plugins"); - - discoverPlugins(); -} - -PluginFactory::~PluginFactory() -{ } PluginFactory* PluginFactory::instance() @@ -107,9 +114,9 @@ const PluginFactory::PluginInfoList& PluginFactory::pluginInfos() const return m_pluginInfos; } -const PluginFactory::PluginInfo PluginFactory::pluginSupportingExtension(const QString& ext) +const PluginFactory::PluginInfoAndKey PluginFactory::pluginSupportingExtension(const QString& ext) { - return m_pluginByExt.value(ext, PluginInfo()); + return m_pluginByExt.value(ext, PluginInfoAndKey()); } const PluginFactory::PluginInfo PluginFactory::pluginInfo(const char* name) const @@ -150,42 +157,82 @@ void PluginFactory::discoverPlugins() for (const QFileInfo& file : files) { auto library = std::make_shared(file.absoluteFilePath()); - if (! library->load()) { m_errors[file.baseName()] = library->errorString(); qWarning("%s", library->errorString().toLocal8Bit().data()); continue; } - if (library->resolve("lmms_plugin_main") == nullptr) { - continue; - } - QString descriptorName = file.baseName() + "_plugin_descriptor"; - if( descriptorName.left(3) == "lib" ) + Plugin::Descriptor* pluginDescriptor = nullptr; + if (library->resolve("lmms_plugin_main")) { - descriptorName = descriptorName.mid(3); - } + QString descriptorName = file.baseName() + "_plugin_descriptor"; + if( descriptorName.left(3) == "lib" ) + { + descriptorName = descriptorName.mid(3); + } - Plugin::Descriptor* pluginDescriptor = reinterpret_cast(library->resolve(descriptorName.toUtf8().constData())); - if(pluginDescriptor == nullptr) + pluginDescriptor = reinterpret_cast(library->resolve(descriptorName.toUtf8().constData())); + if(pluginDescriptor == nullptr) + { + qWarning() << qApp->translate("PluginFactory", "LMMS plugin %1 does not have a plugin descriptor named %2!"). + arg(file.absoluteFilePath()).arg(descriptorName); + continue; + } + } + else { - qWarning() << qApp->translate("PluginFactory", "LMMS plugin %1 does not have a plugin descriptor named %2!"). - arg(file.absoluteFilePath()).arg(descriptorName); - continue; + qDebug() << "Ignoring" << file << "(no lmms_plugin_main())"; } - PluginInfo info; - info.file = file; - info.library = library; - info.descriptor = pluginDescriptor; - pluginInfos << info; - - for (const QString& ext : QString(info.descriptor->supportedFileTypes).split(',')) + if(pluginDescriptor) { - m_pluginByExt.insert(ext, info); - } + PluginInfo info; + info.file = file; + info.library = library; + info.descriptor = pluginDescriptor; + pluginInfos << info; - descriptors.insert(info.descriptor->type, info.descriptor); + qDebug() << "Add" << info.file << "with type" + << info.descriptor->type; + + auto addSupportedFileTypes = + [this](const char* supportedFileTypes, + const PluginInfo& info, + const Plugin::Descriptor::SubPluginFeatures::Key* key = nullptr) + { + if(supportedFileTypes) + for (const QString& ext : QString(supportedFileTypes).split(',')) + { + qDebug() << "Plugin " << info.name() << "supports" << ext; + PluginInfoAndKey infoAndKey; + infoAndKey.info = info; + infoAndKey.key = key + ? *key + : Plugin::Descriptor::SubPluginFeatures::Key(); + m_pluginByExt.insert(ext, infoAndKey); + } + }; + + if (info.descriptor->supportedFileTypes) + addSupportedFileTypes(info.descriptor->supportedFileTypes, info); + + if (info.descriptor->subPluginFeatures) + { + Plugin::Descriptor::SubPluginFeatures::KeyList + subPluginKeys; + info.descriptor->subPluginFeatures->listSubPluginKeys( + info.descriptor, + subPluginKeys); + for(const Plugin::Descriptor::SubPluginFeatures::Key& key + : subPluginKeys) + { + addSupportedFileTypes(key.additionalFileExtensions(), info, &key); + } + } + + descriptors.insert(info.descriptor->type, info.descriptor); + } } m_pluginInfos = pluginInfos; diff --git a/src/core/PresetPreviewPlayHandle.cpp b/src/core/PresetPreviewPlayHandle.cpp index dc36819b7..ca0e52194 100644 --- a/src/core/PresetPreviewPlayHandle.cpp +++ b/src/core/PresetPreviewPlayHandle.cpp @@ -137,8 +137,10 @@ PresetPreviewPlayHandle::PresetPreviewPlayHandle( const QString & _preset_file, suffix().toLower(); if( i == NULL || !i->descriptor()->supportsFileType( ext ) ) { + const PluginFactory::PluginInfoAndKey& infoAndKey = + pluginFactory->pluginSupportingExtension(ext); i = s_previewTC->previewInstrumentTrack()-> - loadInstrument(pluginFactory->pluginSupportingExtension(ext).name()); + loadInstrument(infoAndKey.info.name(), &infoAndKey.key); } if( i != NULL ) { diff --git a/src/gui/EffectSelectDialog.cpp b/src/gui/EffectSelectDialog.cpp index 64b180d48..4b59a19b1 100644 --- a/src/gui/EffectSelectDialog.cpp +++ b/src/gui/EffectSelectDialog.cpp @@ -53,11 +53,6 @@ EffectSelectDialog::EffectSelectDialog( QWidget * _parent ) : if( desc->subPluginFeatures ) { desc->subPluginFeatures->listSubPluginKeys( - // as iterators are always stated to be not - // equal with pointers, we dereference the - // iterator and take the address of the item, - // so we're on the safe side and the compiler - // likely will reduce that to just "it" desc, subPluginEffectKeys ); } @@ -79,14 +74,14 @@ EffectSelectDialog::EffectSelectDialog( QWidget * _parent ) : { QString name; QString type; - if( ( *it ).desc->subPluginFeatures ) + if( it->desc->subPluginFeatures ) { - name = ( *it ).name; - type = ( *it ).desc->displayName; + name = it->displayName(); + type = it->desc->displayName; } else { - name = ( *it ).desc->displayName; + name = it->desc->displayName; type = "LMMS"; } m_sourceModel.setItem( row, 0, new QStandardItem( name ) ); @@ -184,62 +179,63 @@ void EffectSelectDialog::rowChanged( const QModelIndex & _idx, { m_currentSelection = m_effectKeys[m_model.mapToSource( _idx ).row()]; } - if( m_currentSelection.desc ) + if( m_currentSelection.desc ) { m_descriptionWidget = new QWidget; - QHBoxLayout *hbox = new QHBoxLayout( m_descriptionWidget ); + QHBoxLayout *hbox = new QHBoxLayout( m_descriptionWidget ); - Plugin::Descriptor const & descriptor = *( m_currentSelection.desc ); + Plugin::Descriptor const & descriptor = *( m_currentSelection.desc ); - if ( descriptor.logo ) - { - QLabel *logoLabel = new QLabel( m_descriptionWidget ); - logoLabel->setPixmap( descriptor.logo->pixmap() ); - logoLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + const PixmapLoader* pixLoa = m_currentSelection.logo(); + if (pixLoa) + { + QLabel *logoLabel = new QLabel( m_descriptionWidget ); + logoLabel->setPixmap(pixLoa->pixmap()); + logoLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - hbox->addWidget( logoLabel ); - hbox->setAlignment( logoLabel, Qt::AlignTop); - } + hbox->addWidget( logoLabel ); + hbox->setAlignment( logoLabel, Qt::AlignTop); + } - QWidget *textualInfoWidget = new QWidget( m_descriptionWidget ); + QWidget *textualInfoWidget = new QWidget( m_descriptionWidget ); - hbox->addWidget(textualInfoWidget); + hbox->addWidget(textualInfoWidget); - QVBoxLayout * textWidgetLayout = new QVBoxLayout( textualInfoWidget); - textWidgetLayout->setMargin( 4 ); - textWidgetLayout->setSpacing( 0 ); + QVBoxLayout * textWidgetLayout = new QVBoxLayout( textualInfoWidget); + textWidgetLayout->setMargin( 4 ); + textWidgetLayout->setSpacing( 0 ); - if ( m_currentSelection.desc->subPluginFeatures ) - { - QWidget *subWidget = new QWidget(textualInfoWidget); - QVBoxLayout * subLayout = new QVBoxLayout( subWidget ); - subLayout->setMargin( 4 ); - subLayout->setSpacing( 0 ); - m_currentSelection.desc->subPluginFeatures-> - fillDescriptionWidget( subWidget, &m_currentSelection ); - for( QWidget * w : subWidget->findChildren() ) - { - if( w->parent() == subWidget ) - { - subLayout->addWidget( w ); - } - } + if ( m_currentSelection.desc->subPluginFeatures ) + { + QWidget *subWidget = new QWidget(textualInfoWidget); + QVBoxLayout * subLayout = new QVBoxLayout( subWidget ); + subLayout->setMargin( 4 ); + subLayout->setSpacing( 0 ); + m_currentSelection.desc->subPluginFeatures-> + fillDescriptionWidget( subWidget, &m_currentSelection ); + for( QWidget * w : subWidget->findChildren() ) + { + if( w->parent() == subWidget ) + { + subLayout->addWidget( w ); + } + } - textWidgetLayout->addWidget(subWidget); - } - else - { - QLabel *label = new QLabel(m_descriptionWidget); - QString labelText = "

" + tr("Name") + ": " + QString::fromUtf8(descriptor.displayName) + "

"; - labelText += "

" + tr("Description") + ": " + qApp->translate( "pluginBrowser", descriptor.description ) + "

"; - labelText += "

" + tr("Author") + ": " + QString::fromUtf8(descriptor.author) + "

"; + textWidgetLayout->addWidget(subWidget); + } + else + { + QLabel *label = new QLabel(m_descriptionWidget); + QString labelText = "

" + tr("Name") + ": " + QString::fromUtf8(descriptor.displayName) + "

"; + labelText += "

" + tr("Description") + ": " + qApp->translate( "pluginBrowser", descriptor.description ) + "

"; + labelText += "

" + tr("Author") + ": " + QString::fromUtf8(descriptor.author) + "

"; - label->setText(labelText); - textWidgetLayout->addWidget(label); - } + label->setText(labelText); + textWidgetLayout->addWidget(label); + } - ui->scrollArea->setWidget( m_descriptionWidget ); + ui->scrollArea->setWidget( m_descriptionWidget ); m_descriptionWidget->show(); } } diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 05727d332..4311e4e05 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -180,7 +180,7 @@ void FileBrowser::reloadTree( void ) void FileBrowser::expandItems( QTreeWidgetItem * item ) { - int numChildren = item ? item->childCount() : m_fileBrowserTreeWidget->topLevelItemCount(); + int numChildren = item ? item->childCount() : m_fileBrowserTreeWidget->topLevelItemCount(); for( int i = 0; i < numChildren; ++i ) { QTreeWidgetItem * it = item ? item->child( i ) : m_fileBrowserTreeWidget->topLevelItem(i); @@ -241,7 +241,7 @@ void FileBrowser::addItems(const QString & path ) Directory *dd = new Directory( cur_file, path, m_filter ); m_fileBrowserTreeWidget->insertTopLevelItem( i,dd ); - dd->update(); + dd->update(); // add files to the directory orphan = false; break; } @@ -406,7 +406,7 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) delete tf; } else if( ( f->extension ()== "xiz" || f->extension() == "sf2" || f->extension() == "sf3" || f->extension() == "gig" || f->extension() == "pat" ) && - ! pluginFactory->pluginSupportingExtension(f->extension()).isNull() ) + ! pluginFactory->pluginSupportingExtension(f->extension()).info.isNull() ) { m_previewPlayHandle = new PresetPreviewPlayHandle( f->fullName(), f->handling() == FileItem::LoadByPlugin ); } @@ -549,8 +549,9 @@ void FileBrowserTreeWidget::handleFile(FileItem * f, InstrumentTrack * it ) if( i == NULL || !i->descriptor()->supportsFileType( e ) ) { - i = it->loadInstrument( - pluginFactory->pluginSupportingExtension(e).name() ); + PluginFactory::PluginInfoAndKey piakn = + pluginFactory->pluginSupportingExtension(e); + i = it->loadInstrument(piakn.info.name(), &piakn.key); } i->loadFile( f->fullName() ); break; diff --git a/src/gui/InstrumentView.cpp b/src/gui/InstrumentView.cpp index 9e8fc58c1..93e153f6f 100644 --- a/src/gui/InstrumentView.cpp +++ b/src/gui/InstrumentView.cpp @@ -57,7 +57,7 @@ void InstrumentView::setModel( Model * _model, bool ) if( dynamic_cast( _model ) != NULL ) { ModelView::setModel( _model ); - instrumentTrackWindow()->setWindowIcon( model()->descriptor()->logo->pixmap() ); + instrumentTrackWindow()->setWindowIcon( model()->logo()->pixmap() ); connect( model(), SIGNAL( destroyed( QObject * ) ), this, SLOT( close() ) ); } } diff --git a/src/gui/PluginBrowser.cpp b/src/gui/PluginBrowser.cpp index dc0fc35e0..27747bc53 100644 --- a/src/gui/PluginBrowser.cpp +++ b/src/gui/PluginBrowser.cpp @@ -31,6 +31,7 @@ #include #include "embed.h" +#include "Engine.h" #include "templates.h" #include "gui_templates.h" #include "StringPairDrag.h" @@ -85,9 +86,30 @@ PluginDescList::PluginDescList(QWidget *parent) : return qstricmp( d1->displayName, d2->displayName ) < 0 ? true : false; } ); - for (const Plugin::Descriptor* desc : descs) + + typedef Plugin::Descriptor::SubPluginFeatures::KeyList PluginKeyList; + typedef Plugin::Descriptor::SubPluginFeatures::Key PluginKey; + PluginKeyList subPluginKeys, pluginKeys; + + for (const Plugin::Descriptor* desc: descs) { - PluginDescWidget* p = new PluginDescWidget( *desc, this ); + if( desc->subPluginFeatures ) + { + desc->subPluginFeatures->listSubPluginKeys( + desc, + subPluginKeys ); + } + else + { + pluginKeys << PluginKey( desc, desc->name ); + } + } + + pluginKeys += subPluginKeys; + + for (const PluginKey& key : pluginKeys) + { + PluginDescWidget* p = new PluginDescWidget( key, this ); p->show(); layout->addWidget(p); } @@ -99,23 +121,23 @@ PluginDescList::PluginDescList(QWidget *parent) : -PluginDescWidget::PluginDescWidget( const Plugin::Descriptor & _pd, +PluginDescWidget::PluginDescWidget(const PluginKey &_pk, QWidget * _parent ) : QWidget( _parent ), - m_pluginDescriptor( _pd ), - m_logo( _pd.logo->pixmap() ), + m_pluginKey( _pk ), + m_logo( _pk.logo()->pixmap() ), m_mouseOver( false ) { setFixedHeight( DEFAULT_HEIGHT ); setMouseTracking( true ); setCursor( Qt::PointingHandCursor ); - setToolTip(_pd.description); + setToolTip(_pk.description()); } -void PluginDescWidget::paintEvent( QPaintEvent * e ) +void PluginDescWidget::paintEvent( QPaintEvent * ) { QPainter p( this ); @@ -140,8 +162,7 @@ void PluginDescWidget::paintEvent( QPaintEvent * e ) } p.setFont( f ); - p.drawText( 10 + logo_size.width(), 15, - m_pluginDescriptor.displayName ); + p.drawText( 10 + logo_size.width(), 15, m_pluginKey.displayName()); } @@ -171,8 +192,9 @@ void PluginDescWidget::mousePressEvent( QMouseEvent * _me ) { if( _me->button() == Qt::LeftButton ) { - new StringPairDrag( "instrument", m_pluginDescriptor.name, - m_logo, this ); + Engine::setDndPluginKey(&m_pluginKey); + new StringPairDrag("instrument", + QString::fromUtf8(m_pluginKey.desc->name), m_logo, this); leaveEvent( _me ); } } diff --git a/src/gui/TrackContainerView.cpp b/src/gui/TrackContainerView.cpp index 2772ef104..7c69d5eb8 100644 --- a/src/gui/TrackContainerView.cpp +++ b/src/gui/TrackContainerView.cpp @@ -384,8 +384,9 @@ void TrackContainerView::dropEvent( QDropEvent * _de ) InstrumentTrack * it = dynamic_cast( Track::create( Track::InstrumentTrack, m_tc ) ); - Instrument * i = it->loadInstrument( - pluginFactory->pluginSupportingExtension(FileItem::extension(value)).name()); + PluginFactory::PluginInfoAndKey piakn = + pluginFactory->pluginSupportingExtension(FileItem::extension(value)); + Instrument * i = it->loadInstrument(piakn.info.name(), &piakn.key); i->loadFile( value ); //it->toggledInstrumentTrackButton( true ); _de->accept(); @@ -529,7 +530,8 @@ InstrumentLoaderThread::InstrumentLoaderThread( QObject *parent, InstrumentTrack void InstrumentLoaderThread::run() { - Instrument *i = m_it->loadInstrument( m_name ); + Instrument *i = m_it->loadInstrument(m_name, nullptr, + true /*always DnD*/); QObject *parent = i->parent(); i->setParent( 0 ); i->moveToThread( m_containerThread ); diff --git a/src/gui/widgets/TrackLabelButton.cpp b/src/gui/widgets/TrackLabelButton.cpp index db310a05e..361db740e 100644 --- a/src/gui/widgets/TrackLabelButton.cpp +++ b/src/gui/widgets/TrackLabelButton.cpp @@ -195,9 +195,15 @@ void TrackLabelButton::paintEvent( QPaintEvent * _pe ) InstrumentTrack * it = dynamic_cast( m_trackView->getTrack() ); const PixmapLoader * pl; + auto get_logo = [](InstrumentTrack* it) -> const PixmapLoader* + { + return it->instrument()->key().isValid() + ? it->instrument()->key().logo() + : it->instrument()->descriptor()->logo; + }; if( it && it->instrument() && it->instrument()->descriptor() && - ( pl = it->instrument()->descriptor()->logo ) ) + ( pl = get_logo(it) ) ) { if( pl->pixmapName() != m_iconName ) { diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 298430b03..2b25982df 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -735,7 +735,10 @@ void InstrumentTrack::saveTrackSpecificSettings( QDomDocument& doc, QDomElement { QDomElement i = doc.createElement( "instrument" ); i.setAttribute( "name", m_instrument->descriptor()->name ); - m_instrument->saveState( doc, i ); + QDomElement ins = m_instrument->saveState( doc, i ); + if(m_instrument->key().isValid()) { + ins.appendChild( m_instrument->key().saveXML( doc ) ); + } thisElement.appendChild( i ); } m_soundShaping.saveState( doc, thisElement ); @@ -796,9 +799,13 @@ void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & thisElement } else if( node.nodeName() == "instrument" ) { + typedef Plugin::Descriptor::SubPluginFeatures::Key PluginKey; + PluginKey key( node.toElement().elementsByTagName( "key" ).item( 0 ).toElement() ); + delete m_instrument; m_instrument = NULL; - m_instrument = Instrument::instantiate( node.toElement().attribute( "name" ), this ); + m_instrument = Instrument::instantiate( + node.toElement().attribute( "name" ), this, &key); m_instrument->restoreState( node.firstChildElement() ); emit instrumentChanged(); @@ -812,7 +819,8 @@ void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & thisElement { delete m_instrument; m_instrument = NULL; - m_instrument = Instrument::instantiate( node.nodeName(), this ); + m_instrument = Instrument::instantiate( + node.nodeName(), this, nullptr, true); if( m_instrument->nodeName() == node.nodeName() ) { m_instrument->restoreState( node.toElement() ); @@ -837,15 +845,20 @@ void InstrumentTrack::setPreviewMode( const bool value ) -Instrument * InstrumentTrack::loadInstrument( const QString & _plugin_name ) +Instrument * InstrumentTrack::loadInstrument(const QString & _plugin_name, + const Plugin::Descriptor::SubPluginFeatures::Key *key, bool keyFromDnd) { + if(keyFromDnd) + Q_ASSERT(!key); + silenceAllNotes( true ); lock(); delete m_instrument; - m_instrument = Instrument::instantiate( _plugin_name, this ); + m_instrument = Instrument::instantiate(_plugin_name, this, + key, keyFromDnd); unlock(); - setName( m_instrument->displayName() ); + setName(m_instrument->displayName()); emit instrumentChanged(); @@ -1733,7 +1746,7 @@ void InstrumentTrackWindow::dropEvent( QDropEvent* event ) if( type == "instrument" ) { - m_track->loadInstrument( value ); + m_track->loadInstrument( value, nullptr, true /* DnD */ ); Engine::getSong()->setModified(); @@ -1759,7 +1772,9 @@ void InstrumentTrackWindow::dropEvent( QDropEvent* event ) if( !i->descriptor()->supportsFileType( ext ) ) { - i = m_track->loadInstrument( pluginFactory->pluginSupportingExtension(ext).name() ); + PluginFactory::PluginInfoAndKey piakn = + pluginFactory->pluginSupportingExtension(ext); + i = m_track->loadInstrument(piakn.info.name(), &piakn.key); } i->loadFile( value ); From 4d64c422b22f3176aea30955575ab3af287e9e4f Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Thu, 27 Dec 2018 21:59:50 +0100 Subject: [PATCH 173/445] Fix Engine.cpp not compiling on some compilers --- src/core/Engine.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp index 7f89c20f3..50e25b0b4 100644 --- a/src/core/Engine.cpp +++ b/src/core/Engine.cpp @@ -29,6 +29,7 @@ #include "FxMixer.h" #include "Ladspa2LMMS.h" #include "Mixer.h" +#include "Plugin.h" #include "PresetPreviewPlayHandle.h" #include "ProjectJournal.h" #include "Song.h" @@ -118,7 +119,7 @@ void LmmsCore::updateFramesPerTick() void LmmsCore::setDndPluginKey(void *newKey) { - assert(static_cast(newKey)); + Q_ASSERT(static_cast(newKey)); s_dndPluginKey = newKey; } From fcd1a7ee86ca4e1471176853b28fb66762c124f7 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Thu, 27 Dec 2018 22:15:56 +0100 Subject: [PATCH 174/445] Fix or remove wrong or useless debug printfs --- src/core/Plugin.cpp | 1 - src/core/PluginFactory.cpp | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/core/Plugin.cpp b/src/core/Plugin.cpp index e7f80b5ab..7fcbd9795 100644 --- a/src/core/Plugin.cpp +++ b/src/core/Plugin.cpp @@ -220,7 +220,6 @@ Plugin * Plugin::instantiate(const QString& pluginName, Model * parent, } return new DummyPlugin(); } - qDebug() << "Using PluginInfo for " << pluginName; Plugin* inst; InstantiationHook instantiationHook; diff --git a/src/core/PluginFactory.cpp b/src/core/PluginFactory.cpp index a25dca54a..ec390ae6e 100644 --- a/src/core/PluginFactory.cpp +++ b/src/core/PluginFactory.cpp @@ -182,7 +182,7 @@ void PluginFactory::discoverPlugins() } else { - qDebug() << "Ignoring" << file << "(no lmms_plugin_main())"; + //qDebug() << "Ignoring" << file.absoluteFilePath() << "(no lmms_plugin_main())"; } if(pluginDescriptor) @@ -193,9 +193,6 @@ void PluginFactory::discoverPlugins() info.descriptor = pluginDescriptor; pluginInfos << info; - qDebug() << "Add" << info.file << "with type" - << info.descriptor->type; - auto addSupportedFileTypes = [this](const char* supportedFileTypes, const PluginInfo& info, @@ -204,7 +201,7 @@ void PluginFactory::discoverPlugins() if(supportedFileTypes) for (const QString& ext : QString(supportedFileTypes).split(',')) { - qDebug() << "Plugin " << info.name() << "supports" << ext; + //qDebug() << "Plugin " << info.name() << "supports" << ext; PluginInfoAndKey infoAndKey; infoAndKey.info = info; infoAndKey.key = key From f3b23830fbd9ef57ea9b1c6a2ad4aab7649881a0 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Thu, 27 Dec 2018 22:37:34 +0100 Subject: [PATCH 175/445] Fix missing IntrumentTrack header --- plugins/carlapatchbay/carlapatchbay.cpp | 1 + plugins/carlarack/carlarack.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/plugins/carlapatchbay/carlapatchbay.cpp b/plugins/carlapatchbay/carlapatchbay.cpp index 60e022156..ac00630d4 100644 --- a/plugins/carlapatchbay/carlapatchbay.cpp +++ b/plugins/carlapatchbay/carlapatchbay.cpp @@ -25,6 +25,7 @@ #include "carla.h" #include "embed.h" +#include "InstrumentTrack.h" extern "C" { diff --git a/plugins/carlarack/carlarack.cpp b/plugins/carlarack/carlarack.cpp index d057eff83..c0a39f9c2 100644 --- a/plugins/carlarack/carlarack.cpp +++ b/plugins/carlarack/carlarack.cpp @@ -25,6 +25,7 @@ #include "carla.h" #include "embed.h" +#include "InstrumentTrack.h" extern "C" { From aa0ce7fc545bbf2f63cb4df8853c1de474faba0d Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Fri, 28 Dec 2018 16:02:40 +0100 Subject: [PATCH 176/445] 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 177/445] 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 178/445] 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 179/445] 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 180/445] 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 181/445] 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 182/445] 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 183/445] 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 184/445] 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 185/445] 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 186/445] 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 187/445] 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 188/445] 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 189/445] 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 190/445] 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 191/445] 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 192/445] 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 d5dcebed83b21928975a641834dc08875407ff4e Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Fri, 18 Jan 2019 23:22:52 +0100 Subject: [PATCH 193/445] Use QString for SubPluginFeatures' virtuals The former virtuals returned `const char*`, which lead to invalid reads when `LadspaSubPluginFeatures` returned pointers to temporary `QByteArray::data`. --- include/Plugin.h | 12 +++++------ .../LadspaEffect/LadspaSubPluginFeatures.cpp | 4 ++-- .../LadspaEffect/LadspaSubPluginFeatures.h | 2 +- src/core/Plugin.cpp | 20 ++++++++++++++----- src/core/PluginFactory.cpp | 8 ++++---- 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/include/Plugin.h b/include/Plugin.h index 034d8a06c..48c5f90c7 100644 --- a/include/Plugin.h +++ b/include/Plugin.h @@ -165,9 +165,9 @@ public: // helper functions to retrieve data that is // not part of the key, but mapped via desc->subPluginFeatures - const char* additionalFileExtensions() const; - const char* displayName() const; - const char* description() const; + QString additionalFileExtensions() const; + QString displayName() const; + QString description() const; const PixmapLoader* logo() const; } ; @@ -200,19 +200,19 @@ public: // The defaults are sane, i.e. redirect to sub plugins // supererior descriptor - virtual const char* additionalFileExtensions(const Key&) const + virtual QString additionalFileExtensions(const Key&) const { return nullptr; } - virtual const char* displayName(const Key& k) const + virtual QString displayName(const Key& k) const { return k.isValid() ? k.desc->displayName : k.name.toUtf8().data(); } - virtual const char* description(const Key& k) const + virtual QString description(const Key& k) const { return k.isValid() ? k.desc->description : ""; } diff --git a/plugins/LadspaEffect/LadspaSubPluginFeatures.cpp b/plugins/LadspaEffect/LadspaSubPluginFeatures.cpp index 1b055fe73..4cefa90b5 100644 --- a/plugins/LadspaEffect/LadspaSubPluginFeatures.cpp +++ b/plugins/LadspaEffect/LadspaSubPluginFeatures.cpp @@ -44,11 +44,11 @@ LadspaSubPluginFeatures::LadspaSubPluginFeatures( Plugin::PluginTypes _type ) : -const char *LadspaSubPluginFeatures::displayName(const Plugin::Descriptor::SubPluginFeatures::Key &k) const +QString LadspaSubPluginFeatures::displayName(const Plugin::Descriptor::SubPluginFeatures::Key &k) const { const ladspa_key_t & lkey = subPluginKeyToLadspaKey(&k); Ladspa2LMMS * lm = Engine::getLADSPAManager(); - return lm->getName(lkey).toUtf8().data(); + return lm->getName(lkey); } diff --git a/plugins/LadspaEffect/LadspaSubPluginFeatures.h b/plugins/LadspaEffect/LadspaSubPluginFeatures.h index b7613827b..3f47734f9 100644 --- a/plugins/LadspaEffect/LadspaSubPluginFeatures.h +++ b/plugins/LadspaEffect/LadspaSubPluginFeatures.h @@ -37,7 +37,7 @@ class LadspaSubPluginFeatures : public Plugin::Descriptor::SubPluginFeatures public: LadspaSubPluginFeatures( Plugin::PluginTypes _type ); - const char* displayName(const Key& k) const override; + QString displayName(const Key& k) const override; void fillDescriptionWidget( QWidget * _parent, const Key * _key ) const override; diff --git a/src/core/Plugin.cpp b/src/core/Plugin.cpp index 7fcbd9795..2975cf104 100644 --- a/src/core/Plugin.cpp +++ b/src/core/Plugin.cpp @@ -89,6 +89,14 @@ T use_this_or(T this_param, T or_param) +QString use_this_or(QString this_param, QString or_param) +{ + return this_param.isNull() ? or_param : this_param; +} + + + + QString Plugin::displayName() const { return Model::displayName().isEmpty() // currently always empty @@ -113,7 +121,7 @@ const PixmapLoader* Plugin::logo() const -const char *Plugin::Descriptor::SubPluginFeatures::Key::additionalFileExtensions() const +QString Plugin::Descriptor::SubPluginFeatures::Key::additionalFileExtensions() const { Q_ASSERT(isValid()); return desc->subPluginFeatures @@ -126,12 +134,13 @@ const char *Plugin::Descriptor::SubPluginFeatures::Key::additionalFileExtensions -const char* Plugin::Descriptor::SubPluginFeatures::Key::displayName() const +QString Plugin::Descriptor::SubPluginFeatures::Key::displayName() const { Q_ASSERT(isValid()); return desc->subPluginFeatures // get from sub plugin - ? use_this_or(desc->subPluginFeatures->displayName(*this), desc->displayName) + ? use_this_or(desc->subPluginFeatures->displayName(*this), + QString::fromUtf8(desc->displayName)) // get from plugin : desc->displayName; } @@ -150,11 +159,12 @@ const PixmapLoader* Plugin::Descriptor::SubPluginFeatures::Key::logo() const -const char *Plugin::Descriptor::SubPluginFeatures::Key::description() const +QString Plugin::Descriptor::SubPluginFeatures::Key::description() const { Q_ASSERT(isValid()); return desc->subPluginFeatures - ? use_this_or(desc->subPluginFeatures->description(*this), desc->description) + ? use_this_or(desc->subPluginFeatures->description(*this), + QString::fromUtf8(desc->description)) : desc->description; } diff --git a/src/core/PluginFactory.cpp b/src/core/PluginFactory.cpp index ec390ae6e..f84227091 100644 --- a/src/core/PluginFactory.cpp +++ b/src/core/PluginFactory.cpp @@ -194,12 +194,12 @@ void PluginFactory::discoverPlugins() pluginInfos << info; auto addSupportedFileTypes = - [this](const char* supportedFileTypes, + [this](QString supportedFileTypes, const PluginInfo& info, const Plugin::Descriptor::SubPluginFeatures::Key* key = nullptr) { - if(supportedFileTypes) - for (const QString& ext : QString(supportedFileTypes).split(',')) + if(!supportedFileTypes.isNull()) + for (const QString& ext : supportedFileTypes.split(',')) { //qDebug() << "Plugin " << info.name() << "supports" << ext; PluginInfoAndKey infoAndKey; @@ -212,7 +212,7 @@ void PluginFactory::discoverPlugins() }; if (info.descriptor->supportedFileTypes) - addSupportedFileTypes(info.descriptor->supportedFileTypes, info); + addSupportedFileTypes(QString(info.descriptor->supportedFileTypes), info); if (info.descriptor->subPluginFeatures) { From 69a51eb28bf1d7d73594e380d9995ebb2d7b2b19 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Mon, 14 Jan 2019 22:05:42 +0000 Subject: [PATCH 194/445] 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 195/445] 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 196/445] 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

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%0D5W){wgRdp&dqTNCGMMGNn6_YbFhuI{b`cd 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 diff --git a/cmake/linux/CMakeLists.txt b/cmake/linux/CMakeLists.txt index 87f419405..24cc859c3 100644 --- a/cmake/linux/CMakeLists.txt +++ b/cmake/linux/CMakeLists.txt @@ -1,5 +1,4 @@ -INSTALL(FILES lmms.svg DESTINATION "${DATA_DIR}/icons/hicolor/scalable/apps") -INSTALL(FILES project.svg DESTINATION "${DATA_DIR}/icons/hicolor/scalable/mimetypes/" RENAME "application-x-lmms-project.svg") +INSTALL(DIRECTORY icons/ DESTINATION "${DATA_DIR}/icons/hicolor") INSTALL(FILES lmms.desktop DESTINATION "${DATA_DIR}/applications") INSTALL(FILES lmms.xml DESTINATION "${DATA_DIR}/mime/packages") diff --git a/cmake/linux/icons/128x128/apps/lmms.png b/cmake/linux/icons/128x128/apps/lmms.png new file mode 100644 index 0000000000000000000000000000000000000000..7bad96f98ffbd085132d4402f8fec804738af87c GIT binary patch literal 4499 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 literal 0 HcmV?d00001 diff --git a/cmake/linux/icons/128x128@2/mimetypes/application-x-lmms-project.png b/cmake/linux/icons/128x128@2/mimetypes/application-x-lmms-project.png new file mode 100644 index 0000000000000000000000000000000000000000..e7dbe591feea1eb51341ce30939ae40dc77d3b4f GIT binary patch literal 5331 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 literal 0 HcmV?d00001 diff --git a/cmake/linux/icons/16x16/apps/lmms.png b/cmake/linux/icons/16x16/apps/lmms.png new file mode 100644 index 0000000000000000000000000000000000000000..7148c9373ba98f0d89c7f167f661f10782aa4532 GIT binary patch literal 549 zcmV+=0^0qFP)wI4Q zoZdVEw0bIs=ytQ_Ya|wY2*9iLSqi11wX0|i0FOQ0r+OK@a+{%GA7?#Y0B&6l@@{>R zsqaga&BG)5YJfnbse^dv5r#iNaetfG=Qot)kkRlU!#4)Ff3=6P>#41a*}$OxG7e}L4GPctcs8z|+doc(&WqQ0+w%k`tz(67OFNTy;#P&}yGgo@>uxI8 zPPc@|@wR}+3(px24FK>uJ8ub(Lz|Y%gkDyjvZ&GX n?OF;H-BkkQP$lY8doun42pp&9&5}2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4JzX3_ zEP9hu8ki=3zM3x~A=x5X&^){T|3<61=2;bOIwv^HA2@yef4+R4fx#d5t6%@$82+DfyRcOloMCJrFY!D>~(-)1^1aFCK6NBSq%+7 zZ!$Ij0+)5G(ss<=&X>n%3t{5;K|3Thffx3SNyc#ZLri&N)>ep>fqLv-_E^Y+Xjw;MK?MQr6;)r_T?OqW)v0` hgKdftAJt6;OXk;vd$@?2>^zpwTu7& literal 0 HcmV?d00001 diff --git a/cmake/linux/icons/16x16@2/apps/lmms.png b/cmake/linux/icons/16x16@2/apps/lmms.png new file mode 100644 index 0000000000000000000000000000000000000000..f6ca1cb292bea887cc8918c42d5d5602bf61da6f GIT binary patch literal 934 zcmV;X16lluP)LJ{ZDw4}w6e zha!3qqK6^~sRy?tx>)(vLm_k{=pxlaJw#E4L`7(@Yo-QDQPCBxwOq~GHuvegDf`;D3iS_M)W2T__2;9>EeIEy-GgAexcn8jqu{M`NI*!(Awa zq=Ut-dDzO(o~`u%$l4@P0@M)>YrTX?KfXy6QhaQ^bDB7WO))* zxy#vHw2D+^5&#Qk7IEsybn=e{9)YV9Ta0mdKVr6^5YStAj)o@??d&6z{*a<+| z>}&u$&Vv$+eGFBI@M>^XYs7tD2dKV(l$~uS=>I+x;rfHa9O$~h*1JdO`|>I3jM^5J z8w-sAAp}BbnKz%eQrT2XQ*T>@6T9wy=%C_uEtk5RwRsuDHLO4^c6g6RWo@+l!D04y zp4SF2h^rk!9hY(Mn}xx79Ro%I{!HKK{9mtt=@~e?&`sIY!h|z0KRut5uq33{%{XuNzw1M%aGo0ouZ{werfUIM=13~ao%j|ZH-E6vXSTh5r`7zLZ z4L^IIMG;Cf3)nV)4FJa;UBTn)As!O(?IroZ=+|(p0Y8xDfBb?_F!?{F0CI|g&5;W* z;Bg+bLsSbyGr*MGEM&zJ?pYF-tXPEm8y(L085YSXffSv>KaeFu~}; zjk;g~?p>IWs0om^x{<9P;ST_#P~*Y{8<&QVs8MVy=mt@{F#$Ekgh_0zGtb2UZRdk| z)0w6xnZ?}u?mNHSnRhcoU{Exhm;=FSW88%lLP+v$rZf-?EkwrC+tr&pu(>gZxq}2SJnYRSFVqC! zlOzG`X*8ScYZL$g1VPwrESrio3IG5?4BGQpE_Jj~006;W4cc_w0JOqC4hBT(2Jq+0 zDi?%NqE}-=37E>Dt{0%Z&)crEm=gf}=)f)sgqr3Vx9mH>I0q3WKuf?pQoRGzxT9YH z%%KDFzAjt~U&Kxtz{H1Vc)9k`UjVxf$nCmuyrVo*Ci_N^`S}SGOYT9q-vQnD65^e@ zapwCn?!Qi>SSn%o=iz5i}G4K%go`yvZ+OFu#beH)gl3cL87>7DU~c1j?miTNBt{ z6{=Entmg)>I|X!4&^j*(plw0NdZX+oAv0VXdUEbI;+2 z4fXEt!qnNZ>KtQ8pTC9pfpA5+b-huwPeQMGX8?~5exHJY=}}xiH3R^-JO9`@&nesg zg5U2}s^X=!^{RWRBjhUID(l|^3&+N*Jh?j{wl-~@bK1Pab>2?g?*Nemh!yADZQeBi z5h$3da&6)yLaBRz-SS~y%$;QMcTDE$==Z`H_z(09{SE4U%me@c002ovPDHLkV1gVC BPm%xt literal 0 HcmV?d00001 diff --git a/cmake/linux/icons/24x24/apps/lmms.png b/cmake/linux/icons/24x24/apps/lmms.png new file mode 100644 index 0000000000000000000000000000000000000000..988da8872cf8961df27d7aca25cfdd19f3616941 GIT binary patch literal 799 zcmV+)1K|9LP)gk1Fpv?YwQ?sEDh(AyWto}dZ80{}o2N4q zOb71boqO*0o$ovMy$Am}1VF)X!(pUsL$W?LsB#*iR(o=qdQ<@9V(aYW2bXVdJ|_5z zRZp|IoUOnHi=RNG#tIx@3CjhbMtdmP>fn5K1&O+irk8Hs&VG#QTtotk5FFjOhq~-z zBxvyf6gjiFHTsx4V?FrfVw42ZyqW1p<8uB9eqbhD740MK{0ma4o`std}9Q#C5m_fnja%Z=gtJeqiJAg}}l zNTigs?y3!d_l|ogai67Sqzhk?j?fi^uCU3aikW8A4#h2`G@ubn8A)&%paJZVo@B&pTq+%Xel_lT*gdlx-mb{y_o2 zcIRd~_Fph{-dWOU0uQSoqTkWZBcv|uEi!c$6@l^5^d6ME>v%RX7)X1jM>*cv5WL^f z)-8qqk2YBE``rJ^0wCvo_`d(7aBUUXE0jA*3kcC>Ekd@ko6sg1}ri3P{ dV}unxeghp$ESirsS=j&p002ovPDHLkV1hxGWW)df literal 0 HcmV?d00001 diff --git a/cmake/linux/icons/24x24/mimetypes/application-x-lmms-project.png b/cmake/linux/icons/24x24/mimetypes/application-x-lmms-project.png new file mode 100644 index 0000000000000000000000000000000000000000..548660bb22233c9020d8afe7b7909e97bd31f3e8 GIT binary patch literal 681 zcmV;a0#^NrP)e9aeL~ItMpLtR*<%ki&juPcokX+six30QhV`Wup&jYSX~4~c zcHpt>yqWoCW@q1neHKyv5?j_*k#u?R-$aVR%-Qjm^#QV)+*<#Hl(J@Ix%rFc-UtG8 z0XNd!6Z1}XKAU45!7cWn6yZtFJMC6ofCfcK!AvZx4el2JjCMcn$vznPF94wk^zYj? zwM0BBSE!8wIMl??wE|MNezWG@NT?w|G~B_^$!i=?{7mJZvG64aEdlEoI*1)mF-1n; z>zr>twWpizzsK9JADCL5XJI4f6=1ArxPzh7X5gj5dnVtc*!jK7?Y;yTj-6q;f7k%6 zxPxo}Su`q`yQ~3_Ddd@4OtJWR1tk;!AxOR$<6QVSclvG`pi9G?NF^Ns_9>Fm(x$}I z5z;@_P}_nCzk+D;p&mZS^7coP&qrPTs<)`zpe<jr06N8j23KnVp9e#M%H%YJJ# zLZ*9SFRnw2O5_@2SnrtH07965vsV#5`_X3w2=Xnlh?h&>fkOVD{JqK_#3s}c*Aj!T P00000NkvXXu0mjfQ%Nsm literal 0 HcmV?d00001 diff --git a/cmake/linux/icons/24x24@2/apps/lmms.png b/cmake/linux/icons/24x24@2/apps/lmms.png new file mode 100644 index 0000000000000000000000000000000000000000..76d9e5b9bb11772a5b943c1f9d87af565ee1e15f GIT binary patch literal 1449 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 P00000NkvXXu0mjfb7$|k literal 0 HcmV?d00001 diff --git a/cmake/linux/icons/32x32/mimetypes/application-x-lmms-project.png b/cmake/linux/icons/32x32/mimetypes/application-x-lmms-project.png new file mode 100644 index 0000000000000000000000000000000000000000..9aabbde82119630beb802f70c181a1bc146428ab GIT binary patch literal 836 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 literal 0 HcmV?d00001 diff --git a/cmake/linux/icons/48x48/mimetypes/application-x-lmms-project.png b/cmake/linux/icons/48x48/mimetypes/application-x-lmms-project.png new file mode 100644 index 0000000000000000000000000000000000000000..4ea287a9b1ff88a89d0216387cb03239b247054e GIT binary patch literal 1206 zcmV;n1WEgeP)}^jfj25xVyZh?Y$Y{}w|4uUTRl!E@!dX)?`-8mJUA4E3H65Vptd zZFz&&T~9#Tz`&Y$MP!8lfL}z`2mts*WR(CQaS>T307y(kRtf-&i^y65fH4u75kP>@ z-5EosjIn07w`IE)pAi8>qL>;OF(!fljG#@67EP?nIBX(9cY>Jc83I^*b7xISp%#}J z0RjOW5(uQEL#0eWiSuDJRc?k%CG79%#4mqdOGzHn1uV3=u(Nyvo_X{MP!e8ZN7uID z>+9Wk`{zy!Pu?^&pS}QQV1mxVDckWv*?MeSQU?o-o*D!M>lV3D`%o2*4|U<4-Xj6!L_qLV zfg6p>>rr6Oi{S@v|ABpH+7VEKXj!uzWeXP1aZcHe#^v>BSh5!HUpj%KgQuae5N914 zSmoW#{C&f!oaey`G(ENjOXn?);l=_J_~6`e9K3K6K_$G;Q-Pwsq85#w2Dq%w7@yz9 zf5&^hU*N0ZpH%bZloz0T#Xi+qbp?#~`Bb?pTRLLy&4d(ue(5{xKYJLXQ{y0_0P4IC z1i*|x02Wk`YjI$QdlR0o+5m~h4u08Z+f?&8%L_FHB)tXz;0NDDy#D<`^xyJ<2n5t& z0kvD^9*^V_5t<5O+&_so&vc-(_ggf18t`=K<6QY7q2Ed{jq4t4J+cS=w}wHjGNc8L zaPf$?7p&48H+cI7c76F4cfLr(S;WR3iD03iITjF!>iY=*&5$dTBrIC0u(W0Ufex>k7dD|GCmua$YFXs>PN&KC(&MxZ*c z6z#RI;QY;gyxVgOXK(bX+O2$`3@=u0glFNhr1C|=)C0}mLbUL4U8{ESoX{NsmOwL? zDL-=-aR&Xe`m2Nyn06k>lpj|svH5T_x`w literal 0 HcmV?d00001 diff --git a/cmake/linux/icons/48x48@2/apps/lmms.png b/cmake/linux/icons/48x48@2/apps/lmms.png new file mode 100644 index 0000000000000000000000000000000000000000..af2c5eda26f4aa13f3b6cf90e8e54b0570d173f3 GIT binary patch literal 2075 zcmV+$2;}#PP)9 zfV=i~{NuRF)$Z-x?PK=ne3JX8H=X&-_q#JYzuCtD91e%W;cz%Z5u#O~;*Ywt?z^G4 z0Hqof#T3Y}BCu420No(;oI-^Le};d@l_$3aG|He9OXy(cK(ReJjnxZ@|Gp8JF<)SO@+5r{w_raP%~xSI;H1Q4`zq~D#b zHWCE2in=@c-j0ahbM2PU*L9DJ9|u&S=jd6sws<+<#0uPClG=~ zV|`dSx*T6z{sB8LeUCt>mrr1OqK4M}*|Cj6XVDpSxygp$8Hn%jO>CR=7BGiv94ajwQ@NUTx zRE?btqP=6Tig#Ecc2{h`Pwmav)Vv$lyKfs9r7_sb0GH&%iiyvow&+DTMTcSaR^*jo z&f_K6`}+}WJ%0e5z4r{OTQ9aSKp+HF1wO3xzJ?KL*`~DN5G1@Y;aR*?FdN%j4`KI} z9}%Js^AXu|8diR4kg>FQWd$ zUIaoxte&|PbMi|KZ^P>;#O}(C;Y9BAE>jXYL#H5@HRZ*Lr^!}L*;!$uSsZ$y70cl8Lip4)F|BBy$IPH)~A0)Wm-*EKKN2!x<&tPg9a zE;TKY8cg`XFw+PC=m>UU`}u=$CvsUu`3e9umTekz$*0=@-{Zx2zqA@fZgUbTHQ@zW zgplb3Aq1h$0F+=~)c0l^@q1@GwzTZSk+#z@%b9M##n-;p3^p0GgcqFAvnLIPm>4nX z+c#r=uVsKG%g{tsz^V%x zjcu)}!i$+skO#tR#v=<5JuV0XjQF+f0+t{67}G~h#+q5n3^PKnKFl}c;uStoh^#Uq z+FDI9B3YOjV3zO$vAYqLp931(T2X&I4&e=MmpDX7!v;S`EZ_ezrjJh22%T|Seq+|F z`#y*gUywyOJn4{zXBc+W$09N!9K$oBR#FiotcKYXWb{;%C~8xa)mT0S2@Z3onnW2m zH6@JM%TS{gl7^?7Qm)Yd(AxhNwsAtCmL=5W4Hl~ ziQ^n#@T6^YeXP;hA3g#YW4Qqh3qOJ{x5VmZH7OrigfHi>x4d1;m!Z=}PQ;h<*W=Xf z%h-120FJevGq!;QDbFdwO7CL$@{&9#%-@PI2i8XD7TzG3UlFs~2)hU$fw=(@%r?Sq z!bi})C~xtyvEPVWm$CKCe%(ft=M-Vp)K^RsUavm3U4~A}nTW3ze4x9YhUY%A-BJHA zwl!d=zztxG?e2`TUHe+_?da5o8^9RrcS93}b^BU8s>{%!0yls$+yKV#WvE{GGBmZ} z1~A6*dqWe4b^BVFy$q$XKd*kX4nO~C{5y9VZ(P9gh7UE{w|#sXXg;RuKXo;xNx{E6 z0RS_`Ou_28HF)|7eeeHiym0~bNB8uLCg*19s*iPi+0(}BdrmlB10p2b(SaR{V3Yx@ z;?r+HQ)~lhFoaNd07@|WvHf^Es@Ado2RUSYFLh!aUv|0421H1-qh~oC8=B?(oq_W{YDXDk?;etDn57l1UB!A zAPy0dJ6*M-|Ld5=%YD1VXZn3XL>3{*(N7_=IO5e{9iL@4W<{RMwJWUR<9k7jvHy1T zBaZqHxlwch01^2hNtTDSyQ@}4U0nee06=;yjq2VJ8=@aawu=G)L0HR#3{WW90|2fu zBPbC>)_qC24-rMA<&UHQKp$wCkOBS-{|*qe2x&61ipMDOuuRIQBW;K%K=x$Ptdaud z!Oz(?-;<@Cs^w!P0k|@Y^b literal 0 HcmV?d00001 diff --git a/cmake/linux/icons/48x48@2/mimetypes/application-x-lmms-project.png b/cmake/linux/icons/48x48@2/mimetypes/application-x-lmms-project.png new file mode 100644 index 0000000000000000000000000000000000000000..c583535d647140efd4530c41cc9f24d59af01434 GIT binary patch literal 2106 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 v;$Mzw_Ze~s4 + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/cmake/linux/icons/scalable/mimetypes/application-x-lmms-project.svg b/cmake/linux/icons/scalable/mimetypes/application-x-lmms-project.svg new file mode 100644 index 000000000..29697ece8 --- /dev/null +++ b/cmake/linux/icons/scalable/mimetypes/application-x-lmms-project.svg @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/cmake/linux/lmms.png b/cmake/linux/lmms.png deleted file mode 100644 index ae9fe6a2a9f329fb005f8a5bedcf55874bba3b92..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95342 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 U&9n^i#Q*>R07*qoM6N<$f@CRPtN;K2 diff --git a/cmake/linux/lmms.svg b/cmake/linux/lmms.svg deleted file mode 100644 index ffe6976ce..000000000 --- a/cmake/linux/lmms.svg +++ /dev/null @@ -1,1540 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cmake/linux/project.svg b/cmake/linux/project.svg deleted file mode 100644 index 62888e277..000000000 --- a/cmake/linux/project.svg +++ /dev/null @@ -1,1912 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - mmpz - - - - mmpz - mmpz - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cmake/nsis/CMakeLists.txt b/cmake/nsis/CMakeLists.txt index b21c920e5..eb9868bf5 100644 --- a/cmake/nsis/CMakeLists.txt +++ b/cmake/nsis/CMakeLists.txt @@ -1,5 +1,5 @@ SET(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis/nsis_branding.bmp") -SET(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis/lmms.ico") +SET(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis/icon.ico") SET(CPACK_NSIS_INSTALLED_ICON_NAME "${CMAKE_PROJECT_NAME}.exe" PARENT_SCOPE) SET(CPACK_NSIS_DISPLAY_NAME "${PROJECT_NAME_UCASE} ${VERSION}" PARENT_SCOPE) SET(CPACK_NSIS_HELP_LINK "${PROJECT_URL}" PARENT_SCOPE) @@ -71,3 +71,5 @@ IF(LMMS_HAVE_STK) ENDIF() INSTALL(FILES "lmms.exe.manifest" DESTINATION .) +INSTALL(FILES "lmms.VisualElementsManifest.xml" DESTINATION .) +INSTALL(DIRECTORY "assets" DESTINATION .) diff --git a/cmake/nsis/FileAssociation.nsh b/cmake/nsis/FileAssociation.nsh index 061df6c4f..2ae430504 100644 --- a/cmake/nsis/FileAssociation.nsh +++ b/cmake/nsis/FileAssociation.nsh @@ -129,6 +129,7 @@ NoBackup: WriteRegStr HKCR "$R0" "" "$R0" WriteRegStr HKCR "$R0\shell" "" "open" Skip: + WriteRegStr HKCR "$R0\DefaultIcon" "" "$R2,1" WriteRegStr HKCR "$R0\shell\open\command" "" '"$R2" "%1"' WriteRegStr HKCR "$R0\shell\edit" "" "Edit $R0" WriteRegStr HKCR "$R0\shell\edit\command" "" '"$R2" "%1"' diff --git a/cmake/nsis/assets/Logo.png b/cmake/nsis/assets/Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e1566b218f7d425c3fad22c442f026bb5b692504 GIT binary patch literal 5220 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 literal 0 HcmV?d00001 diff --git a/cmake/nsis/assets/SmallLogo.png b/cmake/nsis/assets/SmallLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..23d44ee283e252a181e92632a6d3f66da179c8c7 GIT binary patch literal 1743 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 By2t + + \ No newline at end of file diff --git a/cmake/nsis/lmms.ico b/cmake/nsis/lmms.ico deleted file mode 100644 index 9ee65b86d9c9bc8bded2c5bba79d4c604f469cd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137750 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

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 197/445] 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 198/445] 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 199/445] 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 200/445] 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 201/445] 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 202/445] 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 203/445] 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 204/445] 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 205/445] 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 206/445] 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 207/445] 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 208/445] 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 209/445] 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 210/445] 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 211/445] 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 212/445] =?UTF-8?q?Ghost=20notes=20improvements.=20*=20Mak?= =?UTF-8?q?e=20a=20copy=20of=20a=20pattern=20it=E2=80=99s=20notes=20instea?= =?UTF-8?q?d=20of=20pointing=20to=20a=20pattern.=20*=20Save/load=20the=20g?= =?UTF-8?q?host=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 213/445] 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 214/445] 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 215/445] 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 216/445] 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 217/445] 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 218/445] 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 219/445] 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 220/445] 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 221/445] 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 222/445] 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 223/445] 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 224/445] 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 31dc8e18ff90489804747de8ef5e111da9d74b29 Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Mon, 25 Feb 2019 03:53:05 +0100 Subject: [PATCH 225/445] Test deployment preparation in regular builds (#4847) Tests whether contributions break packaging inadvertently --- .travis.yml | 2 -- .travis/linux..script.sh | 5 ++++- .travis/linux.win32.script.sh | 2 ++ .travis/linux.win64.script.sh | 2 ++ .travis/osx..script.sh | 5 ++++- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index c48186fa3..fb0325a0d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,8 +35,6 @@ script: - . ${TRAVIS_BUILD_DIR}/.travis/${TRAVIS_OS_NAME}.${TARGET_OS}.script.sh after_script: - ccache -s -before_deploy: - - if [ "$TARGET_OS" != debian-sid ]; then make package; fi deploy: provider: releases api_key: diff --git a/.travis/linux..script.sh b/.travis/linux..script.sh index a68620483..8f3b763d3 100644 --- a/.travis/linux..script.sh +++ b/.travis/linux..script.sh @@ -7,8 +7,11 @@ if [ $QT5 ]; then source /opt/qt59/bin/qt59-env.sh fi -cmake -DUSE_WERROR=ON $CMAKE_FLAGS .. +cmake -DCMAKE_INSTALL_PREFIX=../target/ -DUSE_WERROR=ON $CMAKE_FLAGS .. make -j4 make tests ./tests/tests + +make install +make appimage diff --git a/.travis/linux.win32.script.sh b/.travis/linux.win32.script.sh index eb7cb9f7a..1ef063d55 100644 --- a/.travis/linux.win32.script.sh +++ b/.travis/linux.win32.script.sh @@ -6,3 +6,5 @@ export CMAKE_OPTS="$CMAKE_FLAGS -DUSE_WERROR=ON" ../cmake/build_mingw32.sh make -j4 + +make package diff --git a/.travis/linux.win64.script.sh b/.travis/linux.win64.script.sh index fb62cb5b3..b99a461de 100644 --- a/.travis/linux.win64.script.sh +++ b/.travis/linux.win64.script.sh @@ -6,3 +6,5 @@ export CMAKE_OPTS="$CMAKE_FLAGS -DUSE_WERROR=ON" ../cmake/build_mingw64.sh make -j4 + +make package diff --git a/.travis/osx..script.sh b/.travis/osx..script.sh index fb1473f79..58df3b624 100644 --- a/.travis/osx..script.sh +++ b/.travis/osx..script.sh @@ -7,8 +7,11 @@ if [ $QT5 ]; then export CMAKE_PREFIX_PATH="$(brew --prefix qt5)" fi -cmake $CMAKE_FLAGS -DUSE_WERROR=OFF .. +cmake -DCMAKE_INSTALL_PREFIX=../target/ $CMAKE_FLAGS -DUSE_WERROR=OFF .. make -j4 make tests ./tests/tests + +make install +make dmg From e34f75a8c7605cbc9f31fbb43c91255679ede6fb Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Sun, 24 Feb 2019 21:57:53 -0500 Subject: [PATCH 226/445] Add needed macOS shortcuts (#4851) Fix insert bars, delete bars, delete notes on Apple keyboard --- src/gui/editors/AutomationEditor.cpp | 1 + src/gui/editors/PianoRoll.cpp | 1 + src/gui/editors/SongEditor.cpp | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 0234be0ab..06eece23a 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -404,6 +404,7 @@ void AutomationEditor::keyPressEvent(QKeyEvent * ke ) } break; + case Qt::Key_Backspace: case Qt::Key_Delete: deleteSelectedValues(); ke->accept(); diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 7bdf9dc07..fef788885 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -1184,6 +1184,7 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke ) clearSelectedNotes(); break; + case Qt::Key_Backspace: case Qt::Key_Delete: deleteSelectedNotes(); ke->accept(); diff --git a/src/gui/editors/SongEditor.cpp b/src/gui/editors/SongEditor.cpp index f3b69e47d..286b01f15 100644 --- a/src/gui/editors/SongEditor.cpp +++ b/src/gui/editors/SongEditor.cpp @@ -315,13 +315,13 @@ void SongEditor::keyPressEvent( QKeyEvent * ke ) { if( /*_ke->modifiers() & Qt::ShiftModifier*/ gui->mainWindow()->isShiftPressed() == true && - ke->key() == Qt::Key_Insert ) + ( ke->key() == Qt::Key_Insert || ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return ) ) { m_song->insertBar(); } else if(/* _ke->modifiers() & Qt::ShiftModifier &&*/ gui->mainWindow()->isShiftPressed() == true && - ke->key() == Qt::Key_Delete ) + ( ke->key() == Qt::Key_Delete || ke->key() == Qt::Key_Backspace ) ) { m_song->removeBar(); } From ad1fa16a9525776a19d8a760c484d0837c20d621 Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Mon, 25 Feb 2019 19:06:01 +0100 Subject: [PATCH 227/445] Move apt_mingw_cache out of build directory (#4842) --- .travis.yml | 2 +- .travis/linux.win.download.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index fb0325a0d..6067c3cad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ dist: trusty sudo: required cache: directories: - - apt_mingw_cache + - $HOME/apt_mingw_cache - $HOME/.ccache - $HOME/pbuilder-bases matrix: diff --git a/.travis/linux.win.download.sh b/.travis/linux.win.download.sh index 76d7928b4..aad5f1c69 100644 --- a/.travis/linux.win.download.sh +++ b/.travis/linux.win.download.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -e -CACHE_DIR=$TRAVIS_BUILD_DIR/apt_mingw_cache/$1 +CACHE_DIR=$HOME/apt_mingw_cache/$1 mkdir -p $CACHE_DIR pushd $CACHE_DIR From a233291c271a1fbb1da448bbc9efb8f53f3f6fbe Mon Sep 17 00:00:00 2001 From: Lukas W Date: Wed, 27 Feb 2019 09:50:48 +0100 Subject: [PATCH 228/445] Add missing include Compilation fails with debug build. Fixes regression from dd99f3a7c466e86e02a8a8811e4b41f471a8b15d --- src/core/MixHelpers.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/MixHelpers.cpp b/src/core/MixHelpers.cpp index d70b47e07..0957852c6 100644 --- a/src/core/MixHelpers.cpp +++ b/src/core/MixHelpers.cpp @@ -23,6 +23,9 @@ */ #include "MixHelpers.h" + +#include + #include "lmms_math.h" #include "ValueBuffer.h" From 05d5e2036de38b082560d47c04d6bd282a76bd43 Mon Sep 17 00:00:00 2001 From: Alexandre Almeida Date: Sun, 3 Mar 2019 05:44:20 -0300 Subject: [PATCH 229/445] Fix DrumSynth sscanf (#4869) --- src/core/DrumSynth.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/DrumSynth.cpp b/src/core/DrumSynth.cpp index e1fb77793..b39e8f52e 100644 --- a/src/core/DrumSynth.cpp +++ b/src/core/DrumSynth.cpp @@ -119,7 +119,10 @@ void DrumSynth::GetEnv(int env, const char *sec, const char *key, QString ini) char en[256], s[8]; int i=0, o=0, ep=0; GetPrivateProfileString(sec, key, "0,0 100,0", en, sizeof(en), ini); - en[255]=0; //be safe! + + //be safe! + en[255]=0; + s[0]=0; while(en[i]!=0) { From 0e77947793eecc073b820b1d5b9e4210bf2afcb3 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sun, 3 Mar 2019 14:44:19 +0100 Subject: [PATCH 230/445] 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 e54969c568d4e2f270ccb340959129ab653973a4 Mon Sep 17 00:00:00 2001 From: tresf Date: Tue, 5 Mar 2019 15:55:41 -0500 Subject: [PATCH 231/445] Add /sbin to AppImage search path Closes #4846 --- cmake/linux/package_linux.sh.in | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index ee0389749..b02a4c688 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -97,6 +97,7 @@ mv "${APPDIR}usr/bin/lmms" "${APPDIR}usr/bin/lmms.real" cat >"${APPDIR}usr/bin/lmms" < /dev/null 2>&1; then CARLAPATH="\$(which carla)" CARLAPREFIX="\${CARLAPATH%/bin*}" From 009a451d0bbc3c944e08147d825f9941ae7b8ba7 Mon Sep 17 00:00:00 2001 From: Alexandre Almeida Date: Tue, 5 Mar 2019 18:36:01 -0300 Subject: [PATCH 232/445] Fix AudioFileProcessor tooltip (#4868) --- plugins/audio_file_processor/audio_file_processor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/audio_file_processor/audio_file_processor.cpp b/plugins/audio_file_processor/audio_file_processor.cpp index 2fdb8e459..313554899 100644 --- a/plugins/audio_file_processor/audio_file_processor.cpp +++ b/plugins/audio_file_processor/audio_file_processor.cpp @@ -522,7 +522,7 @@ AudioFileProcessorView::AudioFileProcessorView( Instrument * _instrument, "loop_pingpong_on" ) ); m_loopPingPongButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "loop_pingpong_off" ) ); - ToolTip::add( m_loopPingPongButton, tr( "Enable loop" ) ); + ToolTip::add( m_loopPingPongButton, tr( "Enable ping-pong loop" ) ); m_loopPingPongButton->setWhatsThis( tr( "This button enables ping-pong-looping. " "The sample loops backwards and forwards between the end point " From 991ffcd2e0261e306e996ad5eb661388ef39c1e4 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Tue, 5 Mar 2019 16:42:36 -0500 Subject: [PATCH 233/445] Disable soundio on macOS Temporarily disable soundio on macOS to address stability issues with PortAudio Closes #4864 --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e204a644a..2611d7086 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,7 @@ 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_SOUNDIO OFF) SET(WANT_ALSA OFF) SET(WANT_PULSEAUDIO OFF) SET(WANT_VST OFF) From 9e6ce0638d7e9d1ffb51ae32a0730c4c7e4e2379 Mon Sep 17 00:00:00 2001 From: tresf Date: Wed, 6 Mar 2019 23:39:53 -0500 Subject: [PATCH 234/445] Blacklist $HOME as VST directory Closes #4854 --- src/core/ConfigManager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ConfigManager.cpp b/src/core/ConfigManager.cpp index f52e10ac7..2ed0f8308 100644 --- a/src/core/ConfigManager.cpp +++ b/src/core/ConfigManager.cpp @@ -524,8 +524,9 @@ void ConfigManager::loadConfigFile( const QString & configFile ) cfg_file.close(); } - + // Plugins are searched recursively, blacklist problematic locations if( m_vstDir.isEmpty() || m_vstDir == QDir::separator() || m_vstDir == "/" || + m_vstDir == ensureTrailingSlash( QDir::homePath() ) || !QDir( m_vstDir ).exists() ) { #ifdef LMMS_BUILD_WIN32 From cdd1ddbb0cf3e2b09d7dc1daf0f4b2fa456456c1 Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Thu, 7 Mar 2019 06:32:23 +0100 Subject: [PATCH 235/445] Sync Debian version (#4840) * Sync Debian version * Drop temporary logging --- .travis.yml | 2 ++ .travis/linux.debian-sid.script.sh | 34 ++++++++++++++++++++++++++++++ debian/changelog | 2 +- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6067c3cad..b543a956d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,8 @@ matrix: osx_image: xcode8.2 env: QT5=True - env: TARGET_OS=debian-sid TARGET_DEPLOY=True + git: + depth: false - env: TARGET_OS=debian-sid TARGET_ARCH=i386 - compiler: clang env: TARGET_OS=debian-sid diff --git a/.travis/linux.debian-sid.script.sh b/.travis/linux.debian-sid.script.sh index 7318ae5ac..47143b5fe 100755 --- a/.travis/linux.debian-sid.script.sh +++ b/.travis/linux.debian-sid.script.sh @@ -31,6 +31,40 @@ else sudo pbuilder --update --basetgz "$BASETGZ" fi +sync_version() { + local VERSION + local MMR + local STAGE + local EXTRA + + VERSION=$(git describe --tags --match v[0-9].[0-9].[0-9]*) + VERSION=${VERSION#v} + MMR=${VERSION%%-*} + case $VERSION in + *-*-*-*) + VERSION=${VERSION%-*} + STAGE=${VERSION#*-} + STAGE=${STAGE%-*} + EXTRA=${VERSION##*-} + VERSION=$MMR~$STAGE.$EXTRA + ;; + *-*-*) + VERSION=${VERSION%-*} + EXTRA=${VERSION##*-} + VERSION=$MMR.$EXTRA + ;; + *-*) + STAGE=${VERSION#*-} + VERSION=$MMR~$STAGE + ;; + esac + + sed "1 s/@VERSION@/$VERSION/" -i debian/changelog + echo Set Debian version to $VERSION +} + +sync_version + DIR="$PWD" cd .. dpkg-source -b "$DIR" diff --git a/debian/changelog b/debian/changelog index c44b1790c..86f03c427 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -lmms (1.2.0~rc7.1) unstable; urgency=low +lmms (@VERSION@) unstable; urgency=low * Upstream integration. * Drop Debian menu entry (policy 9.6). 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 236/445] 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 237/445] 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 238/445] 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 17e87c1d689e1548d0c98a8a2fce5b229c799dbd Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 10 Mar 2019 10:27:51 +0100 Subject: [PATCH 239/445] Fix MidiJack crash on exit * Fix uninitialized m_jackClient being used in MidiJack destructor * Fix destruction order in Mixer.cpp so that MidiJack doesn't access the deleted AudioJack instance Fixes #4688 --- src/core/Mixer.cpp | 2 +- src/core/midi/MidiJack.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index fae7b35db..c87305641 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -186,8 +186,8 @@ Mixer::~Mixer() } delete m_fifo; - delete m_audioDev; delete m_midiClient; + delete m_audioDev; for( int i = 0; i < 3; i++ ) { diff --git a/src/core/midi/MidiJack.cpp b/src/core/midi/MidiJack.cpp index cea7f7381..568b6dae1 100644 --- a/src/core/midi/MidiJack.cpp +++ b/src/core/midi/MidiJack.cpp @@ -61,6 +61,7 @@ static void JackMidiShutdown(void *arg) MidiJack::MidiJack() : MidiClientRaw(), + m_jackClient( nullptr ), m_input_port( NULL ), m_output_port( NULL ), m_quit( false ) From 2a728080957053b54446d0cebca2417e27c27d14 Mon Sep 17 00:00:00 2001 From: Michael Gregorius Date: Sun, 3 Mar 2019 11:35:30 +0100 Subject: [PATCH 240/445] Fix #3926: QCursor in AFP Fix a crash that occurred on the following steps: 1. Add an AFP track. 2. Open it, and move the waveform display to overlap the track label button. 3. Close the AFP window and open it again by clicking the track label. 4. Move the mouse pointer. The problem occurs because the code makes the implicit assumption that AudioFileProcessorWaveView::enterEvent (and hence QApplication::setOverrideCursor) is called before AudioFileProcessorWaveView::mouseMoveEvent. This is not the case when the waveform display is on top of the track label. In this case the AFP windows is opened with the mouse being immediately positioned over the wave form display. There is no enter event and move events are issues directly. This then leads to a crash in AudioFileProcessorWaveView::mouseMoveEvent when trying to determine the value for is_size_cursor because the override cursor is still null but is dereferenced directly without checking. Only adding a check would not solve the problem because in that case the cursor would not change to the hand cursor when being moved inside the waveform display. The solution is to remove all calls to the global methods setOverrideCursor and restoreOverrideCursor and to only set the cursor locally. This fix is based on a patch by gi0e5b06 which is committed under 8a10c52 in his repository but for which he never created a pull request. --- .../audio_file_processor.cpp | 47 ++++++++++--------- .../audio_file_processor.h | 2 +- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/plugins/audio_file_processor/audio_file_processor.cpp b/plugins/audio_file_processor/audio_file_processor.cpp index 313554899..6be59f3cd 100644 --- a/plugins/audio_file_processor/audio_file_processor.cpp +++ b/plugins/audio_file_processor/audio_file_processor.cpp @@ -795,6 +795,7 @@ AudioFileProcessorWaveView::AudioFileProcessorWaveView( QWidget * _parent, int _ m_graph.fill( Qt::transparent ); update(); + updateCursor(); } @@ -811,7 +812,7 @@ void AudioFileProcessorWaveView::isPlaying( f_cnt_t _current_frame ) void AudioFileProcessorWaveView::enterEvent( QEvent * _e ) { - QApplication::setOverrideCursor( Qt::OpenHandCursor ); + updateCursor(); } @@ -819,10 +820,7 @@ void AudioFileProcessorWaveView::enterEvent( QEvent * _e ) void AudioFileProcessorWaveView::leaveEvent( QEvent * _e ) { - while( QApplication::overrideCursor() ) - { - QApplication::restoreOverrideCursor(); - } + updateCursor(); } @@ -850,7 +848,7 @@ void AudioFileProcessorWaveView::mousePressEvent( QMouseEvent * _me ) else { m_draggingType = wave; - QApplication::setOverrideCursor( Qt::ClosedHandCursor ); + updateCursor(_me); } } @@ -862,7 +860,7 @@ void AudioFileProcessorWaveView::mouseReleaseEvent( QMouseEvent * _me ) m_isDragging = false; if( m_draggingType == wave ) { - QApplication::restoreOverrideCursor(); + updateCursor(_me); } } @@ -873,22 +871,7 @@ void AudioFileProcessorWaveView::mouseMoveEvent( QMouseEvent * _me ) { if( ! m_isDragging ) { - const bool is_size_cursor = - QApplication::overrideCursor()->shape() == Qt::SizeHorCursor; - - if( isCloseTo( _me->x(), m_startFrameX ) || - isCloseTo( _me->x(), m_endFrameX ) || - isCloseTo( _me->x(), m_loopFrameX ) ) - { - if( ! is_size_cursor ) - { - QApplication::setOverrideCursor( Qt::SizeHorCursor ); - } - } - else if( is_size_cursor ) - { - QApplication::restoreOverrideCursor(); - } + updateCursor(_me); return; } @@ -1261,6 +1244,24 @@ void AudioFileProcessorWaveView::reverse() +void AudioFileProcessorWaveView::updateCursor( QMouseEvent * _me ) +{ + bool const waveIsDragged = m_isDragging && (m_draggingType == wave); + bool const pointerCloseToStartEndOrLoop = (_me != nullptr ) && + ( isCloseTo( _me->x(), m_startFrameX ) || + isCloseTo( _me->x(), m_endFrameX ) || + isCloseTo( _me->x(), m_loopFrameX ) ); + + if( !m_isDragging && pointerCloseToStartEndOrLoop) + setCursor(Qt::SizeHorCursor); + else if( waveIsDragged ) + setCursor(Qt::ClosedHandCursor); + else + setCursor(Qt::OpenHandCursor); +} + + + void AudioFileProcessorWaveView::knob::slideTo( double _v, bool _check_bound ) { diff --git a/plugins/audio_file_processor/audio_file_processor.h b/plugins/audio_file_processor/audio_file_processor.h index 150807686..d17be147c 100644 --- a/plugins/audio_file_processor/audio_file_processor.h +++ b/plugins/audio_file_processor/audio_file_processor.h @@ -211,7 +211,6 @@ public: private: bool checkBound( double _v ) const; - } ; @@ -276,6 +275,7 @@ private: void updateGraph(); void reverse(); + void updateCursor( QMouseEvent * _me = nullptr ); static bool isCloseTo( int _a, int _b ) { From 7e1df5cec9275e54b2c07b317864fe72c5dfb3bd Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 10 Mar 2019 14:47:05 +0100 Subject: [PATCH 241/445] Add issue templates Add Github issue templates for bug reports and feature requests --- .github/ISSUE_TEMPLATE/bug_report.md | 26 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 14 ++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..3ca71ce76 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,26 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +### Bug Summary + +#### Steps to reproduce + +#### Expected behavior + +#### Actual behavior + +#### Screenshot + +#### Logs +
+ Click to expand +
+# paste here
+
+
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..feacb8fdb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,14 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement +assignees: '' + +--- + +### Enhancement Summary + +#### Justification + +#### Mockup From 9a91848b3667c7944bf1145dadd35f0f227a10e2 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 11 Mar 2019 16:20:42 +0900 Subject: [PATCH 242/445] 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 243/445] 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 244/445] 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 245/445] 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 246/445] 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 247/445] 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 248/445] 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 249/445] 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 04768ee3e14a57d323112717bef10088411d9ae9 Mon Sep 17 00:00:00 2001 From: tresf Date: Mon, 11 Mar 2019 14:24:12 -0400 Subject: [PATCH 250/445] Fix zyn pitch on project load/export Closes #3451 --- plugins/zynaddsubfx/ZynAddSubFx.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index fff13c62d..a75d573a8 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -291,6 +291,7 @@ void ZynAddSubFxInstrument::loadSettings( const QDomElement & _this ) emit settingsChanged(); } + emit instrumentTrack()->pitchModel()->dataChanged(); } From 37290ace1d8824fc4e80779d9de7ebf5cfba4313 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Mon, 11 Mar 2019 23:03:43 +0100 Subject: [PATCH 251/445] 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 97d5529c18bee51d638607a192ab91b131d41086 Mon Sep 17 00:00:00 2001 From: tresf Date: Tue, 12 Mar 2019 00:25:17 -0400 Subject: [PATCH 252/445] Fix compilation on Qt4 --- plugins/zynaddsubfx/ZynAddSubFx.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index a75d573a8..e929f7c19 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -291,7 +292,10 @@ void ZynAddSubFxInstrument::loadSettings( const QDomElement & _this ) emit settingsChanged(); } +// FIXME: Remove this check in future versions. Slots are public in Qt5+ +#if QT_VERSION >= 0x050000 emit instrumentTrack()->pitchModel()->dataChanged(); +#endif } From 295b899df287c3ea44d5d49e59a12eec4a069fee Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Wed, 13 Mar 2019 23:27:54 +0100 Subject: [PATCH 253/445] Avoid shallow clones in all Debian sid builds (#4888) hallow clone may break version detection. This is fatal in Debian builds, so use full clone. Note: This is safe for stable-1.2 but needs review after merging to master due to submodules. See #4888 for more information. --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index b543a956d..5f8002cb1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,8 +24,12 @@ matrix: git: depth: false - env: TARGET_OS=debian-sid TARGET_ARCH=i386 + git: + depth: false - compiler: clang env: TARGET_OS=debian-sid + git: + depth: false before_install: - . ${TRAVIS_BUILD_DIR}/.travis/${TRAVIS_OS_NAME}.${TARGET_OS}.before_install.sh install: From 17f6235500ca3b820ba53891681ac8f443514a65 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Sun, 3 Mar 2019 16:01:07 +0000 Subject: [PATCH 254/445] Add VST always-on-top config option --- include/SetupDialog.h | 5 ++++ plugins/vst_base/VstPlugin.cpp | 4 +++- src/gui/SetupDialog.cpp | 44 ++++++++++++++++++++++++++++------ 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/include/SetupDialog.h b/include/SetupDialog.h index 338ea93dd..d0607022d 100644 --- a/include/SetupDialog.h +++ b/include/SetupDialog.h @@ -126,6 +126,9 @@ private slots: void toggleDisplayWaveform( bool en ); void toggleDisableAutoquit( bool en ); + void vstEmbedMethodChanged(); + void toggleVSTAlwaysOnTop( bool en ); + void setLanguage( int lang ); @@ -207,6 +210,8 @@ private: QComboBox* m_vstEmbedComboBox; QString m_vstEmbedMethod; + LedCheckBox * m_vstAlwaysOnTopCheckBox; + bool m_vstAlwaysOnTop; } ; diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index a97802bdc..e0e1347fe 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -329,7 +329,9 @@ bool VstPlugin::processMessage( const message & _m ) case IdVstPluginWindowID: m_pluginWindowID = _m.getInt(); - if( m_embedMethod == "none" ) + if( m_embedMethod == "none" + && ConfigManager::inst()->value( + "ui", "vstalwaysontop" ).toInt() ) { #ifdef LMMS_BUILD_WIN32 // We're changing the owner, not the parent, diff --git a/src/gui/SetupDialog.cpp b/src/gui/SetupDialog.cpp index 4c261f581..746e7e651 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -138,7 +138,9 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : "displaywaveform").toInt() ), m_disableAutoQuit(ConfigManager::inst()->value( "ui", "disableautoquit", "1" ).toInt() ), - m_vstEmbedMethod( ConfigManager::inst()->vstEmbedMethod() ) + m_vstEmbedMethod( ConfigManager::inst()->vstEmbedMethod() ), + m_vstAlwaysOnTop( ConfigManager::inst()->value( "ui", + "vstalwaysontop" ).toInt() ) { setWindowIcon( embed::getIconPixmap( "setup_general" ) ); setWindowTitle( tr( "Setup LMMS" ) ); @@ -346,7 +348,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : } TabWidget* embed_tw = new TabWidget( tr( "PLUGIN EMBEDDING" ), general); - embed_tw->setFixedHeight( 48 ); + embed_tw->setFixedHeight( 66 ); m_vstEmbedComboBox = new QComboBox( embed_tw ); m_vstEmbedComboBox->move( XDelta, YDelta ); @@ -365,6 +367,17 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : m_vstEmbedComboBox->addItem( tr( "Embed using XEmbed protocol" ), "xembed" ); } m_vstEmbedComboBox->setCurrentIndex( m_vstEmbedComboBox->findData( m_vstEmbedMethod ) ); + connect( m_vstEmbedComboBox, SIGNAL( currentIndexChanged( int ) ), + this, SLOT( vstEmbedMethodChanged() ) ); + + m_vstAlwaysOnTopCheckBox = new LedCheckBox( + tr( "Keep plugin windows on top when not embedded" ), + embed_tw ); + m_vstAlwaysOnTopCheckBox->move( 20, 44 ); + m_vstAlwaysOnTopCheckBox->setChecked( m_vstAlwaysOnTop ); + m_vstAlwaysOnTopCheckBox->setVisible( m_vstEmbedMethod == "none" ); + connect( m_vstAlwaysOnTopCheckBox, SIGNAL( toggled( bool ) ), + this, SLOT( toggleVSTAlwaysOnTop( bool ) ) ); TabWidget * lang_tw = new TabWidget( tr( "LANGUAGE" ), general ); lang_tw->setFixedHeight( 48 ); @@ -1094,11 +1107,9 @@ void SetupDialog::accept() QString::number( m_disableAutoQuit ) ); ConfigManager::inst()->setValue( "app", "language", m_lang ); ConfigManager::inst()->setValue( "ui", "vstembedmethod", -#if QT_VERSION >= 0x050000 - m_vstEmbedComboBox->currentData().toString() ); -#else - m_vstEmbedComboBox->itemData(m_vstEmbedComboBox->currentIndex()).toString() ); -#endif + m_vstEmbedMethod ); + ConfigManager::inst()->setValue( "ui", "vstalwaysontop", + QString::number( m_vstAlwaysOnTop ) ); ConfigManager::inst()->setWorkingDir(QDir::fromNativeSeparators(m_workingDir)); @@ -1316,6 +1327,25 @@ void SetupDialog::toggleOneInstrumentTrackWindow( bool _enabled ) m_oneInstrumentTrackWindow = _enabled; } + +void SetupDialog::vstEmbedMethodChanged() +{ +#if QT_VERSION >= 0x050000 + m_vstEmbedMethod = m_vstEmbedComboBox->currentData().toString(); +#else + m_vstEmbedMethod = m_vstEmbedComboBox->itemData( + m_vstEmbedComboBox->currentIndex()).toString(); +#endif + m_vstAlwaysOnTopCheckBox->setVisible( m_vstEmbedMethod == "none" ); +} + + +void SetupDialog::toggleVSTAlwaysOnTop( bool en ) +{ + m_vstAlwaysOnTop = en; +} + + void SetupDialog::setLanguage( int lang ) { m_lang = m_languages[lang]; From 6fef905dfe9a556d0e51738d90fff707d678ed44 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Sun, 3 Mar 2019 16:02:37 +0000 Subject: [PATCH 255/445] Ensure VST windows show properly in taskbar --- plugins/vst_base/RemoteVstPlugin.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index fbffe4b34..8dd25c11f 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -775,10 +775,6 @@ void RemoteVstPlugin::initEditor() SWP_NOMOVE | SWP_NOZORDER ); pluginDispatch( effEditTop ); - if (! EMBED) { - showEditor(); - } - #ifdef LMMS_BUILD_LINUX m_windowID = (intptr_t) GetProp( m_window, "__wine_x11_whole_window" ); #else From 205b57531d8b3d11c6d666f302426057c41d3fb0 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Sun, 3 Mar 2019 16:06:04 +0000 Subject: [PATCH 256/445] Don't show error when loading empty VeSTige instance --- plugins/vestige/vestige.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index 0cfa31d21..fc07e46d5 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -181,7 +181,13 @@ vestigeInstrument::~vestigeInstrument() void vestigeInstrument::loadSettings( const QDomElement & _this ) { - loadFile( _this.attribute( "plugin" ) ); + QString plugin = _this.attribute( "plugin" ); + if( plugin.isEmpty() ) + { + return; + } + + loadFile( plugin ); m_pluginMutex.lock(); if( m_plugin != NULL ) { From 3aeacca7acf7fe77a3f0545451dbe4e3332c1628 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Sun, 3 Mar 2019 16:11:02 +0000 Subject: [PATCH 257/445] Fix layout of VstSyncData struct Ensure member of type double is 8-byte aligned for consistent layout between 32- and 64-bit Linux builds. --- include/VstSyncController.h | 2 +- include/VstSyncData.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/VstSyncController.h b/include/VstSyncController.h index 682291b9e..970a48ad3 100644 --- a/include/VstSyncController.h +++ b/include/VstSyncController.h @@ -76,10 +76,10 @@ private slots: private: struct VstSyncData { - bool isPlaying; double ppqPos; int timeSigNumer; int timeSigDenom; + bool isPlaying; bool isCycle; bool hasSHM; float cycleStart; diff --git a/include/VstSyncData.h b/include/VstSyncData.h index f9696252a..6c2f1bbd2 100644 --- a/include/VstSyncData.h +++ b/include/VstSyncData.h @@ -41,10 +41,10 @@ struct VstSyncData { - bool isPlaying; double ppqPos; int timeSigNumer; int timeSigDenom; + bool isPlaying; bool isCycle; bool hasSHM; float cycleStart; From 2d71d6163bf9bb3bbdc715a265209397d58c8c1c Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Fri, 15 Mar 2019 18:42:34 +0100 Subject: [PATCH 258/445] Rework after code reading * Fix possible segfault in `SubPluginFeatures::displayName` * Minor fixes --- include/Plugin.h | 6 +++--- src/core/Plugin.cpp | 4 ++-- src/core/PluginFactory.cpp | 23 +++++++++++------------ 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/include/Plugin.h b/include/Plugin.h index 48c5f90c7..31c83c4ba 100644 --- a/include/Plugin.h +++ b/include/Plugin.h @@ -202,19 +202,19 @@ public: virtual QString additionalFileExtensions(const Key&) const { - return nullptr; + return QString(); } virtual QString displayName(const Key& k) const { return k.isValid() ? k.desc->displayName - : k.name.toUtf8().data(); + : k.name; } virtual QString description(const Key& k) const { - return k.isValid() ? k.desc->description : ""; + return k.isValid() ? k.desc->description : QString(); } virtual const PixmapLoader* logo(const Key& k) const diff --git a/src/core/Plugin.cpp b/src/core/Plugin.cpp index 2975cf104..1562044f9 100644 --- a/src/core/Plugin.cpp +++ b/src/core/Plugin.cpp @@ -127,8 +127,8 @@ QString Plugin::Descriptor::SubPluginFeatures::Key::additionalFileExtensions() c return desc->subPluginFeatures // get from sub plugin ? desc->subPluginFeatures->additionalFileExtensions(*this) - // get from plugin - : nullptr; + // no sub plugin, so no *additional* file extensions + : QString(); } diff --git a/src/core/PluginFactory.cpp b/src/core/PluginFactory.cpp index f84227091..abf642122 100644 --- a/src/core/PluginFactory.cpp +++ b/src/core/PluginFactory.cpp @@ -180,10 +180,6 @@ void PluginFactory::discoverPlugins() continue; } } - else - { - //qDebug() << "Ignoring" << file.absoluteFilePath() << "(no lmms_plugin_main())"; - } if(pluginDescriptor) { @@ -199,15 +195,18 @@ void PluginFactory::discoverPlugins() const Plugin::Descriptor::SubPluginFeatures::Key* key = nullptr) { if(!supportedFileTypes.isNull()) - for (const QString& ext : supportedFileTypes.split(',')) { - //qDebug() << "Plugin " << info.name() << "supports" << ext; - PluginInfoAndKey infoAndKey; - infoAndKey.info = info; - infoAndKey.key = key - ? *key - : Plugin::Descriptor::SubPluginFeatures::Key(); - m_pluginByExt.insert(ext, infoAndKey); + for (const QString& ext : supportedFileTypes.split(',')) + { + //qDebug() << "Plugin " << info.name() + // << "supports" << ext; + PluginInfoAndKey infoAndKey; + infoAndKey.info = info; + infoAndKey.key = key + ? *key + : Plugin::Descriptor::SubPluginFeatures::Key(); + m_pluginByExt.insert(ext, infoAndKey); + } } }; From 9aa997e5740fb6f5442ee2de5b2789530836a142 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 16 Mar 2019 16:38:16 +0100 Subject: [PATCH 259/445] Allow TabWidget to be variable sized --- include/TabWidget.h | 8 +++++-- src/gui/widgets/TabWidget.cpp | 43 ++++++++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/include/TabWidget.h b/include/TabWidget.h index dacd2648b..11e4da40a 100644 --- a/include/TabWidget.h +++ b/include/TabWidget.h @@ -36,7 +36,10 @@ class TabWidget : public QWidget { Q_OBJECT public: - TabWidget( const QString & _caption, QWidget * _parent, bool usePixmap = false ); + //! @param resizable If true, the widget resizes to fit the size of all tabs + //! If false, all child widget will be cut down to the TabWidget's size + TabWidget( const QString & _caption, QWidget * _parent, + bool usePixmap = false, bool resizable = false ); virtual ~TabWidget() = default; void addTab( QWidget * w, const QString & name, const char *pixmap = NULL, int idx = -1 ); @@ -74,7 +77,7 @@ protected: virtual void paintEvent( QPaintEvent * _pe ); virtual void resizeEvent( QResizeEvent * _re ); virtual void wheelEvent( QWheelEvent * _we ); - + virtual QSize minimumSizeHint() const; private: struct widgetDesc @@ -88,6 +91,7 @@ private: widgetStack m_widgets; + bool m_resizable; int m_activeTab; QString m_caption; // Tab caption, used as the tooltip text on icon tabs quint8 m_tabbarHeight; // The height of the tab bar diff --git a/src/gui/widgets/TabWidget.cpp b/src/gui/widgets/TabWidget.cpp index f06710098..49898a3c7 100644 --- a/src/gui/widgets/TabWidget.cpp +++ b/src/gui/widgets/TabWidget.cpp @@ -34,8 +34,10 @@ #include "gui_templates.h" #include "embed.h" -TabWidget::TabWidget( const QString & caption, QWidget * parent, bool usePixmap ) : +TabWidget::TabWidget(const QString & caption, QWidget * parent, bool usePixmap, + bool resizable) : QWidget( parent ), + m_resizable( resizable ), m_activeTab( 0 ), m_caption( caption ), m_usePixmap( usePixmap ), @@ -81,7 +83,9 @@ void TabWidget::addTab( QWidget * w, const QString & name, const char *pixmap, i m_widgets[idx] = d; // Position tab's window - w->setFixedSize( width() - 4, height() - m_tabbarHeight ); + if(!m_resizable) { + w->setFixedSize( width() - 4, height() - m_tabbarHeight ); + } w->move( 2, m_tabbarHeight - 1 ); w->hide(); @@ -189,17 +193,19 @@ void TabWidget::mousePressEvent( QMouseEvent * me ) void TabWidget::resizeEvent( QResizeEvent * ) { - for( widgetStack::iterator it = m_widgets.begin(); - it != m_widgets.end(); ++it ) + if(!m_resizable) { - ( *it ).w->setFixedSize( width() - 4, height() - m_tabbarHeight ); + for( widgetStack::iterator it = m_widgets.begin(); + it != m_widgets.end(); ++it ) + { + ( *it ).w->setFixedSize( width() - 4, height() - m_tabbarHeight ); + } } } - void TabWidget::paintEvent( QPaintEvent * pe ) { QPainter p( this ); @@ -300,6 +306,31 @@ void TabWidget::wheelEvent( QWheelEvent * we ) setActiveTab( tab ); } + + + +// Let parent widgets know how much space this tab widget needs +QSize TabWidget::minimumSizeHint() const +{ + if(m_resizable) + { + int maxWidth = 0, maxHeight = 0; + for( widgetStack::const_iterator it = m_widgets.begin(); + it != m_widgets.end(); ++it ) + { + maxWidth = std::max(maxWidth, it->w->width()); + maxHeight = std::max(maxHeight, it->w->height()); + } + return QSize(maxWidth + 4, maxHeight + m_tabbarHeight); + } + else { + return QWidget::minimumSizeHint(); + } +} + + + + // Return the color to be used to draw a TabWidget's title text (if any) QColor TabWidget::tabTitleText() const { From dd43127514a423cc76ba0a5135c355f3af14220c Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 16 Mar 2019 19:46:21 +0100 Subject: [PATCH 260/445] Allow instrument views to grow with contents Make InstrumentTrackWindow as large as the InstrumentView requires --- src/gui/InstrumentView.cpp | 1 - src/tracks/InstrumentTrack.cpp | 16 +++++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/gui/InstrumentView.cpp b/src/gui/InstrumentView.cpp index 9e8fc58c1..d2a7483e4 100644 --- a/src/gui/InstrumentView.cpp +++ b/src/gui/InstrumentView.cpp @@ -34,7 +34,6 @@ InstrumentView::InstrumentView( Instrument * _Instrument, QWidget * _parent ) : PluginView( _Instrument, _parent ) { setModel( _Instrument ); - setFixedSize( 250, 250 ); setAttribute( Qt::WA_DeleteOnClose, true ); } diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 298430b03..6f4ad2b8e 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -1326,7 +1326,7 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : this, SLOT( textChanged( const QString & ) ) ); m_nameLineEdit->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred)); - nameAndChangeTrackLayout->addWidget(m_nameLineEdit); + nameAndChangeTrackLayout->addWidget(m_nameLineEdit, 1); // set up left/right arrows for changing instrument @@ -1438,8 +1438,8 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : generalSettingsLayout->addLayout( basicControlsLayout ); - m_tabWidget = new TabWidget( "", this, true ); - m_tabWidget->setFixedHeight( INSTRUMENT_HEIGHT + GRAPHIC_TAB_HEIGHT - 4 ); + m_tabWidget = new TabWidget( "", this, true, true ); + m_tabWidget->setMinimumHeight( INSTRUMENT_HEIGHT + GRAPHIC_TAB_HEIGHT - 4 ); // create tab-widgets @@ -1474,18 +1474,16 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : // setup piano-widget m_pianoView = new PianoView( this ); - m_pianoView->setFixedSize( INSTRUMENT_WIDTH, PIANO_HEIGHT ); + m_pianoView->setMinimumHeight( PIANO_HEIGHT ); + m_pianoView->setMaximumHeight( PIANO_HEIGHT ); vlayout->addWidget( generalSettingsWidget ); - vlayout->addWidget( m_tabWidget ); + vlayout->addWidget( m_tabWidget, 1 ); vlayout->addWidget( m_pianoView ); - - setModel( _itv->model() ); updateInstrumentView(); - setFixedWidth( INSTRUMENT_WIDTH ); resize( sizeHint() ); QMdiSubWindow * subWin = gui->mainWindow()->addWindowedWidget( this ); @@ -1501,7 +1499,7 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : systemMenu->actions().at( 4 )->setVisible( false ); // Maximize subWin->setWindowIcon( embed::getIconPixmap( "instrument_track" ) ); - subWin->setFixedSize( subWin->size() ); + subWin->setMinimumSize( subWin->size() ); subWin->hide(); } From f8ba88d55a7f0069c54edb3b80a2ad8e7dc4187b Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 16 Mar 2019 20:10:19 +0100 Subject: [PATCH 261/445] 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 5101aa021440c9e6c183fd197af09154df5d619a Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 16 Mar 2019 20:19:27 +0100 Subject: [PATCH 262/445] Make Model class visitable --- include/AutomatableModel.h | 45 ++++++++++++++++++++++++++++++++ include/ComboBoxModel.h | 1 + include/ModelVisitor.h | 53 ++++++++++++++++++++++++++++++++++++++ src/core/CMakeLists.txt | 1 + src/core/ModelVisitor.cpp | 28 ++++++++++++++++++++ 5 files changed, 128 insertions(+) create mode 100644 include/ModelVisitor.h create mode 100644 src/core/ModelVisitor.cpp diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h index 78f4882b4..f5215676e 100644 --- a/include/AutomatableModel.h +++ b/include/AutomatableModel.h @@ -33,6 +33,7 @@ #include "MidiTime.h" #include "ValueBuffer.h" #include "MemoryManager.h" +#include "ModelVisitor.h" // simple way to map a property of a view to a model #define mapPropertyFromModelPtr(type,getfunc,setfunc,modelname) \ @@ -68,6 +69,7 @@ class LMMS_EXPORT AutomatableModel : public Model, public JournallingObject Q_OBJECT MM_OPERATORS public: + typedef QVector AutoModelVector; enum ScaleType @@ -80,6 +82,32 @@ public: virtual ~AutomatableModel(); + // Implement those by using the MODEL_IS_VISITABLE macro + virtual void accept(ModelVisitor& v) = 0; + virtual void accept(ConstModelVisitor& v) const = 0; + // use this to make subclasses visitable +#define MODEL_IS_VISITABLE \ + void accept(ModelVisitor& v) override { v.visit(*this); } \ + void accept(ConstModelVisitor& v) const override { v.visit(*this); } + +public: + //! Return this class casted to Target, or nullptr if impossible + template + Target* dcast(bool doThrow = false) + { + DCastVisitor vis; accept(vis); + if(doThrow && !vis.result) Q_ASSERT(false); + return vis.result; + } + + //! Return this class casted to const Target, or nullptr if impossible + template + const Target* dcast(bool doThrow = false) const + { + ConstDCastVisitor vis; accept(vis); + if(doThrow && !vis.result) Q_ASSERT(false); + return vis.result; + } bool isAutomated() const; bool isAutomatedOrControlled() const @@ -283,6 +311,20 @@ protected: private: + template + struct DCastVisitor : public ModelVisitor + { + Target* result = nullptr; + void visit(Target& tar) { result = &tar; } + }; + + template + struct ConstDCastVisitor : public ConstModelVisitor + { + const Target* result = nullptr; + void visit(const Target& tar) { result = &tar; } + }; + static bool mustQuoteName(const QString &name); virtual void saveSettings( QDomDocument& doc, QDomElement& element ) @@ -382,6 +424,7 @@ public: class LMMS_EXPORT FloatModel : public TypedAutomatableModel { Q_OBJECT + MODEL_IS_VISITABLE public: FloatModel( float val = 0, float min = 0, float max = 0, float step = 0, Model * parent = NULL, @@ -399,6 +442,7 @@ public: class LMMS_EXPORT IntModel : public TypedAutomatableModel { Q_OBJECT + MODEL_IS_VISITABLE public: IntModel( int val = 0, int min = 0, int max = 0, Model* parent = NULL, @@ -414,6 +458,7 @@ public: class LMMS_EXPORT BoolModel : public TypedAutomatableModel { Q_OBJECT + MODEL_IS_VISITABLE public: BoolModel( const bool val = false, Model* parent = NULL, diff --git a/include/ComboBoxModel.h b/include/ComboBoxModel.h index ad3603759..82c01e69e 100644 --- a/include/ComboBoxModel.h +++ b/include/ComboBoxModel.h @@ -36,6 +36,7 @@ class LMMS_EXPORT ComboBoxModel : public IntModel { Q_OBJECT + MODEL_IS_VISITABLE public: ComboBoxModel( Model* parent = NULL, const QString& displayName = QString(), diff --git a/include/ModelVisitor.h b/include/ModelVisitor.h new file mode 100644 index 000000000..59d1df0c6 --- /dev/null +++ b/include/ModelVisitor.h @@ -0,0 +1,53 @@ +/* + * ModelVisitor.h - visitors for automatable models + * + * Copyright (c) 2019-2019 Johannes Lorenz + * + * 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 MODELVISITOR_H +#define MODELVISITOR_H + +class BoolModel; +class IntModel; +class FloatModel; +class ComboBoxModel; + +class ModelVisitor +{ +public: + virtual void visit(BoolModel& ) {} + virtual void visit(IntModel& ) {} + virtual void visit(FloatModel& ) {} + virtual void visit(ComboBoxModel& ) {} + virtual ~ModelVisitor(); +}; + +class ConstModelVisitor +{ +public: + virtual void visit(const BoolModel& ) {} + virtual void visit(const IntModel& ) {} + virtual void visit(const FloatModel& ) {} + virtual void visit(const ComboBoxModel& ) {} + virtual ~ConstModelVisitor(); +}; + +#endif // MODELVISITOR_H diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 85a00780b..b573b93b0 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -40,6 +40,7 @@ set(LMMS_SRCS core/MixerWorkerThread.cpp core/MixHelpers.cpp core/Model.cpp + core/ModelVisitor.cpp core/Note.cpp core/NotePlayHandle.cpp core/Oscillator.cpp diff --git a/src/core/ModelVisitor.cpp b/src/core/ModelVisitor.cpp new file mode 100644 index 000000000..11a8fc1b1 --- /dev/null +++ b/src/core/ModelVisitor.cpp @@ -0,0 +1,28 @@ +/* + * ModelVisitor.cpp - visitors for automatable models + * + * Copyright (c) 2019-2019 Johannes Lorenz + * + * 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 "ModelVisitor.h" + +ModelVisitor::~ModelVisitor() {} +ConstModelVisitor::~ConstModelVisitor() {} From aac516e27fb441bf754da145fb72a2705fa54a30 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 16 Mar 2019 20:59:45 +0100 Subject: [PATCH 263/445] 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 264/445] 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 7e7141f38816a0b7b293585858c69866c972d2f1 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sun, 17 Mar 2019 10:43:38 +0100 Subject: [PATCH 265/445] Fix too small instrument tabs Previously, they had been resized by the fixed size parent tab widget. We need to do this manually now. --- src/tracks/InstrumentTrack.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 6f4ad2b8e..fb9261ff7 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -1472,6 +1472,17 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : m_tabWidget->addTab( m_midiView, tr( "MIDI" ), "midi_tab", 4 ); m_tabWidget->addTab( m_miscView, tr( "Miscellaneous" ), "misc_tab", 5 ); + //! adjust size of any child widget of the main tab + //! required to keep the old look when using a variable sized tab widget + auto adjustSize = [](QWidget *w) { + w->setMinimumSize(INSTRUMENT_WIDTH, INSTRUMENT_HEIGHT + GRAPHIC_TAB_HEIGHT); + }; + adjustSize(m_ssView); + adjustSize(instrumentFunctions); + adjustSize(m_effectView); + adjustSize(m_midiView); + adjustSize(m_miscView); + // setup piano-widget m_pianoView = new PianoView( this ); m_pianoView->setMinimumHeight( PIANO_HEIGHT ); From 0c3db1045cda28f613f4aecf6a946b6c8f19eb5b Mon Sep 17 00:00:00 2001 From: Martin Pavelek Date: Sun, 17 Mar 2019 15:00:47 +0100 Subject: [PATCH 266/445] Fix Blackman-Harris window formula (#4895) Adds missing parentheses --- plugins/Eq/EqSpectrumView.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/Eq/EqSpectrumView.cpp b/plugins/Eq/EqSpectrumView.cpp index 677c896fb..456ca4871 100644 --- a/plugins/Eq/EqSpectrumView.cpp +++ b/plugins/Eq/EqSpectrumView.cpp @@ -45,11 +45,11 @@ EqAnalyser::EqAnalyser() : const float a2 = 0.14128; const float a3 = 0.01168; - for(int i = 0; i < FFT_BUFFER_SIZE; i++) + for (int i = 0; i < FFT_BUFFER_SIZE; i++) { - m_fftWindow[i] = ( a0 - a1 * cosf( 2 * F_PI * i / (float)FFT_BUFFER_SIZE - 1 ) - + a2 * cosf( 4 * F_PI * i / (float)FFT_BUFFER_SIZE-1) - - a3 * cos( 6 * F_PI * i / (float)FFT_BUFFER_SIZE - 1.0 )); + m_fftWindow[i] = (a0 - a1 * cos(2 * F_PI * i / ((float)FFT_BUFFER_SIZE - 1.0)) + + a2 * cos(4 * F_PI * i / ((float)FFT_BUFFER_SIZE - 1.0)) + - a3 * cos(6 * F_PI * i / ((float)FFT_BUFFER_SIZE - 1.0))); } clear(); } From dd6c18e62b9963baeefbe4fb07b2e6bd67dc2174 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sat, 9 Mar 2019 18:57:12 +0100 Subject: [PATCH 267/445] Automation Editor: Don't accept drag events when there's no pattern Fixes #4857 --- src/gui/editors/AutomationEditor.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 06eece23a..fafb83d0d 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -2565,6 +2565,9 @@ void AutomationEditorWindow::dropEvent( QDropEvent *_de ) void AutomationEditorWindow::dragEnterEvent( QDragEnterEvent *_dee ) { + if (! m_editor->validPattern() ) { + return; + } StringPairDrag::processDragEnterEvent( _dee, "automatable_model" ); } From e1adfc3952389f0e6c18c3bf7daef40c4ca72481 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Fri, 1 Mar 2019 09:00:46 +0100 Subject: [PATCH 268/445] TCO drag: Fix Ctrl+Drag crash Fix some assumptions that source and target of a drag actions are the same track container. Instead of looking up necessary information (track name, type and container id) by track index, add it to the metadata. Refactor canPasteSelection to take QDropEvent instead of the drop event's QMimeData. Coincidentally, this fixes the method to be consistent with its documentation. Fixes #4844 --- include/Track.h | 2 +- src/core/Track.cpp | 27 ++++++++++++++++++--------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/include/Track.h b/include/Track.h index 00ee5d0a6..f548168b7 100644 --- a/include/Track.h +++ b/include/Track.h @@ -341,7 +341,7 @@ public: } } - bool canPasteSelection( MidiTime tcoPos, const QMimeData * mimeData ); + bool canPasteSelection( MidiTime tcoPos, const QDropEvent *de ); bool pasteSelection( MidiTime tcoPos, QDropEvent * de ); MidiTime endPosition( const MidiTime & posStart ); diff --git a/src/core/Track.cpp b/src/core/Track.cpp index b300d94a3..cd1d23b16 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -497,7 +497,7 @@ void TrackContentObjectView::dragEnterEvent( QDragEnterEvent * dee ) { TrackContentWidget * tcw = getTrackView()->getTrackContentWidget(); MidiTime tcoPos = MidiTime( m_tco->startPosition().getTact(), 0 ); - if( tcw->canPasteSelection( tcoPos, dee->mimeData() ) == false ) + if( tcw->canPasteSelection( tcoPos, dee ) == false ) { dee->ignore(); } @@ -602,9 +602,12 @@ DataFile TrackContentObjectView::createTCODataFiles( it != tcoViews.end(); ++it ) { // Insert into the dom under the "tcos" element - int trackIndex = tc->tracks().indexOf( ( *it )->m_trackView->getTrack() ); + Track* tcoTrack = ( *it )->m_trackView->getTrack(); + int trackIndex = tc->tracks().indexOf( tcoTrack ); QDomElement tcoElement = dataFile.createElement( "tco" ); tcoElement.setAttribute( "trackIndex", trackIndex ); + tcoElement.setAttribute( "trackType", tcoTrack->type() ); + tcoElement.setAttribute( "trackName", tcoTrack->name() ); ( *it )->m_tco->saveState( dataFile, tcoElement ); tcoParent.appendChild( tcoElement ); } @@ -621,6 +624,7 @@ DataFile TrackContentObjectView::createTCODataFiles( QDomElement metadata = dataFile.createElement( "copyMetadata" ); // initialTrackIndex is the index of the track that was touched metadata.setAttribute( "initialTrackIndex", initialTrackIndex ); + metadata.setAttribute( "trackContainerId", tc->id() ); // grabbedTCOPos is the pos of the tact containing the TCO we grabbed metadata.setAttribute( "grabbedTCOPos", m_tco->startPosition() ); @@ -1316,7 +1320,7 @@ MidiTime TrackContentWidget::getPosition( int mouseX ) void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee ) { MidiTime tcoPos = MidiTime( getPosition( dee->pos().x() ).getTact(), 0 ); - if( canPasteSelection( tcoPos, dee->mimeData() ) == false ) + if( canPasteSelection( tcoPos, dee ) == false ) { dee->ignore(); } @@ -1335,8 +1339,10 @@ void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee ) * \param tcoPos the position of the TCO slot being pasted on * \param de the DropEvent generated */ -bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * mimeData ) +bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QDropEvent* de ) { + const QMimeData * mimeData = de->mimeData(); + Track * t = getTrack(); QString type = StringPairDrag::decodeMimeKey( mimeData ); QString value = StringPairDrag::decodeMimeValue( mimeData ); @@ -1366,7 +1372,9 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * m const int currentTrackIndex = tracks.indexOf( t ); // Don't paste if we're on the same tact - if( tcoPos == grabbedTCOTact && currentTrackIndex == initialTrackIndex ) + auto sourceTrackContainerId = metadata.attributeNode( "trackContainerId" ).value().toUInt(); + if( de->source() && sourceTrackContainerId == t->trackContainer()->id() && + tcoPos == grabbedTCOTact && currentTrackIndex == initialTrackIndex ) { return false; } @@ -1389,9 +1397,9 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * m } // Track must be of the same type - Track * startTrack = tracks.at( trackIndex ); + auto startTrackType = tcoElement.attributeNode("trackType").value().toInt(); Track * endTrack = tracks.at( finalTrackIndex ); - if( startTrack->type() != endTrack->type() ) + if( startTrackType != endTrack->type() ) { return false; } @@ -1407,7 +1415,7 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * m */ bool TrackContentWidget::pasteSelection( MidiTime tcoPos, QDropEvent * de ) { - if( canPasteSelection( tcoPos, de->mimeData() ) == false ) + if( canPasteSelection( tcoPos, de ) == false ) { return false; } @@ -1478,7 +1486,8 @@ bool TrackContentWidget::pasteSelection( MidiTime tcoPos, QDropEvent * de ) tco->selectViewOnCreate( true ); } //check tco name, if the same as source track name dont copy - if( tco->name() == tracks[trackIndex]->name() ) + QString sourceTrackName = outerTCOElement.attributeNode( "trackName" ).value(); + if( tco->name() == sourceTrackName ) { tco->setName( "" ); } From 79524168b36dd1ecad9adb2585f88cc09bb6abe8 Mon Sep 17 00:00:00 2001 From: tresf Date: Mon, 18 Mar 2019 12:37:07 -0400 Subject: [PATCH 269/445] 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 From ea5cbe6789911ac00292460f66e82628ed614f81 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Mon, 18 Mar 2019 12:41:01 -0400 Subject: [PATCH 270/445] Allow new Zyn bank creation on Linux (#4905) Allow new Zyn bank creation on Linux Closes #4642 --- .../zynaddsubfx/zynaddsubfx/src/Misc/Bank.cpp | 35 +++++++++++++++++-- .../zynaddsubfx/zynaddsubfx/src/Misc/Bank.h | 7 ++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/plugins/zynaddsubfx/zynaddsubfx/src/Misc/Bank.cpp b/plugins/zynaddsubfx/zynaddsubfx/src/Misc/Bank.cpp index 5cb43e4ff..28b69f845 100644 --- a/plugins/zynaddsubfx/zynaddsubfx/src/Misc/Bank.cpp +++ b/plugins/zynaddsubfx/zynaddsubfx/src/Misc/Bank.cpp @@ -188,6 +188,7 @@ void Bank::loadfromslot(unsigned int ninstrument, Part *part) */ int Bank::loadbank(string bankdirname) { + normalizedirsuffix(bankdirname); DIR *dir = opendir(bankdirname.c_str()); clearbank(); @@ -255,9 +256,15 @@ int Bank::newbank(string newbankdirname) string bankdir; bankdir = config.cfg.bankRootDirList[0]; - if(((bankdir[bankdir.size() - 1]) != '/') - && ((bankdir[bankdir.size() - 1]) != '\\')) - bankdir += "/"; + expanddirname(bankdir); + normalizedirsuffix(bankdir); + +// FIXME: Zyn should automatically handle creation of parent directory +#ifdef WIN32 + if(mkdir(bankdir.c_str()) < 0) return -1; +#else + if(mkdir(bankdir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) return -1; +#endif bankdir += newbankdirname; #ifdef WIN32 @@ -355,6 +362,8 @@ void Bank::rescanforbanks() void Bank::scanrootdir(string rootdir) { + expanddirname(rootdir); + DIR *dir = opendir(rootdir.c_str()); if(dir == NULL) return; @@ -472,3 +481,23 @@ Bank::ins_t::ins_t() { info.PADsynth_used = false; } + +void Bank::expanddirname(std::string &dirname) { + if (dirname.empty()) + return; + + // if the directory name starts with a ~ and the $HOME variable is + // defined in the environment, replace ~ by the content of $HOME + if (dirname.at(0) == '~') { + char *home_dirname = getenv("HOME"); + if (home_dirname != NULL) { + dirname = std::string(home_dirname) + dirname.substr(1); + } + } +} + +void Bank::normalizedirsuffix(string &dirname) const { + if(((dirname[dirname.size() - 1]) != '/') + && ((dirname[dirname.size() - 1]) != '\\')) + dirname += "/"; +} diff --git a/plugins/zynaddsubfx/zynaddsubfx/src/Misc/Bank.h b/plugins/zynaddsubfx/zynaddsubfx/src/Misc/Bank.h index e9f56e2fb..a0ae74ce1 100644 --- a/plugins/zynaddsubfx/zynaddsubfx/src/Misc/Bank.h +++ b/plugins/zynaddsubfx/zynaddsubfx/src/Misc/Bank.h @@ -99,6 +99,13 @@ class Bank std::string dirname; void scanrootdir(std::string rootdir); //scans a root dir for banks + + /** Expends ~ prefix in dirname, if any */ + void expanddirname(std::string &dirname); + + /** Ensure that the directory name is suffixed by a + * directory separator */ + void normalizedirsuffix(std::string &dirname) const; }; #endif From f79c2929a5b9baa81279d016341a01bf160eaa3c Mon Sep 17 00:00:00 2001 From: necrashter Date: Tue, 19 Mar 2019 12:06:02 +0300 Subject: [PATCH 271/445] Fix empty editors after closing them and creating a new project (#4891) --- include/Editor.h | 1 + src/gui/editors/Editor.cpp | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/include/Editor.h b/include/Editor.h index 4b9017e9e..c93864439 100644 --- a/include/Editor.h +++ b/include/Editor.h @@ -47,6 +47,7 @@ protected: DropToolBar * addDropToolBar(Qt::ToolBarArea whereToAdd, QString const & windowTitle); DropToolBar * addDropToolBar(QWidget * parent, Qt::ToolBarArea whereToAdd, QString const & windowTitle); + virtual void closeEvent( QCloseEvent * _ce ); protected slots: virtual void play() {} virtual void record() {} diff --git a/src/gui/editors/Editor.cpp b/src/gui/editors/Editor.cpp index bdc3e55d4..9aa81fabb 100644 --- a/src/gui/editors/Editor.cpp +++ b/src/gui/editors/Editor.cpp @@ -32,6 +32,7 @@ #include #include #include +#include void Editor::setPauseIcon(bool displayPauseIcon) @@ -121,8 +122,18 @@ QAction *Editor::playAction() const return m_playAction; } - - +void Editor::closeEvent( QCloseEvent * _ce ) +{ + if( parentWidget() ) + { + parentWidget()->hide(); + } + else + { + hide(); + } + _ce->ignore(); + } DropToolBar::DropToolBar(QWidget* parent) : QToolBar(parent) { @@ -138,3 +149,6 @@ void DropToolBar::dropEvent(QDropEvent* event) { dropped(event); } + + + From 52d1f5588a02cad0adbec46a3ce3435f003402a3 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Fri, 22 Mar 2019 11:20:37 +0100 Subject: [PATCH 272/445] Remove useless include --- include/Plugin.h | 4 ++-- src/core/Plugin.cpp | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/include/Plugin.h b/include/Plugin.h index 31c83c4ba..9a0757c35 100644 --- a/include/Plugin.h +++ b/include/Plugin.h @@ -196,8 +196,8 @@ public: private: - // You can add stuff values mapped by "Key" below - // The defaults are sane, i.e. redirect to sub plugins + // You can add values mapped by "Key" below + // The defaults are sane, i.e. redirect to sub plugin's // supererior descriptor virtual QString additionalFileExtensions(const Key&) const diff --git a/src/core/Plugin.cpp b/src/core/Plugin.cpp index cd1cf8b99..411f6fe58 100644 --- a/src/core/Plugin.cpp +++ b/src/core/Plugin.cpp @@ -22,16 +22,14 @@ * */ +#include "Plugin.h" + #include #include #include #include #include -// comment separator to prevent clang's header sorting -#include "lmmsconfig.h" - -#include "Plugin.h" #include "embed.h" #include "Engine.h" #include "GuiApplication.h" @@ -314,3 +312,4 @@ QDomElement Plugin::Descriptor::SubPluginFeatures::Key::saveXML( } + From 34835811e1877191ac46c34012015c67965e5dc7 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Fri, 22 Mar 2019 20:35:21 +0100 Subject: [PATCH 273/445] Fix invalid display names --- include/Plugin.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/Plugin.h b/include/Plugin.h index 9a0757c35..af42b0f10 100644 --- a/include/Plugin.h +++ b/include/Plugin.h @@ -207,9 +207,7 @@ public: virtual QString displayName(const Key& k) const { - return k.isValid() - ? k.desc->displayName - : k.name; + return k.isValid() ? k.name : QString(); } virtual QString description(const Key& k) const From 032c324dbc592173f94d24f835f8a7fdc8f73879 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 25 Mar 2019 15:30:45 +0900 Subject: [PATCH 274/445] Travis: use carla instead of carla-git Due to some breaking changes in the development branch of Carla, we can't use the package right now. Fortunately, the carla package now points to 2.0 series. So we will use it. See also: https://kx.studio/News/?action=view&url=changes-in-kxstudio-repos-regarding-carla-and-jack2 --- .travis/linux..install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis/linux..install.sh b/.travis/linux..install.sh index a4e0ea1cf..3e86eecfe 100644 --- a/.travis/linux..install.sh +++ b/.travis/linux..install.sh @@ -22,4 +22,4 @@ sudo apt-get install -y $PACKAGES sudo add-apt-repository -y ppa:kxstudio-debian/libs sudo add-apt-repository -y ppa:kxstudio-debian/apps sudo apt-get update -sudo apt-get install -y carla-git +sudo apt-get install -y carla From f18efb470ff96b5531da265f3ad3ddee9b9be311 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 26 Mar 2019 09:54:48 +0900 Subject: [PATCH 275/445] Travis: fix shellcheck warnings for the Debian sid script --- .travis/linux.debian-sid.script.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis/linux.debian-sid.script.sh b/.travis/linux.debian-sid.script.sh index 1c62ce6a4..9b8db416c 100755 --- a/.travis/linux.debian-sid.script.sh +++ b/.travis/linux.debian-sid.script.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash set -e : "${TARGET_ARCH:=amd64}" @@ -60,7 +60,7 @@ sync_version() { esac sed "1 s/@VERSION@/$VERSION/" -i debian/changelog - echo Set Debian version to $VERSION + echo "Set Debian version to $VERSION" } sync_version From 4dce466873b3249c0b1a97f6e3a782062623e065 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 27 Mar 2019 07:05:38 +0900 Subject: [PATCH 276/445] Remove some Qt4 compatibility code --- include/Model.h | 17 ----------------- plugins/VstEffect/VstEffectControls.cpp | 10 ---------- plugins/vestige/vestige.cpp | 10 ---------- plugins/zynaddsubfx/ZynAddSubFx.cpp | 3 --- src/gui/SetupDialog.cpp | 5 ----- 5 files changed, 45 deletions(-) diff --git a/include/Model.h b/include/Model.h index bc9f5c046..b40c21029 100644 --- a/include/Model.h +++ b/include/Model.h @@ -41,10 +41,6 @@ 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() @@ -89,19 +85,6 @@ 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 d92717d37..a0f97ce71 100644 --- a/plugins/VstEffect/VstEffectControls.cpp +++ b/plugins/VstEffect/VstEffectControls.cpp @@ -90,13 +90,8 @@ void VstEffectControls::loadSettings( const QDomElement & _this ) knobFModel[ i ]->setInitValue(LocaleHelper::toFloat(s_dumpValues.at(2))); } -#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 } } @@ -383,13 +378,8 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls * } 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 ); } diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index f4abed916..1d54538b6 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -223,13 +223,8 @@ void vestigeInstrument::loadSettings( const QDomElement & _this ) knobFModel[ i ]->setInitValue(LocaleHelper::toFloat(s_dumpValues.at(2))); } -#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(); @@ -984,13 +979,8 @@ manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrume } 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 ); } diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index fec5b3855..277c22596 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -291,10 +291,7 @@ void ZynAddSubFxInstrument::loadSettings( const QDomElement & _this ) emit settingsChanged(); } -// FIXME: Remove this check in future versions. Slots are public in Qt5+ -#if QT_VERSION >= 0x050000 emit instrumentTrack()->pitchModel()->dataChanged(); -#endif } diff --git a/src/gui/SetupDialog.cpp b/src/gui/SetupDialog.cpp index e8c7d5f82..f2ad13ee9 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -1075,12 +1075,7 @@ void SetupDialog::toggleOneInstrumentTrackWindow( bool _enabled ) void SetupDialog::vstEmbedMethodChanged() { -#if QT_VERSION >= 0x050000 m_vstEmbedMethod = m_vstEmbedComboBox->currentData().toString(); -#else - m_vstEmbedMethod = m_vstEmbedComboBox->itemData( - m_vstEmbedComboBox->currentIndex()).toString(); -#endif m_vstAlwaysOnTopCheckBox->setVisible( m_vstEmbedMethod == "none" ); } From 93ec816d4ca45d1b542a89cfc63c489f66e41498 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Thu, 28 Mar 2019 10:48:01 +0900 Subject: [PATCH 277/445] SetupDialog: fix file dialog not opening for theme directory It was caused by a typo affecting a signal-slot connection. --- 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 f2ad13ee9..5ab9630b2 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -440,7 +440,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : #endif addPathEntry("Themes directory", m_artworkDir, SLOT(setArtworkDir(const QString &)), - SLOT(openArtwortDir()), + SLOT(openArtworkDir()), m_adLineEdit, pathSelectors); pathSelectorLayout->addStretch(); addPathEntry("Background artwork", m_backgroundArtwork, From d52c220a5cd40af37a0c167c1425f89edca991cf Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Thu, 28 Mar 2019 18:57:19 +0100 Subject: [PATCH 278/445] Fix instrument window tab sizes - Fix the instrument window tabs minimum width and height formulae - Also set minimum height and width for instrument tab --- include/InstrumentTrack.h | 3 +++ src/tracks/InstrumentTrack.cpp | 26 ++++++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index fb12e825a..0627e9f4e 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -427,6 +427,9 @@ protected slots: private: virtual void modelChanged(); void viewInstrumentInDirection(int d); + //! adjust size of any child widget of the main tab + //! required to keep the old look when using a variable sized tab widget + void adjustTabSize(QWidget *w); InstrumentTrack * m_track; InstrumentTrackView * m_itv; diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index fb9261ff7..69924c8be 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -1471,17 +1471,11 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : m_tabWidget->addTab( m_effectView, tr( "Effects" ), "fx_tab", 3 ); m_tabWidget->addTab( m_midiView, tr( "MIDI" ), "midi_tab", 4 ); m_tabWidget->addTab( m_miscView, tr( "Miscellaneous" ), "misc_tab", 5 ); - - //! adjust size of any child widget of the main tab - //! required to keep the old look when using a variable sized tab widget - auto adjustSize = [](QWidget *w) { - w->setMinimumSize(INSTRUMENT_WIDTH, INSTRUMENT_HEIGHT + GRAPHIC_TAB_HEIGHT); - }; - adjustSize(m_ssView); - adjustSize(instrumentFunctions); - adjustSize(m_effectView); - adjustSize(m_midiView); - adjustSize(m_miscView); + adjustTabSize(m_ssView); + adjustTabSize(instrumentFunctions); + adjustTabSize(m_effectView); + adjustTabSize(m_midiView); + adjustTabSize(m_miscView); // setup piano-widget m_pianoView = new PianoView( this ); @@ -1497,7 +1491,7 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : resize( sizeHint() ); - QMdiSubWindow * subWin = gui->mainWindow()->addWindowedWidget( this ); + QMdiSubWindow* subWin = gui->mainWindow()->addWindowedWidget( this ); Qt::WindowFlags flags = subWin->windowFlags(); flags |= Qt::MSWindowsFixedSizeDialogHint; flags &= ~Qt::WindowMaximizeButtonHint; @@ -1659,6 +1653,8 @@ void InstrumentTrackWindow::updateInstrumentView() modelChanged(); // Get the instrument window to refresh m_track->dataChanged(); // Get the text on the trackButton to change + + adjustTabSize(m_instrumentView); } } @@ -1846,6 +1842,7 @@ void InstrumentTrackWindow::viewInstrumentInDirection(int d) // scroll the SongEditor/BB-editor to make sure the new trackview label is visible bringToFront->trackContainerView()->scrollToTrackView(bringToFront); } + Q_ASSERT(bringToFront); bringToFront->getInstrumentTrackWindow()->setFocus(); } @@ -1858,4 +1855,9 @@ void InstrumentTrackWindow::viewPrevInstrument() viewInstrumentInDirection(-1); } +void InstrumentTrackWindow::adjustTabSize(QWidget *w) +{ + w->setMinimumSize(INSTRUMENT_WIDTH - 4, INSTRUMENT_HEIGHT - 4); +} + #include "InstrumentTrack.moc" From 3ef33dbbe994141ce3d7c5da7b9d44bcb1fdffb2 Mon Sep 17 00:00:00 2001 From: CYBERDEViLNL Date: Sat, 30 Mar 2019 23:51:56 +0100 Subject: [PATCH 279/445] PluginBrowser: Tree layout and search bar --- include/PluginBrowser.h | 25 +++++--- src/gui/PluginBrowser.cpp | 125 +++++++++++++++++++++++++++++++------- 2 files changed, 119 insertions(+), 31 deletions(-) diff --git a/include/PluginBrowser.h b/include/PluginBrowser.h index f7c46db72..3cc54c6e4 100644 --- a/include/PluginBrowser.h +++ b/include/PluginBrowser.h @@ -31,6 +31,10 @@ #include "SideBarWidget.h" #include "Plugin.h" +class QLineEdit; +class QTreeWidget; +class QTreeWidgetItem; + class PluginBrowser : public SideBarWidget { @@ -39,18 +43,18 @@ public: PluginBrowser( QWidget * _parent ); virtual ~PluginBrowser() = default; +private slots: + void onFilterChanged( const QString & filter ); + private: + void addPlugins(); + void updateRootVisibility( int index ); + void updateRootVisibilities(); + QWidget * m_view; -}; - - - - -class PluginDescList : public QWidget -{ - Q_OBJECT -public: - PluginDescList(QWidget* parent); + QTreeWidget * m_descTree; + QTreeWidgetItem * m_lmmsRoot; + QTreeWidgetItem * m_lv2Root; }; @@ -62,6 +66,7 @@ class PluginDescWidget : public QWidget public: typedef Plugin::Descriptor::SubPluginFeatures::Key PluginKey; PluginDescWidget( const PluginKey & _pk, QWidget * _parent ); + QString name() const; protected: diff --git a/src/gui/PluginBrowser.cpp b/src/gui/PluginBrowser.cpp index 27747bc53..1e73b7cdc 100644 --- a/src/gui/PluginBrowser.cpp +++ b/src/gui/PluginBrowser.cpp @@ -24,11 +24,13 @@ #include "PluginBrowser.h" +#include #include -#include +#include #include -#include +#include #include +#include #include "embed.h" #include "Engine.h" @@ -60,23 +62,91 @@ PluginBrowser::PluginBrowser( QWidget * _parent ) : m_view ); hint->setWordWrap( true ); - QScrollArea* scrollarea = new QScrollArea( m_view ); - PluginDescList* descList = new PluginDescList( m_view ); - scrollarea->setWidget(descList); - scrollarea->setWidgetResizable(true); + QLineEdit * searchBar = new QLineEdit( m_view ); + searchBar->setPlaceholderText( "Search" ); + searchBar->setMaxLength( 64 ); + searchBar->setClearButtonEnabled( true ); - view_layout->addWidget(hint); - view_layout->addWidget(scrollarea); + m_descTree = new QTreeWidget( m_view ); + m_descTree->setColumnCount( 1 ); + m_descTree->header()->setVisible( false ); + m_descTree->setIndentation( 10 ); + m_descTree->setSelectionMode( QAbstractItemView::NoSelection ); + + connect( searchBar, SIGNAL( textEdited( const QString & ) ), + this, SLOT( onFilterChanged( const QString & ) ) ); + + view_layout->addWidget( hint ); + view_layout->addWidget( searchBar ); + view_layout->addWidget( m_descTree ); + + // Add LMMS root to the tree + m_lmmsRoot = new QTreeWidgetItem(); + m_lmmsRoot->setText( 0, "LMMS" ); + m_descTree->insertTopLevelItem( 0, m_lmmsRoot ); + m_lmmsRoot->setExpanded( true ); + + // Add LV2 root to the tree + m_lv2Root = new QTreeWidgetItem(); + m_lv2Root->setText( 0, "LV2" ); + m_descTree->insertTopLevelItem( 1, m_lv2Root ); + + // Add plugins to the tree roots + addPlugins(); + + // Resize + m_descTree->header()->setSectionResizeMode( QHeaderView::ResizeToContents ); + + // Hide empty roots + updateRootVisibilities(); } - - -PluginDescList::PluginDescList(QWidget *parent) : - QWidget(parent) +void PluginBrowser::updateRootVisibility( int rootIndex ) { - QVBoxLayout* layout = new QVBoxLayout(this); + QTreeWidgetItem * root = m_descTree->topLevelItem( rootIndex ); + root->setHidden( !root->childCount() ); +} + +void PluginBrowser::updateRootVisibilities() +{ + int rootCount = m_descTree->topLevelItemCount(); + for (int rootIndex = 0; rootIndex < rootCount; ++rootIndex) + { + updateRootVisibility( rootIndex ); + } +} + + +void PluginBrowser::onFilterChanged( const QString & filter ) +{ + int rootCount = m_descTree->topLevelItemCount(); + for (int rootIndex = 0; rootIndex < rootCount; ++rootIndex) + { + QTreeWidgetItem * root = m_descTree->topLevelItem( rootIndex ); + + int itemCount = root->childCount(); + for (int itemIndex = 0; itemIndex < itemCount; ++itemIndex) + { + QTreeWidgetItem * item = root->child( itemIndex ); + PluginDescWidget * descWidget = static_cast + (m_descTree->itemWidget( item, 0)); + if (descWidget->name().contains(filter, Qt::CaseInsensitive)) + { + item->setHidden( false ); + } + else + { + item->setHidden( true ); + } + } + } +} + + +void PluginBrowser::addPlugins() +{ QList descs = pluginFactory->descriptors(Plugin::Instrument); std::sort( descs.begin(), @@ -93,7 +163,7 @@ PluginDescList::PluginDescList(QWidget *parent) : for (const Plugin::Descriptor* desc: descs) { - if( desc->subPluginFeatures ) + if ( desc->subPluginFeatures ) { desc->subPluginFeatures->listSubPluginKeys( desc, @@ -109,13 +179,18 @@ PluginDescList::PluginDescList(QWidget *parent) : for (const PluginKey& key : pluginKeys) { - PluginDescWidget* p = new PluginDescWidget( key, this ); - p->show(); - layout->addWidget(p); + QTreeWidgetItem * item = new QTreeWidgetItem(); + if ( key.desc->name == QStringLiteral("lv2instrument") ) + { + m_lv2Root->addChild( item ); + } + else + { + m_lmmsRoot->addChild( item ); + } + PluginDescWidget* p = new PluginDescWidget( key, m_descTree ); + m_descTree->setItemWidget( item, 0, p ); } - - setLayout(layout); - layout->addStretch(); } @@ -137,6 +212,14 @@ PluginDescWidget::PluginDescWidget(const PluginKey &_pk, +QString PluginDescWidget::name() const +{ + return m_pluginKey.displayName(); +} + + + + void PluginDescWidget::paintEvent( QPaintEvent * ) { @@ -190,7 +273,7 @@ void PluginDescWidget::leaveEvent( QEvent * _e ) void PluginDescWidget::mousePressEvent( QMouseEvent * _me ) { - if( _me->button() == Qt::LeftButton ) + if ( _me->button() == Qt::LeftButton ) { Engine::setDndPluginKey(&m_pluginKey); new StringPairDrag("instrument", From 82e3ba75c62a9db174e8844893da5901b76e1838 Mon Sep 17 00:00:00 2001 From: Gingka Akiyama <33764485+GingkathFox@users.noreply.github.com> Date: Sat, 6 Apr 2019 09:19:32 -0700 Subject: [PATCH 280/445] [Equalizer] Bright analyzer colors, opacity increased (#4772) * [Equalizer] Bright analyzer colors, opacity incr Brightened spectrum analyzer colors and increased opacity a tad to make more visible * Fixed RGB Value * Update EqControlsDialog.cpp * Fixed color change * Changed colors again * Fixed colors, now brighter and bluer * Ok, its actually bright now lol --- plugins/Eq/EqControlsDialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Eq/EqControlsDialog.cpp b/plugins/Eq/EqControlsDialog.cpp index 826b5e73f..b43faa8a1 100644 --- a/plugins/Eq/EqControlsDialog.cpp +++ b/plugins/Eq/EqControlsDialog.cpp @@ -55,10 +55,10 @@ EqControlsDialog::EqControlsDialog( EqControls *controls ) : EqSpectrumView * inSpec = new EqSpectrumView( &controls->m_inFftBands, this ); inSpec->move( 26, 17 ); - inSpec->setColor( QColor( 54, 45, 142, 150 ) ); + inSpec->setColor( QColor( 77, 101, 242, 150 ) ); EqSpectrumView * outSpec = new EqSpectrumView( &controls->m_outFftBands, this ); - outSpec->setColor( QColor( 9, 166, 156, 150 ) ); + outSpec->setColor( QColor( 0, 255, 239, 150 ) ); outSpec->move( 26, 17 ); m_parameterWidget = new EqParameterWidget( this , controls ); From 07dcea129440d6f34029f0fd5aa82830d9502d45 Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+DouglasDGI@users.noreply.github.com> Date: Sat, 13 Apr 2019 14:26:41 -0600 Subject: [PATCH 281/445] Replace Monstro icons --- plugins/monstro/exp.png | Bin 522 -> 539 bytes plugins/monstro/moog.png | Bin 599 -> 498 bytes plugins/monstro/noise.png | Bin 563 -> 711 bytes plugins/monstro/ramp.png | Bin 520 -> 443 bytes plugins/monstro/saw.png | Bin 529 -> 489 bytes plugins/monstro/sin.png | Bin 578 -> 596 bytes plugins/monstro/sinabs.png | Bin 468 -> 530 bytes plugins/monstro/sqr.png | Bin 427 -> 345 bytes plugins/monstro/sqrsoft.png | Bin 539 -> 453 bytes plugins/monstro/tri.png | Bin 602 -> 566 bytes 10 files changed, 0 insertions(+), 0 deletions(-) diff --git a/plugins/monstro/exp.png b/plugins/monstro/exp.png index 9fe634881a8d4c47b380b1963604c840b40a623f..acb7a55cbc2671ed17d4cb0e8ae080028f1160a2 100644 GIT binary patch literal 539 zcmV+$0_6RPP)AHt5#EFVf5n0=;+-!GkA{9z&r^f&L9)_o9nLkQOoK2y##( z1Vt#AKgRbU2x^Bdx9^?~wb*2neW~a4Ja3-Y^M2srf&U(=VsARt(VTO3Rhwxi-pL)r z5q!XaXV~EH1rU(L8z<-q1~b^mdV6ZuJ;9dftwvrEU(^%qDzU$VdWd^-R;HTD`(4BK zhf*5Du&NXRq|VH}*Lwq9!5T1gzfbMHRMmGFEcaUfLOWPmT(hM##$*7><@0DL7>d=^ zS_j}lZs#8i?sjxm%X$n@N1tp@#*3fEhc-Z00o2d))Xs5#TiDJz&qOti%J)zv{IsF_ zrS=Hbf{2clPpWHUua5d!*0yubBCw2#i{&Qs$s1eE4vCLW#H#CiL1I8&+@BA((l__b z-K?_&ECaZvI(r!e_>v4CUT9?+)dFCigP)e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00DAIL_t(2&z+DzOI%SD#D8<| zeJ<>3wDB3N6wIa(QdPH-TTJE z^$)T(p5}0dGiTEmyj!;+TFXJ8AskT{N!uQ?NdWx*EaZ!S6L{NXC)%ohUhF{_9sW9@ZOo^U_>c$u2(B@Z5$C`T4R%`vy>Ey7Zx!@tunX)U&Ly(Jw{hTwGnzPHT>t<8 M07*qoM6N<$g8hfkK>z>% diff --git a/plugins/monstro/moog.png b/plugins/monstro/moog.png index 6d9005966f448c6da2cd4003fc4f06d6c4e2af7e..f206bd0da044290a77383c72779c5c414d340b26 100644 GIT binary patch literal 498 zcmVpP^PU6$`RsJX4)30IxMk)iSo}_+Rp#>oM>FLm6{cI| zEt|tfcU>5gUc+0$&)w}Qg&r^1RXda}Mu6x~`*3YmztzxHss9NMW{N8!I;Q9iIKPKO zXAc3(ND@HaH1;QLwW=wQPE_`Dk-)*PVLMZr6e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00F;AL_t(2&vnp0Z;f#j2k_5% zp66cGmXHvGGWZk!a;Hi}B0|C-NJR7%SWFVH0PlcJ;vKk46Tx6022)KmmZk>8U_i80 zz4!SYLxl>y<4Haz-*dv6OwMGze$1veTn{ei>iBM5x!LUXX*oj?lx7aj7SHh z(O@akt1O0F*DU{qrurhj>t;F~VNZr{nHEuoU8(;MG(RPhb-@8_305L3XDAl^kp|qz zXy!E0+KnC}`Ho?vIl7LXYf9FhxTX9+KB4o)Ee}0t7;{TCdXs-o|!CeB@cq_5iZsP`8#3?<)KYSFKc8*)#)0SPN0{}C?3VQ#dQllDegpgfD0vEEnjUs zGpDXfIwwrxW$>(!&dUAW?-IgKdX)OSb-TwtSF*0)jqY*$<>f`z1&c8z9qs2?r=R~#` z*NCM-T32K4yF1waY^tVf`179MAj!ueY|%_Jre!E6y=yU5|7!JAvIwJ&Yi zPv_S`9MW%Q*WxdV^#C2CvquH4Bi0Cj*f#)ty)4SE@|$P{(l$~|i_i_=MS~uIk_2}E z)bv0oOQ!)Wa2>1fJp46?M67>Jlk~J@KORz*G=NpYdFMY&p5Q9|$mN-D3-n8YM-ST3~V zMKzfz91*i5CWVPq(|}Wduu8#GOukn9>r!Dn)wDmC+Utu-uH5W89ZR*mcVfL*&sp~4`6~#bT&^`1}v}zfB=p9025uYC+j9q85B5{JKda5WM+PrdoYVg zrN=8;TJYG0V$n^>&UE002ovPDHLkV1i(}F8Tlf literal 563 zcmV-30?hr1P)e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00EmxL_t(2&ppw-Zd_Fq#qr-h z_s$IC4>^`i5vAb;Kp;^eA)&kjrCS;v$&V7cbdgY`G?9|HM8L=b#t?h%$DB=vJOfBeT2UBN~TNnQpK?1$)9hnzWb275_};Yp(fi%r>Zk_ z5+Q^iYUj;d{9$t43l~^o2)Fdh=n1z>t%`#}?Bzd5aLS{%riF1B#Zfaf$kjuajkYAo! zl$xTDRH@+Z7pm`*nO9mdC$RY&0|TRsr;B5V#`&Y?>^+zgWsZG(|9hTUYIdXE*<9D_ zj)EzNc^xNT2{UnxHVKQiaEms%m6cq7K+%U^$-pUUQK03N7BfZD_kXuu`8Ut|{5Kx? zABXnmZo70t;_9mu1 z=B)fk_mCwmvE~`EQOOOrvVPrinb?0J^w6~E+}OzEhA6Y*{I*BTvaFWdFYTLIJ#C5T zKi!Hq*0u5(8mifT+he14{GPMn5X0A_FMnMRsA(}@8aeUG0+Zs~GdCS#Sby`&?w6hY iC%T0`9t&<3I>2w`k#~xF+qZU57<#(;xvX6vrPa102y>e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00D4GL_t(2&vnwhOVx1{$MM(s z-m8fZA+=^xL+DrzZmprAi|x@=5R_|6YXlNS1pNyxMx_u$e}QdMLtD@iSw8E1_?-s5 zSb6W6&zsLV?{i}6b1p`>1=6dmJZ|jUT)P@=J*q_bj>M=i8O2buPfcd@gs_7j*pwzS z+#MY@a{a3s-NAx(rUo{J4QaY{=*D)#(8RjZ4J;5LlWn|@5LrB^in;S=40i*I`3w0b!xpGJ7rzUi;`YXGMo&TeJ6ssos15p(EJ@!mQ_6|a(&K)) zv1_ld?ll%2>AT-C+8tVAeO&eP&`zl=Cr^)6Ei_wZdnFN(>l3Pxe!ErWO{RAl#)6x@ zp(8R^FKM^-Y^i%5e86-;1MSW`WnDEfFaJ(lyQ0-7er0%qhkpP>51QPMrc!7C0000< KMNUMnLSTYBVbo0k diff --git a/plugins/monstro/saw.png b/plugins/monstro/saw.png index 56c077f2c529fea4f55046656dcc36e66c5bc71c..3122b082f8dbabcfde52d71584a8ec3712f45fab 100644 GIT binary patch literal 489 zcmVfBv=d#2GYbp#6Tn_i9sSUh{PaeqDe{G zPA?S$yU+AtHM{p15MQmnXK}Z4@A)O?o^yczI`kLRc5oR9)gU5*!mh)srf_X24FEC- zv@cF&1z_l-I z=ZgKPLYkPu(0a>_*AIMtFN>r3+d+W#0RYVFZlZDYdrnDgXCKB4mOB6dg;h7+Fi|S+ z2ae|MCP8`=0HCqxI_7k_>cm%AoH1amy@j)G!kqi9C*tFe#d!m?0sxvZ<@T6Ml_ntp zAeO&h7R<@l=3u-KH#hvuU&gYJLxNQj0JKuW1;^Ue zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00DVPL_t(2&xMh_YE)qmhM#xN zmo;XSxL|9nEF=pyA&8x=Bq3?yB?tV$LR*<;hlL#{HJE#xo8~cgo0a$D*$mMVXHqvp`eMF1zLcQfUHX&C|cu8 zSX{%*0zZH+=`f((A-W~aEEW)Rh|OU*WgG^aJjQqqmK@xa5b(;-mGHi#i*M0DjP)xP zB~}DD^H70g&RhSAxNW7=GzM^1unbHA>nT{r?4sdVs++p-nY7!ZMR3(-UgEI}?)NKp zLgc@rQ8$&lOlET(Sdw@_<`E^|M@OmZ3q{>j1Pj1C=96Ky7-QqqH093L-n*l2N^k=( zaCao}baR{DpMEbinP~Pa7J(H&hI^5D^7R*6ooOLs>jclXBZ4a53XdhCh^STbs2nnKSNbdXfNZB8)TbOVgT?P^azou T!DIAa00000NkvXXu0mjfI`-7i diff --git a/plugins/monstro/sin.png b/plugins/monstro/sin.png index acabd5a171a9fc5ccefec61c360de9c09629563b..3ac3c9afa238aec201672993437ba6406c79a551 100644 GIT binary patch literal 596 zcmV-a0;~OrP)6+beFTQ+BPvC_e&4mI^- zv>??WeWODZ#DZgo4k9r|$# z=jH$~dvB)I#@Uf-8tedc*TxN;n=>#oz92Gz%iNhGY#2lq|_p!)b#rSKLYu&w(5B62zv_V{A=y#7aAu8h4ibX!Dk5EtRC4E3 zew9|rhZo`(e8-vq1Tq%aPu9bG7!RfvTh|=GN_q6dKP_ck1e@!D1K~iFj{oYC{}GWL_4#}|6<$75tf5-Nqyz4fi0o6e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00F8=L_t(2&u!65i;V#o2k_tX zzVA7VTP~e(X`(EI5xHcc>{y76Vj~~H);GY1VK1|h`$FV4LXk`oGiB1rQiZAR{9SdCIrJ=`DtfA^hyo6WkenX*~z6=7S1)tUAL6T*{X z`L}zsGDjM**bC#y?qEkQ9_+_TG)Fa1;~l&7|ZWTwZ_xSf6dzs?7?(f_%- QUjP6A07*qoM6N<$f=v?tU;qFB diff --git a/plugins/monstro/sinabs.png b/plugins/monstro/sinabs.png index 2216224e69d09e64184be0033f77821712ea0c58..e28d1ec21d4a3b3ef6ed2c7e26f5acbfdc9220ac 100644 GIT binary patch literal 530 zcmV+t0`2{YP)Wzp=8_llFDr zOHHrePhI|e>J8xfi-Swy!r=n$RRE+NDbyO%rCNDo?yWb5F+rVQVU)vhN>=8haCK{E(V2afYJeZyU z$gTSB*3fN0l(PUdo>f``G-pJ6F{t!r7V+o2>ou{99#xyOkLRyu!|}7 zE*tTbbf}eo@3e@wmElbh{37MC04d&VzhvKAjsDDg_w1Y`47f*D z1aMi~;~@Lm+Q(tuC*oK3OVsa@6#x{sPxeSJ0W1mY{ENx@mr?$Ma((|H=bR<}0-%(L UDvD>tcK`qY07*qoM6N<$g6{q6e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00BHnL_t(2&+W{=YEy9-fZ^vm z`I(p@LQ}y%xC&MfD+LEZbP)%q&h}CqI&|)R=p6_SwnOcp1dDXlEZSzULnTd4a?a(49qBkbTornl0zupQw!MwwpqTA$A^TvTPKUl*GZcCn7{II8I2 z=x?t_*sY7rGSn}nb|u-u!(=Zw5q2_c;SOFWli-Q;vTD35$&2I$zTizF(!Jz%aGYTu zlGWg*#1(WFb+J=b6DFUZ$$G1qSF%ecW zT`R#V&N7{-)EX70`R6{>T4YBXtsl}^gsYV_&$J&L^cu5X*GxE!@Jl%Cb89rc7 zTEyey9Jr+IPc7=7mYz~R>7MtL!Q67Wq4u8cP^m8~^QH9PKllx$f`URePxCGS0000< KMNUMnLSTYeH^UwP diff --git a/plugins/monstro/sqr.png b/plugins/monstro/sqr.png index 83d5e4869038b5d02b01cf876afb598e62036928..d5d3c211c6e109e02863df08a81c1f60ac721135 100644 GIT binary patch literal 345 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+o!3HFmxV|j}Qfx`y?k)`fL2$v|<&%LToCO|{ z#S9GG!XV7ZFl&wkP>{XE)7O>#F$*sPy9i(De{GT_i(`nz>Er|njRP5VFDBY6x~ji@VwNPFp7`gm z(*OCbiAs9C|Nk4`Nl!>PuugJaN8>}e!~g$Jf9RK#^dRZS`4?U1T?@|k{QsYCnW;aQ z|MBa$H49Ii{P|wa?yS!gmKz5$(<~pVn4Zk}pRD+7KF{Qit0~+57cvVAA66A(V`FOz z?%TwBB+KMhv48)>nLGd4Ge2IsP%5D%_K|E^c|Vd;Ir8L`7~m+2du4sipy zW6=|L7__l;ZvMdWO2v)$aCQCe1fIhWoK}>UhL)BdzxaGrL8}&1D@T0S_1c$@e@_on z;xdYOu%<#gRZpuV%Yn>SAU@e{pYL05`Z_f9U(|(dcdcec-M`~-CHMC3;HUr1 zxBNE0Vc%9)BjB~@=+parN1M&8Rut5q?LW)@{Y~)Jz0W)!OSGr%EsQb$$E+?KWp-8Z S`F~&-GI+ZBxvXrkk diff --git a/plugins/monstro/sqrsoft.png b/plugins/monstro/sqrsoft.png index 2e5626d20538b8aaca92137852baa9687602a89b..037fcab12bf443e946f6682723d10159b1d5adf8 100644 GIT binary patch literal 453 zcmV;$0XqJPP)^!sl=%!CVuPt=E?i#c|;52XW@b$86P0Bgq4}}1wSBwOfg)M@wOzAU(2ri z@vilo*;FY`zz4u+RU&EO&^WyUI7OqvWIf-m0kHzg9zCY&3BL-eT}>y`t;OJ^`YfY9 zr?=tj+~D1J0;cVL(gT3!x_je#48P=$3IwOM<)9cA0Q~aYK&|PAj*;7x=M4p=``v$k z#Dsun9?diQCIuYNYK1m8t%HMRubx>O68wlJekQi0a#P v`o78IFkSb$#yl7GM8>&Fap!e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00DzZL_t(2&yCW*YE)qmhVkEg z=j^T_0f~(kk@zQ|g4ie`R)UQ}3L9_0I}ij@T8Y?r2e}8a(9*_En;=9a5ReEKN)V#U z?%8w3W`mo=!grWvhKG4)n7FZ-XM;x(Rx!vl!mFyy^%USsY)F*~V5_#$iz?=yU>(wk}Tvhc9! zS=ifB4nW9hw54b#J)IO1sZ@>HAss3FOT!&x#w-*Fq10nBi9-wY7%r)R??#U+s*Z$hJiXG*Udk^%DvyT6g0r=!Iy}yAHt&nbRm|RFvIk80o6W~V zVbAjdfJj`;JgWjY^~(Rnx%I;wCO5%OZNdxp<}=ShJ_vH%ZyY@wh|^oN zw*m3#P)WvXpVFuV-7bY^+q(;wL&H7_dLv)&-0O>Ha^nGT-W>JaV&u4F^FDkK))z?h91poj507*qoM6N<$ Eg8o4HO#lD@ literal 602 zcmV-g0;Te zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00F{DL_t(2&t1|zOO*i_#_`|% zc+PX|&`^S#6i&Wy93r97MaZG`nWC)^qFU(mzd|FK&(uagQ#+ae z6&lr|xY^!9`;{mzl)_wu`}i5*zA#r@DEF)Xq0E@v(}==srjC@!fs~m#QJ9_F(~udr zP}LR9OHH98JP=NTo^W#AJIzbYs_PocjMHhwFtn4ENK4p?@CsXzmXeiWXrE4B?Te}_ zhErM!Ytpi?gUuZKj!j`lT2@#aPH9zLQS4VjTPs-*X7DA`=ZSEZ=`+3vGs%Ls)_x_5 z$vq8Yvq1-vo~DEId-|FVk{$#d<0~P>tpFZM$H8u#8Th7-GlO7PI>y5rA;q}iuC#(B zVN30O`NLrQvAX;#)-I-fpOi^%Cyb(zkCP5ufgTq&KwQKsH# z!l+wG=vHzxVU($dqX;w7Vj-*sC64NJ*q<{NSH~2Q{W;@09ZE+@DLidR?=TiVX!^aq oq4rO Date: Sat, 13 Apr 2019 14:30:46 -0600 Subject: [PATCH 282/445] Shrink ComboBox arrow section slightly This is being done for two reasons: 1. The new Monstro icons (and the icons for Microwave when it's finished) are too large. 2. All ComboBoxes (subjectively) look much nicer this way. --- src/gui/widgets/ComboBox.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gui/widgets/ComboBox.cpp b/src/gui/widgets/ComboBox.cpp index 0673ee32d..c796bfa74 100644 --- a/src/gui/widgets/ComboBox.cpp +++ b/src/gui/widgets/ComboBox.cpp @@ -42,7 +42,7 @@ QPixmap * ComboBox::s_background = NULL; QPixmap * ComboBox::s_arrow = NULL; QPixmap * ComboBox::s_arrowSelected = NULL; -const int CB_ARROW_BTN_WIDTH = 20; +const int CB_ARROW_BTN_WIDTH = 18; ComboBox::ComboBox( QWidget * _parent, const QString & _name ) : @@ -198,7 +198,7 @@ void ComboBox::paintEvent( QPaintEvent * _pe ) QPixmap * arrow = m_pressed ? s_arrowSelected : s_arrow; - p.drawPixmap( width() - CB_ARROW_BTN_WIDTH + 5, 4, *arrow ); + p.drawPixmap( width() - CB_ARROW_BTN_WIDTH + 3, 4, *arrow ); if( model() && model()->size() > 0 ) { @@ -251,4 +251,3 @@ void ComboBox::setItem( QAction* item ) - From 91f9f1a890f529779931501d7f571de9cec54226 Mon Sep 17 00:00:00 2001 From: Noah Brecht Date: Sun, 14 Apr 2019 06:26:49 -0400 Subject: [PATCH 283/445] Don't try to connect to nonexistent controllers (#4939) Fixes crash on loading presets with controllers. --- src/core/ControllerConnection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ControllerConnection.cpp b/src/core/ControllerConnection.cpp index 45e36e12f..4d43a4366 100644 --- a/src/core/ControllerConnection.cpp +++ b/src/core/ControllerConnection.cpp @@ -205,7 +205,7 @@ void ControllerConnection::loadSettings( const QDomElement & _this ) else { m_controllerId = _this.attribute( "id", "-1" ).toInt(); - if( m_controllerId < 0 ) + if( m_controllerId < 0 || m_controllerId >= Engine::getSong()->controllers().size() ) { qWarning( "controller index invalid\n" ); m_controllerId = -1; From 5a56969af2dbc8729070729ecbd3d522c2344c5f Mon Sep 17 00:00:00 2001 From: Spekular Date: Mon, 15 Apr 2019 17:54:18 +0200 Subject: [PATCH 284/445] Allow sample track TCOs to resize smaller than one bar (#4933) Other changes: * Update TCO position more exact when a drag leaves a TCO and enters `TrackContentWidget` (required to detect that the cursor has really moved when leaving a TCO with length < 1 to the right) * Use exact length when samples are loaded, don't round it up * Reset size when reloading same file --- src/core/Track.cpp | 22 ++++++++++---------- src/tracks/SampleTrack.cpp | 41 ++++++++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index cd1d23b16..4cec5a4ee 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -310,8 +310,8 @@ TrackContentObjectView::~TrackContentObjectView() /*! \brief Update a TrackContentObjectView * - * TCO's get drawn only when needed, - * and when a TCO is updated, + * TCO's get drawn only when needed, + * and when a TCO is updated, * it needs to be redrawn. * */ @@ -678,7 +678,7 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) } } } - else if( me->button() == Qt::LeftButton && + else if( me->button() == Qt::LeftButton && me->modifiers() & Qt::ControlModifier ) { // start drag-action @@ -1123,7 +1123,7 @@ void TrackContentWidget::updateBackground() // draw lines // vertical lines - pmp.setPen( QPen( gridColor(), 1 ) ); + pmp.setPen( QPen( gridColor(), 1 ) ); for( float x = 0; x < w * 2; x += ppt ) { pmp.drawLine( QLineF( x, 0.0, x, h ) ); @@ -1134,9 +1134,9 @@ void TrackContentWidget::updateBackground() { pmp.drawLine( QLineF( x, 0.0, x, h ) ); } - + // horizontal line - pmp.setPen( QPen( gridColor(), 1 ) ); + pmp.setPen( QPen( gridColor(), 1 ) ); pmp.drawLine( 0, h-1, w*2, h-1 ); pmp.end(); @@ -1319,7 +1319,7 @@ MidiTime TrackContentWidget::getPosition( int mouseX ) */ void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee ) { - MidiTime tcoPos = MidiTime( getPosition( dee->pos().x() ).getTact(), 0 ); + MidiTime tcoPos = getPosition( dee->pos().x() ); if( canPasteSelection( tcoPos, dee ) == false ) { dee->ignore(); @@ -1862,7 +1862,7 @@ void TrackOperationsWidget::updateMenu() toMenu->addAction( embed::getIconPixmap( "cancel", 16, 16 ), tr( "Remove this track" ), this, SLOT( removeTrack() ) ); - + if( ! m_trackView->trackContainerView()->fixedTCOs() ) { toMenu->addAction( tr( "Clear this track" ), this, SLOT( clearTrack() ) ); @@ -2787,12 +2787,12 @@ void TrackView::mouseMoveEvent( QMouseEvent * me ) else if( m_action == MoveTrack ) { // look which track-widget the mouse-cursor is over - const int yPos = + const int yPos = m_trackContainerView->contentWidget()->mapFromGlobal( me->globalPos() ).y(); const TrackView * trackAtY = m_trackContainerView->trackViewAt( yPos ); -// debug code -// qDebug( "y position %d", yPos ); + // debug code + // qDebug( "y position %d", yPos ); // a track-widget not equal to ourself? if( trackAtY != NULL && trackAtY != this ) diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index fd9a92a23..0a5fabd1a 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -106,7 +106,7 @@ SampleTCO::SampleTCO( Track * _track ) : SampleTCO::~SampleTCO() { SampleTrack * sampletrack = dynamic_cast( getTrack() ); - if( sampletrack) + if ( sampletrack ) { sampletrack->updateTcos(); } @@ -118,10 +118,7 @@ SampleTCO::~SampleTCO() void SampleTCO::changeLength( const MidiTime & _length ) { - float nom = Engine::getSong()->getTimeSigModel().getNumerator(); - float den = Engine::getSong()->getTimeSigModel().getDenominator(); - int ticksPerTact = DefaultTicksPerTact * ( nom / den ); - TrackContentObject::changeLength( qMax( static_cast( _length ), ticksPerTact ) ); + TrackContentObject::changeLength( qMax( static_cast( _length ), 1 ) ); } @@ -147,8 +144,19 @@ void SampleTCO::setSampleBuffer( SampleBuffer* sb ) void SampleTCO::setSampleFile( const QString & _sf ) { - m_sampleBuffer->setAudioFile( _sf ); - changeLength( (int) ( m_sampleBuffer->frames() / Engine::framesPerTick() ) ); + int length; + if ( _sf.isEmpty() ) + { //When creating an empty sample pattern make it a bar long + float nom = Engine::getSong()->getTimeSigModel().getNumerator(); + float den = Engine::getSong()->getTimeSigModel().getDenominator(); + length = DefaultTicksPerTact * ( nom / den ); + } + else + { //Otherwise set it to the sample's length + m_sampleBuffer->setAudioFile( _sf ); + length = sampleLength(); + } + changeLength(length); emit sampleChanged(); emit playbackPositionChanged(); @@ -440,8 +448,15 @@ void SampleTCOView::mouseReleaseEvent(QMouseEvent *_me) void SampleTCOView::mouseDoubleClickEvent( QMouseEvent * ) { QString af = m_tco->m_sampleBuffer->openAudioFile(); - if( af != "" && af != m_tco->m_sampleBuffer->audioFile() ) - { + + if ( af.isEmpty() ) {} //Don't do anything if no file is loaded + else if ( af == m_tco->m_sampleBuffer->audioFile() ) + { //Instead of reloading the existing file, just reset the size + int length = (int) ( m_tco->m_sampleBuffer->frames() / Engine::framesPerTick() ); + m_tco->changeLength(length); + } + else + { //Otherwise load the new file as ususal m_tco->setSampleFile( af ); Engine::getSong()->setModified(); } @@ -462,7 +477,7 @@ void SampleTCOView::paintEvent( QPaintEvent * pe ) setNeedsUpdate( false ); - m_paintPixmap = m_paintPixmap.isNull() == true || m_paintPixmap.size() != size() + m_paintPixmap = m_paintPixmap.isNull() == true || m_paintPixmap.size() != size() ? QPixmap( size() ) : m_paintPixmap; QPainter p( &m_paintPixmap ); @@ -472,7 +487,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 ) ); @@ -511,7 +526,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 @@ -527,7 +542,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() ) { From 5784dd6dc9483535c2290407d4e417a4b5ad8bd6 Mon Sep 17 00:00:00 2001 From: "https://gitlab.com/users/CYBERDEViLNL" <1148379+CYBERDEViLNL@users.noreply.github.com> Date: Mon, 15 Apr 2019 23:37:20 +0200 Subject: [PATCH 285/445] Use local cursor for TrackContentObjectView (#4918) Fixes crash on cloning patterns on Qt >= 5.12. --- src/core/Track.cpp | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 4cec5a4ee..63893c6a4 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -570,9 +570,9 @@ void TrackContentObjectView::dropEvent( QDropEvent * de ) */ void TrackContentObjectView::leaveEvent( QEvent * e ) { - while( QApplication::overrideCursor() != NULL ) + if( cursor().shape() != Qt::BitmapCursor ) { - QApplication::restoreOverrideCursor(); + setCursor( QCursor( embed::getIconPixmap( "hand" ), 3, 3 ) ); } if( e != NULL ) { @@ -707,8 +707,7 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) if( me->x() < width() - RESIZE_GRIP_WIDTH ) { m_action = Move; - QCursor c( Qt::SizeAllCursor ); - QApplication::setOverrideCursor( c ); + setCursor( Qt::SizeAllCursor ); delete m_hint; m_hint = TextFloat::displayMessage( tr( "Hint" ), tr( "Press <%1> and drag to make " @@ -729,8 +728,7 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) else if( !m_tco->getAutoResize() ) { m_action = Resize; - QCursor c( Qt::SizeHorCursor ); - QApplication::setOverrideCursor( c ); + setCursor( Qt::SizeHorCursor ); delete m_hint; m_hint = TextFloat::displayMessage( tr( "Hint" ), tr( "Press <%1> for free " @@ -932,17 +930,7 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) { if( me->x() > width() - RESIZE_GRIP_WIDTH && !me->buttons() && !m_tco->getAutoResize() ) { - if( QApplication::overrideCursor() != NULL && - QApplication::overrideCursor()->shape() != - Qt::SizeHorCursor ) - { - while( QApplication::overrideCursor() != NULL ) - { - QApplication::restoreOverrideCursor(); - } - } - QCursor c( Qt::SizeHorCursor ); - QApplication::setOverrideCursor( c ); + setCursor( Qt::SizeHorCursor ); } else { From 96cc5e0e5e9ae1277108622020b54ec1d63dd356 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz <1042576+JohannesLorenz@users.noreply.github.com> Date: Wed, 17 Apr 2019 19:08:59 +0200 Subject: [PATCH 286/445] Add PluginIssue class (#4901) --- include/PluginIssue.h | 66 ++++++++++++++++++++++++++++++++++++ src/core/CMakeLists.txt | 1 + src/core/PluginIssue.cpp | 72 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 include/PluginIssue.h create mode 100644 src/core/PluginIssue.cpp diff --git a/include/PluginIssue.h b/include/PluginIssue.h new file mode 100644 index 000000000..c00945805 --- /dev/null +++ b/include/PluginIssue.h @@ -0,0 +1,66 @@ +/* + * PluginIssue.h - PluginIssue class + * + * Copyright (c) 2019 Johannes Lorenz + * + * 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 PLUGINISSUE_H +#define PLUGINISSUE_H + +#include +#include + +//! Types of issues that can cause LMMS to not load a plugin +//! LMMS Plugins should use this to indicate errors +enum PluginIssueType +{ + unknownPortFlow, + unknownPortType, + tooManyInputChannels, + tooManyOutputChannels, + noOutputChannel, + portHasNoDef, + portHasNoMin, + portHasNoMax, + featureNotSupported, //!< plugin requires functionality LMMS can't offer + badPortType, //!< port type not supported + noIssue +}; + +//! Issue type bundled with informational string +class PluginIssue +{ + static const char* msgFor(const PluginIssueType& it); + + PluginIssueType m_issueType; + std::string m_info; + +public: + PluginIssue(PluginIssueType it, std::string msg = std::string()) + : m_issueType(it), m_info(msg) + { + } + friend QDebug operator<<(QDebug stream, const PluginIssue& iss); +}; + +QDebug operator<<(QDebug stream, const PluginIssue& iss); + +#endif // PLUGINISSUE_H diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 7870415f9..cc8bfd34c 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -48,6 +48,7 @@ set(LMMS_SRCS core/Piano.cpp core/PlayHandle.cpp core/Plugin.cpp + core/PluginIssue.cpp core/PluginFactory.cpp core/PresetPreviewPlayHandle.cpp core/ProjectJournal.cpp diff --git a/src/core/PluginIssue.cpp b/src/core/PluginIssue.cpp new file mode 100644 index 000000000..4a8b2ee5b --- /dev/null +++ b/src/core/PluginIssue.cpp @@ -0,0 +1,72 @@ +/* + * PluginIssue.h - PluginIssue class + * + * Copyright (c) 2019 Johannes Lorenz + * + * This file is part of LMMS - https://lmms.io + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include + +#include "PluginIssue.h" + +const char *PluginIssue::msgFor(const PluginIssueType &it) +{ + switch (it) + { + case unknownPortFlow: + return "unknown port flow for mandatory port"; + case unknownPortType: + return "unknown port type for mandatory port"; + case tooManyInputChannels: + return "too many audio input channels"; + case tooManyOutputChannels: + return "too many audio output channels"; + case noOutputChannel: + return "no audio output channel"; + case portHasNoDef: + return "port is missing default value"; + case portHasNoMin: + return "port is missing min value"; + case portHasNoMax: + return "port is missing max value"; + case featureNotSupported: + return "required feature not supported"; + case badPortType: + return "unsupported port type"; + case noIssue: + return nullptr; + } + return nullptr; +} + + + + +QDebug operator<<(QDebug stream, const PluginIssue &iss) +{ + stream << PluginIssue::msgFor(iss.m_issueType); + if (iss.m_info.length()) + { + stream.nospace() << ": " << iss.m_info.c_str(); + } + return stream; +} + + From d06f5088a152f3bb228050f8fe25673332ce66fd Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 20 Apr 2019 13:09:49 +0200 Subject: [PATCH 287/445] Move macro definition out of class --- include/AutomatableModel.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h index f5215676e..a92bd5191 100644 --- a/include/AutomatableModel.h +++ b/include/AutomatableModel.h @@ -60,6 +60,11 @@ modelname.setValue( (float) val ); \ } +// use this to make subclasses visitable +#define MODEL_IS_VISITABLE \ + void accept(ModelVisitor& v) override { v.visit(*this); } \ + void accept(ConstModelVisitor& v) const override { v.visit(*this); } + class ControllerConnection; @@ -85,10 +90,6 @@ public: // Implement those by using the MODEL_IS_VISITABLE macro virtual void accept(ModelVisitor& v) = 0; virtual void accept(ConstModelVisitor& v) const = 0; - // use this to make subclasses visitable -#define MODEL_IS_VISITABLE \ - void accept(ModelVisitor& v) override { v.visit(*this); } \ - void accept(ConstModelVisitor& v) const override { v.visit(*this); } public: //! Return this class casted to Target, or nullptr if impossible From 91099e28d56bdb0ddf4c37da6a23582f92b52db1 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 20 Apr 2019 13:23:42 +0200 Subject: [PATCH 288/445] Fix -1 offset in plugin tab In the instrument plugin tab, there was an orange stripe for TripleOscillator. This was because internally, TabWidget moves up the widget by 1 (TabWidget.cpp, line 89). The size of the whole window is: ``` widget->height() + m_tabbarHeight - 1 ``` So this code adds an offset of "-1" to the necessary computations. --- src/gui/widgets/TabWidget.cpp | 5 ++++- src/tracks/InstrumentTrack.cpp | 10 ++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/gui/widgets/TabWidget.cpp b/src/gui/widgets/TabWidget.cpp index 49898a3c7..6049ce6cb 100644 --- a/src/gui/widgets/TabWidget.cpp +++ b/src/gui/widgets/TabWidget.cpp @@ -321,7 +321,10 @@ QSize TabWidget::minimumSizeHint() const maxWidth = std::max(maxWidth, it->w->width()); maxHeight = std::max(maxHeight, it->w->height()); } - return QSize(maxWidth + 4, maxHeight + m_tabbarHeight); + // "-1" : + // in "addTab", under "Position tab's window", the widget is + // moved up by 1 pixel + return QSize(maxWidth + 4, maxHeight + m_tabbarHeight - 1); } else { return QWidget::minimumSizeHint(); diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 69924c8be..5466dd806 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -1439,7 +1439,10 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : m_tabWidget = new TabWidget( "", this, true, true ); - m_tabWidget->setMinimumHeight( INSTRUMENT_HEIGHT + GRAPHIC_TAB_HEIGHT - 4 ); + // "-1" : + // in "TabWidget::addTab", under "Position tab's window", the widget is + // moved up by 1 pixel + m_tabWidget->setMinimumHeight( INSTRUMENT_HEIGHT + GRAPHIC_TAB_HEIGHT - 4 - 1 ); // create tab-widgets @@ -1857,7 +1860,10 @@ void InstrumentTrackWindow::viewPrevInstrument() void InstrumentTrackWindow::adjustTabSize(QWidget *w) { - w->setMinimumSize(INSTRUMENT_WIDTH - 4, INSTRUMENT_HEIGHT - 4); + // "-1" : + // in "TabWidget::addTab", under "Position tab's window", the widget is + // moved up by 1 pixel + w->setMinimumSize(INSTRUMENT_WIDTH - 4, INSTRUMENT_HEIGHT - 4 - 1); } #include "InstrumentTrack.moc" From 53942a146a50c7378d99737749bb88879416b16d Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 20 Apr 2019 18:32:17 +0200 Subject: [PATCH 289/445] Fix bad identation in old code --- src/gui/widgets/TabWidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/TabWidget.cpp b/src/gui/widgets/TabWidget.cpp index 6049ce6cb..10e139ce4 100644 --- a/src/gui/widgets/TabWidget.cpp +++ b/src/gui/widgets/TabWidget.cpp @@ -290,7 +290,7 @@ void TabWidget::wheelEvent( QWheelEvent * we ) if( we->y() > m_tabheight ) { return; - } + } we->accept(); int dir = ( we->delta() < 0 ) ? 1 : -1; From e1df16c45b8ac2923dec8e475b6cf44f23752512 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 20 Apr 2019 22:12:32 +0200 Subject: [PATCH 290/445] Coding conventions --- src/gui/widgets/TabWidget.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/gui/widgets/TabWidget.cpp b/src/gui/widgets/TabWidget.cpp index 10e139ce4..9bdbec2e0 100644 --- a/src/gui/widgets/TabWidget.cpp +++ b/src/gui/widgets/TabWidget.cpp @@ -83,7 +83,8 @@ void TabWidget::addTab( QWidget * w, const QString & name, const char *pixmap, i m_widgets[idx] = d; // Position tab's window - if(!m_resizable) { + if (!m_resizable) + { w->setFixedSize( width() - 4, height() - m_tabbarHeight ); } w->move( 2, m_tabbarHeight - 1 ); @@ -193,9 +194,9 @@ void TabWidget::mousePressEvent( QMouseEvent * me ) void TabWidget::resizeEvent( QResizeEvent * ) { - if(!m_resizable) + if (!m_resizable) { - for( widgetStack::iterator it = m_widgets.begin(); + for ( widgetStack::iterator it = m_widgets.begin(); it != m_widgets.end(); ++it ) { ( *it ).w->setFixedSize( width() - 4, height() - m_tabbarHeight ); @@ -312,10 +313,10 @@ void TabWidget::wheelEvent( QWheelEvent * we ) // Let parent widgets know how much space this tab widget needs QSize TabWidget::minimumSizeHint() const { - if(m_resizable) + if (m_resizable) { int maxWidth = 0, maxHeight = 0; - for( widgetStack::const_iterator it = m_widgets.begin(); + for ( widgetStack::const_iterator it = m_widgets.begin(); it != m_widgets.end(); ++it ) { maxWidth = std::max(maxWidth, it->w->width()); @@ -326,9 +327,7 @@ QSize TabWidget::minimumSizeHint() const // moved up by 1 pixel return QSize(maxWidth + 4, maxHeight + m_tabbarHeight - 1); } - else { - return QWidget::minimumSizeHint(); - } + else { return QWidget::minimumSizeHint(); } } From 407444ea1d28cf2c0412f87ab8b5efbd2a059ea0 Mon Sep 17 00:00:00 2001 From: CYBERDEViLNL Date: Wed, 3 Apr 2019 19:54:01 +0200 Subject: [PATCH 291/445] FileBrowser: Backup expanded directories and restore that state when the tree is reloaded. --- include/FileBrowser.h | 6 +++++- src/gui/FileBrowser.cpp | 40 +++++++++++++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/include/FileBrowser.h b/include/FileBrowser.h index 7e0482ce3..4b92dd549 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -55,7 +55,7 @@ public: private slots: void reloadTree( void ); - void expandItems( QTreeWidgetItem * item=NULL ); + void expandItems( QTreeWidgetItem * item=NULL, QList expandedDirs = QList() ); // call with item=NULL to filter the entire tree bool filterItems( const QString & filter, QTreeWidgetItem * item=NULL ); void giveFocusToFilter(); @@ -87,6 +87,10 @@ public: FileBrowserTreeWidget( QWidget * parent ); virtual ~FileBrowserTreeWidget() = default; + //! This method returns a QList with paths (QString's) of all directories + //! that are expanded in the tree. + QList expandedDirs( QTreeWidgetItem * item = nullptr ) const; + protected: virtual void contextMenuEvent( QContextMenuEvent * e ); diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 4311e4e05..7eeb87ed2 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -163,6 +163,7 @@ bool FileBrowser::filterItems( const QString & filter, QTreeWidgetItem * item ) void FileBrowser::reloadTree( void ) { + QList expandedDirs = m_fileBrowserTreeWidget->expandedDirs(); const QString text = m_filterEdit->text(); m_filterEdit->clear(); m_fileBrowserTreeWidget->clear(); @@ -171,17 +172,17 @@ void FileBrowser::reloadTree( void ) { addItems( *it ); } - expandItems(); + expandItems(NULL, expandedDirs); m_filterEdit->setText( text ); filterItems( text ); } -void FileBrowser::expandItems( QTreeWidgetItem * item ) +void FileBrowser::expandItems( QTreeWidgetItem * item, QList expandedDirs ) { int numChildren = item ? item->childCount() : m_fileBrowserTreeWidget->topLevelItemCount(); - for( int i = 0; i < numChildren; ++i ) + for (int i = 0; i < numChildren; ++i) { QTreeWidgetItem * it = item ? item->child( i ) : m_fileBrowserTreeWidget->topLevelItem(i); if ( m_recurse ) @@ -189,14 +190,15 @@ void FileBrowser::expandItems( QTreeWidgetItem * item ) it->setExpanded( true ); } Directory *d = dynamic_cast ( it ); - if( d ) + if (d) { d->update(); - d->setExpanded( false ); + bool expand = expandedDirs.contains( d->fullName() ); + d->setExpanded( expand ); } - if( m_recurse && it->childCount() ) + if (m_recurse && it->childCount()) { - expandItems(it); + expandItems(it, expandedDirs); } } } @@ -326,6 +328,30 @@ FileBrowserTreeWidget::FileBrowserTreeWidget(QWidget * parent ) : } +QList FileBrowserTreeWidget::expandedDirs( QTreeWidgetItem * item ) const +{ + int numChildren = item ? item->childCount() : topLevelItemCount(); + QList dirs; + for (int i = 0; i < numChildren; ++i) + { + QTreeWidgetItem * it = item ? item->child(i) : topLevelItem(i); + + // Add expanded top level directories. + if (it->isExpanded() && (it->type() == TypeDirectoryItem)) + { + Directory *d = static_cast ( it ); + dirs.append( d->fullName() ); + } + + // Add expanded child directories (recurse). + if (it->childCount()) + { + dirs.append( expandedDirs( it ) ); + } + } + return dirs; +} + void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e ) { FileItem * f = dynamic_cast( itemAt( e->pos() ) ); From a685049627483cd71a5286a355861e0a00affacc Mon Sep 17 00:00:00 2001 From: makepost Date: Fri, 19 Apr 2019 15:12:29 +0000 Subject: [PATCH 292/445] Allow build for Wayland w/o X11Extras, if VST off @lukas-w reminds in 134dae8 comments that X11Extras help Linux users of VST effects #3786. Now LMMS builds and runs on Weston without X11 dependencies, though only if WANT_VST is off. --- CMakeLists.txt | 2 +- src/3rdparty/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2611d7086..e186fa61c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -158,7 +158,7 @@ IF(WANT_QT5) Qt5::Xml ) - IF(LMMS_BUILD_LINUX) + IF(LMMS_BUILD_LINUX AND WANT_VST) FIND_PACKAGE(Qt5X11Extras REQUIRED) LIST(APPEND QT_LIBRARIES Qt5::X11Extras) ENDIF() diff --git a/src/3rdparty/CMakeLists.txt b/src/3rdparty/CMakeLists.txt index 5dec2890c..d546fd06e 100644 --- a/src/3rdparty/CMakeLists.txt +++ b/src/3rdparty/CMakeLists.txt @@ -1,7 +1,7 @@ set(CMAKE_C_FLAGS "") set(CMAKE_CXX_FLAGS "") -IF(QT5 AND LMMS_BUILD_LINUX) +IF(QT5 AND LMMS_BUILD_LINUX AND WANT_VST) set(BUILD_SHARED_LIBS OFF) add_subdirectory(qt5-x11embed) ENDIF() From d537561ffc60e5bed978bf8ac839f5a7c646f783 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Mon, 22 Apr 2019 09:27:01 +0200 Subject: [PATCH 293/445] Document Effect::checkGate --- include/Effect.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/Effect.h b/include/Effect.h index 3d765fdc0..4dc50e8a4 100644 --- a/include/Effect.h +++ b/include/Effect.h @@ -161,6 +161,13 @@ public: protected: + /** + Effects should call this at the end of audio processing + + If the setting "Keep effects running even without input" is disabled, + after "decay" ms of a signal below "gate", the effect is turned off + and won't be processed again until it receives new audio input + */ void checkGate( double _out_sum ); virtual PluginView * instantiateView( QWidget * ); From 7ae4e85ffe27753f87c6cf2bd8b7617ee39f8996 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Mon, 22 Apr 2019 11:05:59 +0200 Subject: [PATCH 294/445] Document graph widget --- include/Graph.h | 38 ++++++++++++++++++++++++++++++++------ src/gui/widgets/Graph.cpp | 5 +++-- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/include/Graph.h b/include/Graph.h index 4827bda40..1bee05c41 100644 --- a/include/Graph.h +++ b/include/Graph.h @@ -44,13 +44,18 @@ class LMMS_EXPORT Graph : public QWidget, public ModelView public: enum graphStyle { - NearestStyle, - LinearStyle, - LinearNonCyclicStyle, - BarStyle, + NearestStyle, //!< draw as stairs + LinearStyle, //!< connect each 2 samples with a line, with wrapping + LinearNonCyclicStyle, //!< LinearStyle without wrapping + BarStyle, //!< draw thick bars NumGraphStyles }; + /** + * @brief Constructor + * @param _width Pixel width of widget + * @param _height Pixel height of widget + */ Graph( QWidget * _parent, graphStyle _style = Graph::LinearStyle, int _width = 132, int _height = 104 @@ -111,10 +116,24 @@ private: } ; +/** + @brief 2 dimensional function plot + + Function plot graph with discrete x scale and continous y scale + This makes it possible to display "#x" samples +*/ class LMMS_EXPORT graphModel : public Model { Q_OBJECT public: + /** + * @brief Constructor + * @param _min Minimum y value to display + * @param _max Maximum y value to display + * @param _size Number of samples (e.g. x value) + * @param _step Step size on y axis where values snap to, or 0.0f + * for "no snapping" + */ graphModel( float _min, float _max, int _size, @@ -146,14 +165,21 @@ public: return( m_samples.data() ); } - void convolve(const float *convolution, const int convolutionLength, const int centerOffset); + //! Make cyclic convolution + //! @param convolution Samples to convolve with + //! @param convolutionLength Number of samples to take for each sum + //! @param centerOffset Offset for resulting values + void convolve(const float *convolution, + const int convolutionLength, const int centerOffset); public slots: + //! Set range of y values void setRange( float _min, float _max ); void setLength( int _size ); - + //! Update one sample void setSampleAt( int x, float val ); + //! Update samples array void setSamples( const float * _value ); void setWaveToSine(); diff --git a/src/gui/widgets/Graph.cpp b/src/gui/widgets/Graph.cpp index f93ed523c..4710089dd 100644 --- a/src/gui/widgets/Graph.cpp +++ b/src/gui/widgets/Graph.cpp @@ -635,13 +635,14 @@ void graphModel::smoothNonCyclic() emit samplesChanged(0, length()-1); } -//makes a cyclic convolution. -void graphModel::convolve(const float *convolution, const int convolutionLength, const int centerOffset) +void graphModel::convolve(const float *convolution, + const int convolutionLength, const int centerOffset) { // store values in temporary array QVector temp = m_samples; const int graphLength = length(); float sum; + // make a cyclic convolution for ( int i = 0; i < graphLength; i++ ) { sum = 0; From b5e408d25a7a1805e0442bebd4c834bbb9835d62 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Mon, 22 Apr 2019 20:03:57 +0200 Subject: [PATCH 295/445] Update wiki submodule --- doc/wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/wiki b/doc/wiki index 42193f98f..9c1613155 160000 --- a/doc/wiki +++ b/doc/wiki @@ -1 +1 @@ -Subproject commit 42193f98f37d6b69f47edbdfd50a20090193e70a +Subproject commit 9c1613155898f9a70273101b09907a87501b82ed From c80f0bf5e716f8fa6e847a1ef20646b7b165e680 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 24 Apr 2019 13:58:37 +0900 Subject: [PATCH 296/445] Fix wiki submodule --- doc/wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/wiki b/doc/wiki index 9c1613155..19179c6f6 160000 --- a/doc/wiki +++ b/doc/wiki @@ -1 +1 @@ -Subproject commit 9c1613155898f9a70273101b09907a87501b82ed +Subproject commit 19179c6f6afb422cf8376ed3b4a498a6396fc12f From 461faccaa0d9399e137e471d5bfa0f2b43434d9b Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Wed, 24 Apr 2019 12:50:07 +0100 Subject: [PATCH 297/445] Fix notes getting stuck under high CPU conditions (#4908) --- include/NotePlayHandle.h | 1 + src/core/NotePlayHandle.cpp | 31 +++++++++++++++++++------------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/include/NotePlayHandle.h b/include/NotePlayHandle.h index 768a74aa2..023c3f7c4 100644 --- a/include/NotePlayHandle.h +++ b/include/NotePlayHandle.h @@ -302,6 +302,7 @@ private: NotePlayHandleList m_subNotes; // used for chords and arpeggios volatile bool m_released; // indicates whether note is released bool m_releaseStarted; + bool m_hasMidiNote; bool m_hasParent; // indicates whether note has parent NotePlayHandle * m_parent; // parent note bool m_hadChildren; diff --git a/src/core/NotePlayHandle.cpp b/src/core/NotePlayHandle.cpp index 596e17a71..84d83bb0a 100644 --- a/src/core/NotePlayHandle.cpp +++ b/src/core/NotePlayHandle.cpp @@ -63,6 +63,7 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack, m_subNotes(), m_released( false ), m_releaseStarted( false ), + m_hasMidiNote( false ), m_hasParent( parent != NULL ), m_parent( parent ), m_hadChildren( false ), @@ -106,17 +107,6 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack, m_instrumentTrack->midiNoteOn( *this ); } - if( hasParent() || ! m_instrumentTrack->isArpeggioEnabled() ) - { - const int baseVelocity = m_instrumentTrack->midiPort()->baseVelocity(); - - // send MidiNoteOn event - m_instrumentTrack->processOutEvent( - MidiEvent( MidiNoteOn, midiChannel(), midiKey(), midiVelocity( baseVelocity ) ), - MidiTime::fromFrames( offset(), Engine::framesPerTick() ), - offset() ); - } - if( m_instrumentTrack->instrument()->flags() & Instrument::IsSingleStreamed ) { setUsesBuffer( false ); @@ -208,6 +198,21 @@ void NotePlayHandle::play( sampleFrame * _working_buffer ) } lock(); + + if( m_totalFramesPlayed == 0 && !m_hasMidiNote + && ( hasParent() || ! m_instrumentTrack->isArpeggioEnabled() ) ) + { + m_hasMidiNote = true; + + const int baseVelocity = m_instrumentTrack->midiPort()->baseVelocity(); + + // send MidiNoteOn event + m_instrumentTrack->processOutEvent( + MidiEvent( MidiNoteOn, midiChannel(), midiKey(), midiVelocity( baseVelocity ) ), + MidiTime::fromFrames( offset(), Engine::framesPerTick() ), + offset() ); + } + if( m_frequencyNeedsUpdate ) { updateFrequency(); @@ -360,8 +365,10 @@ void NotePlayHandle::noteOff( const f_cnt_t _s ) m_framesBeforeRelease = _s; m_releaseFramesToDo = qMax( 0, actualReleaseFramesToDo() ); - if( hasParent() || ! m_instrumentTrack->isArpeggioEnabled() ) + if( m_hasMidiNote ) { + m_hasMidiNote = false; + // send MidiNoteOff event m_instrumentTrack->processOutEvent( MidiEvent( MidiNoteOff, midiChannel(), midiKey(), 0 ), From 160d306f481a90e1ddb37666200934d70902ce5c Mon Sep 17 00:00:00 2001 From: Alexandra Dutton Date: Wed, 24 Apr 2019 13:18:53 -0400 Subject: [PATCH 298/445] Record chords (#4938) * Added check for chord to notes recorded from keyboard --- src/gui/editors/PianoRoll.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index fef788885..7d9f95257 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -3522,6 +3522,22 @@ void PianoRoll::finishRecordNote(const Note & n ) it->key(), it->getVolume(), it->getPanning() ); n1.quantizeLength( quantization() ); + + //Get selected chord + const InstrumentFunctionNoteStacking::Chord & chord = InstrumentFunctionNoteStacking::ChordTable::getInstance() + .getChordByName( m_chordModel.currentText() ); + + if( !chord.isEmpty() ) + { + for( int i = 1; i < chord.size(); i++ ) + { + Note new_note( n.length(), it->pos(), it->key() + chord[i] ); + new_note.setPanning( it->getPanning() ); + new_note.setVolume( it->getVolume() ); + m_pattern->addNote( new_note ); + } + } + m_pattern->addNote( n1 ); update(); m_recordingNotes.erase( it ); From ca9a9564cd11eb298f598af33d6032e4b17bac10 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Fri, 26 Apr 2019 12:59:53 +0100 Subject: [PATCH 299/445] Make more connections direct for automation (#4942) --- plugins/LadspaEffect/LadspaControls.cpp | 6 ++++-- plugins/VstEffect/VstEffect.cpp | 3 --- plugins/vst_base/RemoteVstPlugin.cpp | 3 ++- plugins/vst_base/VstPlugin.cpp | 2 +- src/core/EnvelopeAndLfoParameters.cpp | 26 ++++++++++++------------- src/core/LadspaControl.cpp | 3 ++- src/core/LfoController.cpp | 6 +++--- src/core/MeterModel.cpp | 4 ++-- src/core/PeakController.cpp | 6 ++++-- src/core/Song.cpp | 8 ++++---- src/core/TempoSyncKnobModel.cpp | 6 ++++-- src/core/Track.cpp | 2 +- src/core/midi/MidiAlsaSeq.cpp | 2 +- src/core/midi/MidiPort.cpp | 9 ++++++--- src/gui/FxMixerView.cpp | 2 +- src/tracks/SampleTrack.cpp | 2 +- 16 files changed, 49 insertions(+), 41 deletions(-) diff --git a/plugins/LadspaEffect/LadspaControls.cpp b/plugins/LadspaEffect/LadspaControls.cpp index 1a2f26a35..b7f5d2f57 100644 --- a/plugins/LadspaEffect/LadspaControls.cpp +++ b/plugins/LadspaEffect/LadspaControls.cpp @@ -36,7 +36,8 @@ LadspaControls::LadspaControls( LadspaEffect * _eff ) : { connect( &m_stereoLinkModel, SIGNAL( dataChanged() ), - this, SLOT( updateLinkStatesFromGlobal() ) ); + this, SLOT( updateLinkStatesFromGlobal() ), + Qt::DirectConnection ); multi_proc_t controls = m_effect->getPortControls(); m_controlCount = controls.count(); @@ -59,7 +60,8 @@ LadspaControls::LadspaControls( LadspaEffect * _eff ) : if( linked_control ) { connect( (*it)->control, SIGNAL( linkChanged( int, bool ) ), - this, SLOT( linkPort( int, bool ) ) ); + this, SLOT( linkPort( int, bool ) ), + Qt::DirectConnection ); } } } diff --git a/plugins/VstEffect/VstEffect.cpp b/plugins/VstEffect/VstEffect.cpp index 10005d744..ec2ab78e7 100644 --- a/plugins/VstEffect/VstEffect.cpp +++ b/plugins/VstEffect/VstEffect.cpp @@ -145,9 +145,6 @@ void VstEffect::openPlugin( const QString & _plugin ) return; } - VstPlugin::connect( Engine::getSong(), SIGNAL( tempoChanged( bpm_t ) ), m_plugin.data(), SLOT( setTempo( bpm_t ) ) ); - m_plugin->setTempo( Engine::getSong()->getTempo() ); - delete tf; m_key.attributes["file"] = _plugin; diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 8dd25c11f..4a147f7c9 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -1953,7 +1953,8 @@ DWORD WINAPI RemoteVstPlugin::processingThread( LPVOID _param ) { if( m.id == IdStartProcessing || m.id == IdMidiEvent - || m.id == IdVstSetParameter ) + || m.id == IdVstSetParameter + || m.id == IdVstSetTempo ) { _this->processMessage( m ); } diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index e0e1347fe..c707e3fc3 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -92,7 +92,7 @@ VstPlugin::VstPlugin( const QString & _plugin ) : setTempo( Engine::getSong()->getTempo() ); connect( Engine::getSong(), SIGNAL( tempoChanged( bpm_t ) ), - this, SLOT( setTempo( bpm_t ) ) ); + this, SLOT( setTempo( bpm_t ) ), Qt::DirectConnection ); connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( updateSampleRate() ) ); diff --git a/src/core/EnvelopeAndLfoParameters.cpp b/src/core/EnvelopeAndLfoParameters.cpp index d1fbaeb03..27766709d 100644 --- a/src/core/EnvelopeAndLfoParameters.cpp +++ b/src/core/EnvelopeAndLfoParameters.cpp @@ -129,32 +129,32 @@ EnvelopeAndLfoParameters::EnvelopeAndLfoParameters( instances()->add( this ); connect( &m_predelayModel, SIGNAL( dataChanged() ), - this, SLOT( updateSampleVars() ) ); + this, SLOT( updateSampleVars() ), Qt::DirectConnection ); connect( &m_attackModel, SIGNAL( dataChanged() ), - this, SLOT( updateSampleVars() ) ); + this, SLOT( updateSampleVars() ), Qt::DirectConnection ); connect( &m_holdModel, SIGNAL( dataChanged() ), - this, SLOT( updateSampleVars() ) ); + this, SLOT( updateSampleVars() ), Qt::DirectConnection ); connect( &m_decayModel, SIGNAL( dataChanged() ), - this, SLOT( updateSampleVars() ) ); + this, SLOT( updateSampleVars() ), Qt::DirectConnection ); connect( &m_sustainModel, SIGNAL( dataChanged() ), - this, SLOT( updateSampleVars() ) ); + this, SLOT( updateSampleVars() ), Qt::DirectConnection ); connect( &m_releaseModel, SIGNAL( dataChanged() ), - this, SLOT( updateSampleVars() ) ); + this, SLOT( updateSampleVars() ), Qt::DirectConnection ); connect( &m_amountModel, SIGNAL( dataChanged() ), - this, SLOT( updateSampleVars() ) ); + this, SLOT( updateSampleVars() ), Qt::DirectConnection ); connect( &m_lfoPredelayModel, SIGNAL( dataChanged() ), - this, SLOT( updateSampleVars() ) ); + this, SLOT( updateSampleVars() ), Qt::DirectConnection ); connect( &m_lfoAttackModel, SIGNAL( dataChanged() ), - this, SLOT( updateSampleVars() ) ); + this, SLOT( updateSampleVars() ), Qt::DirectConnection ); connect( &m_lfoSpeedModel, SIGNAL( dataChanged() ), - this, SLOT( updateSampleVars() ) ); + this, SLOT( updateSampleVars() ), Qt::DirectConnection ); connect( &m_lfoAmountModel, SIGNAL( dataChanged() ), - this, SLOT( updateSampleVars() ) ); + this, SLOT( updateSampleVars() ), Qt::DirectConnection ); connect( &m_lfoWaveModel, SIGNAL( dataChanged() ), - this, SLOT( updateSampleVars() ) ); + this, SLOT( updateSampleVars() ), Qt::DirectConnection ); connect( &m_x100Model, SIGNAL( dataChanged() ), - this, SLOT( updateSampleVars() ) ); + this, SLOT( updateSampleVars() ), Qt::DirectConnection ); connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( updateSampleVars() ) ); diff --git a/src/core/LadspaControl.cpp b/src/core/LadspaControl.cpp index d2d6e147a..73a32dbb4 100644 --- a/src/core/LadspaControl.cpp +++ b/src/core/LadspaControl.cpp @@ -42,7 +42,8 @@ LadspaControl::LadspaControl( Model * _parent, port_desc_t * _port, if( m_link ) { connect( &m_linkEnabledModel, SIGNAL( dataChanged() ), - this, SLOT( linkStateChanged() ) ); + this, SLOT( linkStateChanged() ), + Qt::DirectConnection ); } switch( m_port->data_type ) diff --git a/src/core/LfoController.cpp b/src/core/LfoController.cpp index c1c81119f..2b2db2f14 100644 --- a/src/core/LfoController.cpp +++ b/src/core/LfoController.cpp @@ -49,12 +49,12 @@ LfoController::LfoController( Model * _parent ) : { setSampleExact( true ); connect( &m_waveModel, SIGNAL( dataChanged() ), - this, SLOT( updateSampleFunction() ) ); + this, SLOT( updateSampleFunction() ), Qt::DirectConnection ); connect( &m_speedModel, SIGNAL( dataChanged() ), - this, SLOT( updateDuration() ) ); + this, SLOT( updateDuration() ), Qt::DirectConnection ); connect( &m_multiplierModel, SIGNAL( dataChanged() ), - this, SLOT( updateDuration() ) ); + this, SLOT( updateDuration() ), Qt::DirectConnection ); connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( updateDuration() ) ); diff --git a/src/core/MeterModel.cpp b/src/core/MeterModel.cpp index 87b1b950a..30db26d9b 100644 --- a/src/core/MeterModel.cpp +++ b/src/core/MeterModel.cpp @@ -33,9 +33,9 @@ MeterModel::MeterModel( ::Model * _parent ) : m_denominatorModel( 4, 1, 32, this, tr( "Denominator" ) ) { connect( &m_numeratorModel, SIGNAL( dataChanged() ), - this, SIGNAL( dataChanged() ) ); + this, SIGNAL( dataChanged() ), Qt::DirectConnection ); connect( &m_denominatorModel, SIGNAL( dataChanged() ), - this, SIGNAL( dataChanged() ) ); + this, SIGNAL( dataChanged() ), Qt::DirectConnection ); } diff --git a/src/core/PeakController.cpp b/src/core/PeakController.cpp index 9e5e654a6..b2e3bc921 100644 --- a/src/core/PeakController.cpp +++ b/src/core/PeakController.cpp @@ -53,8 +53,10 @@ PeakController::PeakController( Model * _parent, this, SLOT( handleDestroyedEffect( ) ) ); } connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( updateCoeffs() ) ); - connect( m_peakEffect->attackModel(), SIGNAL( dataChanged() ), this, SLOT( updateCoeffs() ) ); - connect( m_peakEffect->decayModel(), SIGNAL( dataChanged() ), this, SLOT( updateCoeffs() ) ); + connect( m_peakEffect->attackModel(), SIGNAL( dataChanged() ), + this, SLOT( updateCoeffs() ), Qt::DirectConnection ); + connect( m_peakEffect->decayModel(), SIGNAL( dataChanged() ), + this, SLOT( updateCoeffs() ), Qt::DirectConnection ); m_coeffNeedsUpdate = true; } diff --git a/src/core/Song.cpp b/src/core/Song.cpp index ba2659a6c..943524e6d 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -96,18 +96,18 @@ Song::Song() : m_elapsedTacts( 0 ) { connect( &m_tempoModel, SIGNAL( dataChanged() ), - this, SLOT( setTempo() ) ); + this, SLOT( setTempo() ), Qt::DirectConnection ); connect( &m_tempoModel, SIGNAL( dataUnchanged() ), - this, SLOT( setTempo() ) ); + this, SLOT( setTempo() ), Qt::DirectConnection ); connect( &m_timeSigModel, SIGNAL( dataChanged() ), - this, SLOT( setTimeSignature() ) ); + this, SLOT( setTimeSignature() ), Qt::DirectConnection ); connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( updateFramesPerTick() ) ); connect( &m_masterVolumeModel, SIGNAL( dataChanged() ), - this, SLOT( masterVolumeChanged() ) ); + this, SLOT( masterVolumeChanged() ), Qt::DirectConnection ); /* connect( &m_masterPitchModel, SIGNAL( dataChanged() ), this, SLOT( masterPitchChanged() ) );*/ diff --git a/src/core/TempoSyncKnobModel.cpp b/src/core/TempoSyncKnobModel.cpp index e94c6e424..a85ca2e9f 100644 --- a/src/core/TempoSyncKnobModel.cpp +++ b/src/core/TempoSyncKnobModel.cpp @@ -42,7 +42,8 @@ TempoSyncKnobModel::TempoSyncKnobModel( const float _val, const float _min, m_custom( _parent ) { connect( Engine::getSong(), SIGNAL( tempoChanged( bpm_t ) ), - this, SLOT( calculateTempoSyncTime( bpm_t ) ) ); + this, SLOT( calculateTempoSyncTime( bpm_t ) ), + Qt::DirectConnection ); } @@ -154,7 +155,8 @@ void TempoSyncKnobModel::setSyncMode( TempoSyncMode _new_mode ) if( _new_mode == SyncCustom ) { connect( &m_custom, SIGNAL( dataChanged() ), - this, SLOT( updateCustom() ) ); + this, SLOT( updateCustom() ), + Qt::DirectConnection ); } } calculateTempoSyncTime( Engine::getSong()->getTempo() ); diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 63893c6a4..7a04ded95 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -2548,7 +2548,7 @@ TrackView::TrackView( Track * track, TrackContainerView * tcv ) : &m_trackContentWidget, SLOT( update() ) ); connect( &m_track->m_soloModel, SIGNAL( dataChanged() ), - m_track, SLOT( toggleSolo() ) ); + m_track, SLOT( toggleSolo() ), Qt::DirectConnection ); // create views for already existing TCOs for( Track::tcoVector::iterator it = m_track->m_trackContentObjects.begin(); diff --git a/src/core/midi/MidiAlsaSeq.cpp b/src/core/midi/MidiAlsaSeq.cpp index be1e623de..e420ebc08 100644 --- a/src/core/midi/MidiAlsaSeq.cpp +++ b/src/core/midi/MidiAlsaSeq.cpp @@ -100,7 +100,7 @@ MidiAlsaSeq::MidiAlsaSeq() : snd_seq_start_queue( m_seqHandle, m_queueID, NULL ); changeQueueTempo( Engine::getSong()->getTempo() ); connect( Engine::getSong(), SIGNAL( tempoChanged( bpm_t ) ), - this, SLOT( changeQueueTempo( bpm_t ) ) ); + this, SLOT( changeQueueTempo( bpm_t ) ), Qt::DirectConnection ); // initial list-update updatePortList(); diff --git a/src/core/midi/MidiPort.cpp b/src/core/midi/MidiPort.cpp index 9e3cdb13d..52e0a5223 100644 --- a/src/core/midi/MidiPort.cpp +++ b/src/core/midi/MidiPort.cpp @@ -63,9 +63,12 @@ MidiPort::MidiPort( const QString& name, m_readableModel.setValue( m_mode == Input || m_mode == Duplex ); m_writableModel.setValue( m_mode == Output || m_mode == Duplex ); - connect( &m_readableModel, SIGNAL( dataChanged() ), this, SLOT( updateMidiPortMode() ) ); - connect( &m_writableModel, SIGNAL( dataChanged() ), this, SLOT( updateMidiPortMode() ) ); - connect( &m_outputProgramModel, SIGNAL( dataChanged() ), this, SLOT( updateOutputProgram() ) ); + connect( &m_readableModel, SIGNAL( dataChanged() ), + this, SLOT( updateMidiPortMode() ), Qt::DirectConnection ); + connect( &m_writableModel, SIGNAL( dataChanged() ), + this, SLOT( updateMidiPortMode() ), Qt::DirectConnection ); + connect( &m_outputProgramModel, SIGNAL( dataChanged() ), + this, SLOT( updateOutputProgram() ), Qt::DirectConnection ); // when using with non-raw-clients we can provide buttons showing diff --git a/src/gui/FxMixerView.cpp b/src/gui/FxMixerView.cpp index 5a26372f9..8f1b7e791 100644 --- a/src/gui/FxMixerView.cpp +++ b/src/gui/FxMixerView.cpp @@ -306,7 +306,7 @@ FxMixerView::FxChannelView::FxChannelView(QWidget * _parent, FxMixerView * _mv, m_soloBtn->setCheckable( true ); m_soloBtn->move( 9, m_fader->y()-21); connect(&fxChannel->m_soloModel, SIGNAL( dataChanged() ), - _mv, SLOT ( toggledSolo() ) ); + _mv, SLOT ( toggledSolo() ), Qt::DirectConnection ); ToolTip::add( m_soloBtn, tr( "Solo FX channel" ) ); // Create EffectRack for the channel diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 0a5fabd1a..faf066e8d 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -61,7 +61,7 @@ SampleTCO::SampleTCO( Track * _track ) : // we need to receive bpm-change-events, because then we have to // change length of this TCO connect( Engine::getSong(), SIGNAL( tempoChanged( bpm_t ) ), - this, SLOT( updateLength() ) ); + this, SLOT( updateLength() ), Qt::DirectConnection ); connect( Engine::getSong(), SIGNAL( timeSignatureChanged( int,int ) ), this, SLOT( updateLength() ) ); From 0fd5693e12cf2e5cae0967763854382e0ad376be Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 27 Apr 2019 00:29:49 +0200 Subject: [PATCH 300/445] Improve dcast * document `dcast` * make `dcast` not only cast exact, but also upwards * add `dcast` test * rename `dcast` -> `dynamicCast` --- include/AutomatableModel.h | 17 ++++++-- include/ModelVisitor.h | 24 +++++++---- src/core/ModelVisitor.cpp | 13 ++++++ tests/CMakeLists.txt | 1 + tests/src/core/AutomatableModelTest.cpp | 53 +++++++++++++++++++++++++ 5 files changed, 96 insertions(+), 12 deletions(-) create mode 100644 tests/src/core/AutomatableModelTest.cpp diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h index a92bd5191..93550e33f 100644 --- a/include/AutomatableModel.h +++ b/include/AutomatableModel.h @@ -92,18 +92,25 @@ public: virtual void accept(ConstModelVisitor& v) const = 0; public: - //! Return this class casted to Target, or nullptr if impossible + /** + @brief Return this class casted to Target + @test AutomatableModelTest.cpp + @param doThrow throw an assertion if the cast fails, instead of + returning a nullptr + @return the casted class if Target is the exact or a base class of + *this, nullptr otherwise + */ template - Target* dcast(bool doThrow = false) + Target* dynamicCast(bool doThrow = false) { DCastVisitor vis; accept(vis); if(doThrow && !vis.result) Q_ASSERT(false); return vis.result; } - //! Return this class casted to const Target, or nullptr if impossible + //! const overload, see overloaded function template - const Target* dcast(bool doThrow = false) const + const Target* dynamicCast(bool doThrow = false) const { ConstDCastVisitor vis; accept(vis); if(doThrow && !vis.result) Q_ASSERT(false); @@ -312,6 +319,7 @@ protected: private: + // dynamicCast implementation template struct DCastVisitor : public ModelVisitor { @@ -319,6 +327,7 @@ private: void visit(Target& tar) { result = &tar; } }; + // dynamicCast implementation template struct ConstDCastVisitor : public ConstModelVisitor { diff --git a/include/ModelVisitor.h b/include/ModelVisitor.h index 59d1df0c6..6411d0702 100644 --- a/include/ModelVisitor.h +++ b/include/ModelVisitor.h @@ -25,6 +25,7 @@ #ifndef MODELVISITOR_H #define MODELVISITOR_H +class AutomatableModel; class BoolModel; class IntModel; class FloatModel; @@ -32,21 +33,28 @@ class ComboBoxModel; class ModelVisitor { + template + void up(ModelType& m) { visit(static_cast(m)); } public: - virtual void visit(BoolModel& ) {} - virtual void visit(IntModel& ) {} - virtual void visit(FloatModel& ) {} - virtual void visit(ComboBoxModel& ) {} + virtual void visit(AutomatableModel& ) {} + virtual void visit(BoolModel& m); + virtual void visit(IntModel& ); + virtual void visit(FloatModel& ); + virtual void visit(ComboBoxModel& ); virtual ~ModelVisitor(); }; class ConstModelVisitor { + template + void up(const ModelType& m) { + visit(static_cast(m)); } public: - virtual void visit(const BoolModel& ) {} - virtual void visit(const IntModel& ) {} - virtual void visit(const FloatModel& ) {} - virtual void visit(const ComboBoxModel& ) {} + virtual void visit(const AutomatableModel& ) {} + virtual void visit(const BoolModel& m); + virtual void visit(const IntModel& m); + virtual void visit(const FloatModel& m); + virtual void visit(const ComboBoxModel& m); virtual ~ConstModelVisitor(); }; diff --git a/src/core/ModelVisitor.cpp b/src/core/ModelVisitor.cpp index 11a8fc1b1..48065c57e 100644 --- a/src/core/ModelVisitor.cpp +++ b/src/core/ModelVisitor.cpp @@ -24,5 +24,18 @@ #include "ModelVisitor.h" +#include "AutomatableModel.h" +#include "ComboBoxModel.h" + +void ModelVisitor::visit(BoolModel &m) { up(m); } +void ModelVisitor::visit(IntModel &m) { up(m); } +void ModelVisitor::visit(FloatModel &m) { up(m); } +void ModelVisitor::visit(ComboBoxModel &m) { up(m); } + +void ConstModelVisitor::visit(const BoolModel &m) { up(m); } +void ConstModelVisitor::visit(const IntModel &m) { up(m); } +void ConstModelVisitor::visit(const FloatModel &m) { up(m); } +void ConstModelVisitor::visit(const ComboBoxModel &m) { up(m); } + ModelVisitor::~ModelVisitor() {} ConstModelVisitor::~ConstModelVisitor() {} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c39f8e56e..ddebe116c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -14,6 +14,7 @@ ADD_EXECUTABLE(tests QTestSuite $ + src/core/AutomatableModelTest.cpp src/core/ProjectVersionTest.cpp src/core/RelativePathsTest.cpp diff --git a/tests/src/core/AutomatableModelTest.cpp b/tests/src/core/AutomatableModelTest.cpp new file mode 100644 index 000000000..9bc19d7e8 --- /dev/null +++ b/tests/src/core/AutomatableModelTest.cpp @@ -0,0 +1,53 @@ +/* + * AutomatableModelTest.cpp + * + * Copyright (c) 2019-2019 Johannes Lorenz + * + * 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 "QTestSuite.h" + +#include "AutomatableModel.h" +#include "ComboBoxModel.h" + +class AutomatableModelTest : QTestSuite +{ + Q_OBJECT + +private slots: + void CastTests() + { + ComboBoxModel comboModel; + AutomatableModel* amPtr = &comboModel; + QCOMPARE(nullptr, amPtr->dynamicCast()); + QVERIFY(nullptr != amPtr->dynamicCast()); + QVERIFY(nullptr != amPtr->dynamicCast()); + QVERIFY(nullptr != amPtr->dynamicCast()); + + IntModel intModel; + IntModel* imPtr = &intModel; + QCOMPARE(nullptr, imPtr->dynamicCast()); + QVERIFY(nullptr != imPtr->dynamicCast()); + QVERIFY(nullptr != imPtr->dynamicCast()); + QCOMPARE(nullptr, imPtr->dynamicCast()); + } +} AutomatableModelTests; + +#include "AutomatableModelTest.moc" From 8d005e7565b80f161a51bebb26cf62c700b39dd6 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 27 Apr 2019 10:48:37 +0200 Subject: [PATCH 301/445] AutomatableModelTest: Improve tests Check whether returned pointers from the cast are equal to the original pointers, rather than just checking wether they are not `nullptr`. --- tests/src/core/AutomatableModelTest.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/src/core/AutomatableModelTest.cpp b/tests/src/core/AutomatableModelTest.cpp index 9bc19d7e8..6717da12d 100644 --- a/tests/src/core/AutomatableModelTest.cpp +++ b/tests/src/core/AutomatableModelTest.cpp @@ -32,21 +32,23 @@ class AutomatableModelTest : QTestSuite Q_OBJECT private slots: + //! Test that upcast and exact casts work, + //! but no downcast or any other casts void CastTests() { ComboBoxModel comboModel; AutomatableModel* amPtr = &comboModel; - QCOMPARE(nullptr, amPtr->dynamicCast()); - QVERIFY(nullptr != amPtr->dynamicCast()); - QVERIFY(nullptr != amPtr->dynamicCast()); - QVERIFY(nullptr != amPtr->dynamicCast()); + QCOMPARE(nullptr, amPtr->dynamicCast()); // not a parent class + QCOMPARE(&comboModel, amPtr->dynamicCast()); // parent class + QCOMPARE(&comboModel, amPtr->dynamicCast()); // parent class + QCOMPARE(&comboModel, amPtr->dynamicCast()); // same class IntModel intModel; IntModel* imPtr = &intModel; - QCOMPARE(nullptr, imPtr->dynamicCast()); - QVERIFY(nullptr != imPtr->dynamicCast()); - QVERIFY(nullptr != imPtr->dynamicCast()); - QCOMPARE(nullptr, imPtr->dynamicCast()); + QCOMPARE(nullptr, imPtr->dynamicCast()); // not a parent class + QCOMPARE(&intModel, imPtr->dynamicCast()); // parent class + QCOMPARE(&intModel, imPtr->dynamicCast()); // same class + QCOMPARE(nullptr, imPtr->dynamicCast()); // child class } } AutomatableModelTests; From 777da5e391a81ed561767708c2f86a6b7b36af09 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 27 Apr 2019 11:11:48 +0200 Subject: [PATCH 302/445] Fix CI on windows --- tests/src/core/AutomatableModelTest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/src/core/AutomatableModelTest.cpp b/tests/src/core/AutomatableModelTest.cpp index 6717da12d..116f95e60 100644 --- a/tests/src/core/AutomatableModelTest.cpp +++ b/tests/src/core/AutomatableModelTest.cpp @@ -38,17 +38,17 @@ private slots: { ComboBoxModel comboModel; AutomatableModel* amPtr = &comboModel; - QCOMPARE(nullptr, amPtr->dynamicCast()); // not a parent class + QVERIFY(nullptr == amPtr->dynamicCast()); // not a parent class QCOMPARE(&comboModel, amPtr->dynamicCast()); // parent class QCOMPARE(&comboModel, amPtr->dynamicCast()); // parent class QCOMPARE(&comboModel, amPtr->dynamicCast()); // same class IntModel intModel; IntModel* imPtr = &intModel; - QCOMPARE(nullptr, imPtr->dynamicCast()); // not a parent class + QVERIFY(nullptr == imPtr->dynamicCast()); // not a parent class QCOMPARE(&intModel, imPtr->dynamicCast()); // parent class QCOMPARE(&intModel, imPtr->dynamicCast()); // same class - QCOMPARE(nullptr, imPtr->dynamicCast()); // child class + QVERIFY(nullptr == imPtr->dynamicCast()); // child class } } AutomatableModelTests; From 2c134d65fed33930801581e8c906ed1eb0048112 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 27 Apr 2019 15:26:17 +0200 Subject: [PATCH 303/445] Code style + Extend for TempoSyncKnob --- include/AutomatableModel.h | 4 ++-- include/ModelVisitor.h | 9 ++++++--- include/TempoSyncKnobModel.h | 1 + src/core/ModelVisitor.cpp | 3 +++ 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h index 93550e33f..3e0b6143d 100644 --- a/include/AutomatableModel.h +++ b/include/AutomatableModel.h @@ -104,7 +104,7 @@ public: Target* dynamicCast(bool doThrow = false) { DCastVisitor vis; accept(vis); - if(doThrow && !vis.result) Q_ASSERT(false); + if (doThrow && !vis.result) { Q_ASSERT(false); } return vis.result; } @@ -113,7 +113,7 @@ public: const Target* dynamicCast(bool doThrow = false) const { ConstDCastVisitor vis; accept(vis); - if(doThrow && !vis.result) Q_ASSERT(false); + if (doThrow && !vis.result) { Q_ASSERT(false); } return vis.result; } diff --git a/include/ModelVisitor.h b/include/ModelVisitor.h index 6411d0702..f9d156e30 100644 --- a/include/ModelVisitor.h +++ b/include/ModelVisitor.h @@ -30,6 +30,7 @@ class BoolModel; class IntModel; class FloatModel; class ComboBoxModel; +class TempoSyncKnobModel; class ModelVisitor { @@ -38,9 +39,10 @@ class ModelVisitor public: virtual void visit(AutomatableModel& ) {} virtual void visit(BoolModel& m); - virtual void visit(IntModel& ); - virtual void visit(FloatModel& ); - virtual void visit(ComboBoxModel& ); + virtual void visit(IntModel& m); + virtual void visit(FloatModel& m); + virtual void visit(ComboBoxModel& m); + virtual void visit(TempoSyncKnobModel& m); virtual ~ModelVisitor(); }; @@ -55,6 +57,7 @@ public: virtual void visit(const IntModel& m); virtual void visit(const FloatModel& m); virtual void visit(const ComboBoxModel& m); + virtual void visit(const TempoSyncKnobModel& m); virtual ~ConstModelVisitor(); }; diff --git a/include/TempoSyncKnobModel.h b/include/TempoSyncKnobModel.h index 9a8ad619c..52fab30bb 100644 --- a/include/TempoSyncKnobModel.h +++ b/include/TempoSyncKnobModel.h @@ -33,6 +33,7 @@ class QAction; class LMMS_EXPORT TempoSyncKnobModel : public FloatModel { Q_OBJECT + MODEL_IS_VISITABLE public: enum TempoSyncMode { diff --git a/src/core/ModelVisitor.cpp b/src/core/ModelVisitor.cpp index 48065c57e..4036f56e0 100644 --- a/src/core/ModelVisitor.cpp +++ b/src/core/ModelVisitor.cpp @@ -26,16 +26,19 @@ #include "AutomatableModel.h" #include "ComboBoxModel.h" +#include "TempoSyncKnobModel.h" void ModelVisitor::visit(BoolModel &m) { up(m); } void ModelVisitor::visit(IntModel &m) { up(m); } void ModelVisitor::visit(FloatModel &m) { up(m); } void ModelVisitor::visit(ComboBoxModel &m) { up(m); } +void ModelVisitor::visit(TempoSyncKnobModel &m) { up(m); } void ConstModelVisitor::visit(const BoolModel &m) { up(m); } void ConstModelVisitor::visit(const IntModel &m) { up(m); } void ConstModelVisitor::visit(const FloatModel &m) { up(m); } void ConstModelVisitor::visit(const ComboBoxModel &m) { up(m); } +void ConstModelVisitor::visit(const TempoSyncKnobModel &m) { up(m); } ModelVisitor::~ModelVisitor() {} ConstModelVisitor::~ConstModelVisitor() {} From 8bcdf06c6c632d612eb39e6a82d62022f9dc2ddd Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 29 Apr 2019 16:34:35 +0900 Subject: [PATCH 304/445] Travis: fix a debootstrap error from missing keyrings Uses 18.04's debian-archive-keyring to fix the missing keyrings. --- .travis/debian_pkgs.sha256 | 1 + .travis/linux.debian-sid.install.sh | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis/debian_pkgs.sha256 b/.travis/debian_pkgs.sha256 index 96a4bd8aa..ed4e11737 100644 --- a/.travis/debian_pkgs.sha256 +++ b/.travis/debian_pkgs.sha256 @@ -1,2 +1,3 @@ 314ef4af137903dfb13e8c3ef1e6ea56cfdb23808d52ec4f5f50e288c73610c5 pbuilder_0.229.1_all.deb fa82aa8ed3055c6f6330104deedf080b26778295e589426d4c4dd0f2c2a5defa debootstrap_1.0.95_all.deb +2ef4c09f7841b72f93412803ddd142f72658536dbfabe00e449eb548f432f3f8 debian-archive-keyring_2017.7ubuntu1_all.deb diff --git a/.travis/linux.debian-sid.install.sh b/.travis/linux.debian-sid.install.sh index ecdcf6d91..ef8368822 100755 --- a/.travis/linux.debian-sid.install.sh +++ b/.travis/linux.debian-sid.install.sh @@ -2,15 +2,16 @@ 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 +# and also missing signing keys in Trusty's debian-archive-keyring 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 +wget http://archive.ubuntu.com/ubuntu/pool/universe/d/debian-archive-keyring/debian-archive-keyring_2017.7ubuntu1_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 +sudo dpkg -i pbuilder_0.229.1_all.deb debootstrap_1.0.95_all.deb debian-archive-keyring_2017.7ubuntu1_all.deb cd "$OLDPWD" From 32df2d7fbad48c97322fdd1ebdffd0b5fee8fff8 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Sun, 5 May 2019 12:39:36 +0900 Subject: [PATCH 305/445] Don't draw note detuning info over the volume/panning area (#4965) --- src/gui/editors/PianoRoll.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 7d9f95257..18995bfde 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -883,6 +883,9 @@ void PianoRoll::drawDetuningInfo( QPainter & _p, const Note * _n, int _x, { int middle_y = _y + KEY_LINE_HEIGHT / 2; _p.setPen( noteColor() ); + _p.setClipRect(WHITE_KEY_WIDTH, PR_TOP_MARGIN, + width() - WHITE_KEY_WIDTH, + keyAreaBottom() - PR_TOP_MARGIN); int old_x = 0; int old_y = 0; @@ -3077,6 +3080,10 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) } } + p.setClipRect(WHITE_KEY_WIDTH, PR_TOP_MARGIN, + width() - WHITE_KEY_WIDTH, + height() - PR_TOP_MARGIN - PR_TOP_MARGIN); + p.setPen( QPen( noteColor(), NOTE_EDIT_LINE_WIDTH + 2 ) ); p.drawPoints( editHandles ); From cb6b4ec44b0df002ea7f38163207678511d1cc19 Mon Sep 17 00:00:00 2001 From: "https://gitlab.com/users/CYBERDEViLNL" <1148379+CYBERDEViLNL@users.noreply.github.com> Date: Sun, 5 May 2019 15:57:16 +0200 Subject: [PATCH 306/445] Show/Focus BBEditor on TrackLabelButton click #4946 (#4959) It will be shown even if the parent is hidden. --- src/tracks/BBTrack.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tracks/BBTrack.cpp b/src/tracks/BBTrack.cpp index c37c1466f..205a22087 100644 --- a/src/tracks/BBTrack.cpp +++ b/src/tracks/BBTrack.cpp @@ -635,5 +635,6 @@ bool BBTrackView::close() void BBTrackView::clickedTrackLabel() { Engine::getBBTrackContainer()->setCurrentBB( m_bbTrack->index() ); - gui->getBBEditor()->show(); + gui->getBBEditor()->parentWidget()->show(); + gui->getBBEditor()->setFocus( Qt::ActiveWindowFocusReason ); } From 8f4757ee3b8f1efe321a82d8b10f6bcf990233a9 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 6 May 2019 12:13:22 +0900 Subject: [PATCH 307/445] Use extracted linuxdeployqt directly As of https://github.com/probonopd/linuxdeployqt/pull/370/, the AppRun of linuxdeployqt unsets LD_LIBRARY_PATH. This behavior isn't suitable for our cases, so we use the extracted binary directly as a workaround. --- cmake/linux/package_linux.sh.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index b02a4c688..7c0e2593b 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -70,6 +70,9 @@ elif ! find "$LINUXDEPLOYQT" -mtime -$DAYSOLD 2>/dev/null|grep -q "." > /dev/nul touch "$LINUXDEPLOYQT" success "Downloaded $LINUXDEPLOYQT" "$LINUXDEPLOYQT" --appimage-extract > /dev/null 2>&1 + # We need to set LD_LIBRARY_PATH, but linuxdepoyqt's AppRun unsets it + # See https://github.com/probonopd/linuxdeployqt/pull/370/ + LINUXDEPLOYQT="squashfs-root/usr/bin/linuxdeployqt" success "Extracted $APPIMAGETOOL" else skipped "$LINUXDEPLOYQT is less than $DAYSOLD days old" From 9ff882d09d169e16e0b58b32d279d919968a7329 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 6 May 2019 15:36:38 +0900 Subject: [PATCH 308/445] Fix invisible note editing handles when a note has detuning info Fixes a regression in 32df2d7fbad48c97322fdd1ebdffd0b5fee8fff8, the clipping area was restored in a wrong place. Also, a wrong value was used while restoring. --- src/gui/editors/PianoRoll.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 18995bfde..5b306a783 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -3077,12 +3077,12 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) drawDetuningInfo( p, note, x + WHITE_KEY_WIDTH, y_base - key * KEY_LINE_HEIGHT ); + p.setClipRect(WHITE_KEY_WIDTH, PR_TOP_MARGIN, + width() - WHITE_KEY_WIDTH, + height() - PR_TOP_MARGIN); } } - p.setClipRect(WHITE_KEY_WIDTH, PR_TOP_MARGIN, - width() - WHITE_KEY_WIDTH, - height() - PR_TOP_MARGIN - PR_TOP_MARGIN); p.setPen( QPen( noteColor(), NOTE_EDIT_LINE_WIDTH + 2 ) ); p.drawPoints( editHandles ); From d54c79d33be63367415258a214791f4b9d84878b Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 6 May 2019 16:43:01 +0900 Subject: [PATCH 309/445] Fix the wrong merge --- cmake/linux/package_linux.sh.in | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index a517ee53e..0dec715f4 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -76,6 +76,7 @@ else # to support systems without fuse # Also, we need to set LD_LIBRARY_PATH, but linuxdepoyqt's AppRun unsets it # See https://github.com/probonopd/linuxdeployqt/pull/370/ + "$LINUXDEPLOYQT" --appimage-extract > /dev/null 2>&1 LINUXDEPLOYQT="squashfs-root/usr/bin/linuxdeployqt" success "Extracted $APPIMAGETOOL" fi From 3dcffbf96fad5c3f787433de0d070230bc006bae Mon Sep 17 00:00:00 2001 From: Ron U Date: Mon, 6 May 2019 12:00:37 +0300 Subject: [PATCH 310/445] fix hanging mouse in piano roll (#4822) (#4960) * fix hanging mouse in piano roll (#4822) * fix hanging mouse in automation & pianoroll (#4822); * fix hanging mouse in automation & pianoroll (#4822) removed TODO comment that I forgot in the code --- src/gui/TimeLineWidget.cpp | 2 ++ src/gui/editors/AutomationEditor.cpp | 9 ++++++--- src/gui/editors/PianoRoll.cpp | 7 ++++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/gui/TimeLineWidget.cpp b/src/gui/TimeLineWidget.cpp index cfb4288c7..a98381b0f 100644 --- a/src/gui/TimeLineWidget.cpp +++ b/src/gui/TimeLineWidget.cpp @@ -88,6 +88,7 @@ TimeLineWidget::TimeLineWidget( const int xoff, const int yoff, const float ppt, m_xOffset -= s_posMarkerPixmap->width() / 2; + setMouseTracking(true); m_pos.m_timeLine = this; QTimer * updateTimer = new QTimer( this ); @@ -365,6 +366,7 @@ void TimeLineWidget::mousePressEvent( QMouseEvent* event ) void TimeLineWidget::mouseMoveEvent( QMouseEvent* event ) { + parentWidget()->update(); // essential for widgets that this timeline had taken their mouse move event from. const MidiTime t = m_begin + static_cast( qMax( event->x() - m_xOffset - m_moveXOff, 0 ) * MidiTime::ticksPerTact() / m_ppt ); switch( m_action ) diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index fafb83d0d..5e8ea8a0a 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -430,8 +430,8 @@ void AutomationEditor::leaveEvent(QEvent * e ) { QApplication::restoreOverrideCursor(); } - QWidget::leaveEvent( e ); + update(); } @@ -1510,8 +1510,11 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) case SELECT: cursor = s_toolSelect; break; case MOVE: cursor = s_toolMove; break; } - p.drawPixmap( mapFromGlobal( QCursor::pos() ) + QPoint( 8, 8 ), - *cursor ); + QPoint mousePosition = mapFromGlobal( QCursor::pos() ); + if( cursor != NULL && mousePosition.y() > TOP_MARGIN + SCROLLBAR_SIZE) + { + p.drawPixmap( mousePosition + QPoint( 8, 8 ), *cursor ); + } } diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 5b306a783..b65a6b56b 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -1297,6 +1297,7 @@ void PianoRoll::leaveEvent(QEvent * e ) QWidget::leaveEvent( e ); s_textFloat->hide(); + update(); // cleaning inner mouse-related graphics } @@ -3167,10 +3168,10 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) case ModeSelect: cursor = s_toolSelect; break; case ModeEditDetuning: cursor = s_toolOpen; break; } - if( cursor != NULL ) + QPoint mousePosition = mapFromGlobal( QCursor::pos() ); + if( cursor != NULL && mousePosition.y() > keyAreaTop() && mousePosition.x() > noteEditLeft()) { - p.drawPixmap( mapFromGlobal( QCursor::pos() ) + QPoint( 8, 8 ), - *cursor ); + p.drawPixmap( mousePosition + QPoint( 8, 8 ), *cursor ); } } From b9503a8c7094dd175cb8261a56832343a4451f61 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 8 May 2019 15:12:17 +0900 Subject: [PATCH 311/445] Fix race conditions in NotePlayHandleManager (#4966) NotePlayHandleManager::acquire uses a read lock unless the pool is empty. If two threads try to acquire NotePlayHandle simultaneously when the value of s_availableIndex is 1, one thread will try to read s_available[-1]. If the acquire action and the release action are done at the same time, NotePlayHandleManager::acquire may try to read data before NotePlayHandleManager::release actually writes. This commit prevents them by always using the write lock when acquiring a NotePlayHandle. --- src/core/NotePlayHandle.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/core/NotePlayHandle.cpp b/src/core/NotePlayHandle.cpp index 84d83bb0a..1e6ce01c9 100644 --- a/src/core/NotePlayHandle.cpp +++ b/src/core/NotePlayHandle.cpp @@ -577,13 +577,9 @@ NotePlayHandle * NotePlayHandleManager::acquire( InstrumentTrack* instrumentTrac int midiEventChannel, NotePlayHandle::Origin origin ) { - if( s_availableIndex < 0 ) - { - s_mutex.lockForWrite(); - if( s_availableIndex < 0 ) extend( NPH_CACHE_INCREMENT ); - s_mutex.unlock(); - } - s_mutex.lockForRead(); + // TODO: use some lockless data structures + s_mutex.lockForWrite(); + if (s_availableIndex < 0) { extend(NPH_CACHE_INCREMENT); } NotePlayHandle * nph = s_available[ s_availableIndex.fetchAndAddOrdered( -1 ) ]; s_mutex.unlock(); From 50796b20889ccf0f6a19184eff7eb45ed0d9b375 Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Thu, 9 May 2019 19:51:10 +0200 Subject: [PATCH 312/445] Nescaline and Freeboy - Better default sound (#4968) --- plugins/nes/Nes.cpp | 2 +- plugins/papu/papu_instrument.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/nes/Nes.cpp b/plugins/nes/Nes.cpp index 1b385e465..aaf45143e 100644 --- a/plugins/nes/Nes.cpp +++ b/plugins/nes/Nes.cpp @@ -519,7 +519,7 @@ NesInstrument::NesInstrument( InstrumentTrack * instrumentTrack ) : m_ch3Volume( 15.f, 0.f, 15.f, 1.f, this, tr( "Channel 3 Volume" ) ), //channel 4 - m_ch4Enabled( true, this ), + m_ch4Enabled( false, this ), m_ch4Volume( 15.f, 0.f, 15.f, 1.f, this, tr( "Channel 4 Volume" ) ), m_ch4EnvEnabled( false, this ), diff --git a/plugins/papu/papu_instrument.cpp b/plugins/papu/papu_instrument.cpp index b9c1b28ae..328ddffa2 100644 --- a/plugins/papu/papu_instrument.cpp +++ b/plugins/papu/papu_instrument.cpp @@ -104,11 +104,11 @@ papuInstrument::papuInstrument( InstrumentTrack * _instrument_track ) : m_ch1So1Model( true, this, tr( "Channel 1 to SO2 (Left)" ) ), m_ch2So1Model( true, this, tr( "Channel 2 to SO2 (Left)" ) ), m_ch3So1Model( true, this, tr( "Channel 3 to SO2 (Left)" ) ), - m_ch4So1Model( true, this, tr( "Channel 4 to SO2 (Left)" ) ), + m_ch4So1Model( false, this, tr( "Channel 4 to SO2 (Left)" ) ), m_ch1So2Model( true, this, tr( "Channel 1 to SO1 (Right)" ) ), m_ch2So2Model( true, this, tr( "Channel 2 to SO1 (Right)" ) ), m_ch3So2Model( true, this, tr( "Channel 3 to SO1 (Right)" ) ), - m_ch4So2Model( true, this, tr( "Channel 4 to SO1 (Right)" ) ), + m_ch4So2Model( false, this, tr( "Channel 4 to SO1 (Right)" ) ), m_trebleModel( -20.0f, -100.0f, 200.0f, 1.0f, this, tr( "Treble" ) ), m_bassModel( 461.0f, -1.0f, 600.0f, 1.0f, this, tr( "Bass" ) ), From 934ea6d0866818833caaacbe16c816b9a94c9b9a Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Fri, 10 May 2019 07:32:40 +0900 Subject: [PATCH 313/445] Fix controller loading error on loading projects Fixes a regression in 91f9f1a890f529779931501d7f571de9cec54226, which added the range check into the wrong if statement. --- src/core/ControllerConnection.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/ControllerConnection.cpp b/src/core/ControllerConnection.cpp index 4d43a4366..e08f15b63 100644 --- a/src/core/ControllerConnection.cpp +++ b/src/core/ControllerConnection.cpp @@ -205,13 +205,15 @@ void ControllerConnection::loadSettings( const QDomElement & _this ) else { m_controllerId = _this.attribute( "id", "-1" ).toInt(); - if( m_controllerId < 0 || m_controllerId >= Engine::getSong()->controllers().size() ) + if( m_controllerId < 0 ) { qWarning( "controller index invalid\n" ); m_controllerId = -1; } - if (!Engine::getSong()->isLoadingProject() && m_controllerId != -1) + if (!Engine::getSong()->isLoadingProject() + && m_controllerId != -1 + && m_controllerId < Engine::getSong()->controllers().size()) { setController( Engine::getSong()-> controllers().at( m_controllerId ) ); From 4b4b4705501302e3704bc6ed559595419d90c801 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Mon, 13 May 2019 20:23:01 +0200 Subject: [PATCH 314/445] Extend ProjectJournal docs, thx to @DomClark --- include/ProjectJournal.h | 3 +++ src/core/ProjectJournal.cpp | 2 ++ 2 files changed, 5 insertions(+) diff --git a/include/ProjectJournal.h b/include/ProjectJournal.h index e0e738b70..cb487617b 100644 --- a/include/ProjectJournal.h +++ b/include/ProjectJournal.h @@ -34,6 +34,7 @@ class JournallingObject; +//! @warning many parts of this class may be rewritten soon class ProjectJournal { public: @@ -76,7 +77,9 @@ public: reallocID( _id, NULL ); } + //! hack, not used when saving a file static jo_id_t idToSave( jo_id_t id ); + //! hack, not used when loading a savefile static jo_id_t idFromSave( jo_id_t id ); void clearJournal(); diff --git a/src/core/ProjectJournal.cpp b/src/core/ProjectJournal.cpp index ce811dbc5..e3cd362cb 100644 --- a/src/core/ProjectJournal.cpp +++ b/src/core/ProjectJournal.cpp @@ -29,6 +29,8 @@ #include "JournallingObject.h" #include "Song.h" +//! Avoid clashes between loaded IDs (have the bit cleared) +//! and newly created IDs (have the bit set) static const int EO_ID_MSB = 1 << 23; const int ProjectJournal::MAX_UNDO_STATES = 100; // TODO: make this configurable in settings From ec64de072352c17a025e073114aaaea6ba773822 Mon Sep 17 00:00:00 2001 From: T0NIT0 RMX Date: Tue, 14 May 2019 21:19:30 +0200 Subject: [PATCH 315/445] Fixes #4781: Don't disconnect LADSPA automation on export --- src/core/AutomationPattern.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/core/AutomationPattern.cpp b/src/core/AutomationPattern.cpp index 2ee41b5f2..827f207dc 100644 --- a/src/core/AutomationPattern.cpp +++ b/src/core/AutomationPattern.cpp @@ -796,6 +796,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/4781 + o = Engine::projectJournal()->journallingObject(ProjectJournal::idToSave(*k)); + if( o && dynamic_cast( o ) ) + { + a->addObject( dynamic_cast( o ), false ); + } + } } } a->m_idsToResolve.clear(); From 28143e61edc53124e6df0081517e17fb964d13d4 Mon Sep 17 00:00:00 2001 From: sharpblade4 Date: Fri, 24 May 2019 19:37:14 +0300 Subject: [PATCH 316/445] playing/recording pianoRoll's chord notes (#4963) --- include/PianoRoll.h | 2 + src/gui/editors/PianoRoll.cpp | 84 +++++++++++++++++++++++++---------- 2 files changed, 62 insertions(+), 24 deletions(-) diff --git a/include/PianoRoll.h b/include/PianoRoll.h index b4115b054..4451a07c5 100644 --- a/include/PianoRoll.h +++ b/include/PianoRoll.h @@ -296,6 +296,8 @@ private: void testPlayNote( Note * n ); void testPlayKey( int _key, int _vol, int _pan ); void pauseTestNotes(bool pause = true ); + void playChordNotes(int key, int velocity=-1); + void pauseChordNotes(int key); QList getAllOctavesForKey( int keyToMirror ) const; diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 03d7c14c7..a3ff9c5fd 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -1191,9 +1191,11 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke) { const int key_num = PianoView::getKeyFromKeyEvent( ke ) + ( DefaultOctave - 1 ) * KeysPerOctave; - if(! ke->isAutoRepeat() && key_num > -1) + if (!ke->isAutoRepeat() && key_num > -1) { - m_pattern->instrumentTrack()->pianoModel()->handleKeyPress( key_num ); + m_pattern->instrumentTrack()->pianoModel()->handleKeyPress(key_num); + // if a chord is set, play all chord notes (simulate click on all): + playChordNotes(key_num); ke->accept(); } } @@ -1391,10 +1393,11 @@ void PianoRoll::keyReleaseEvent(QKeyEvent* ke ) if( hasValidPattern() && ke->modifiers() == Qt::NoModifier ) { const int key_num = PianoView::getKeyFromKeyEvent( ke ) + ( DefaultOctave - 1 ) * KeysPerOctave; - - if( ! ke->isAutoRepeat() && key_num > -1 ) + if (!ke->isAutoRepeat() && key_num > -1) { - m_pattern->instrumentTrack()->pianoModel()->handleKeyRelease( key_num ); + m_pattern->instrumentTrack()->pianoModel()->handleKeyRelease(key_num); + // if a chord is set, simulate click release on all chord notes + pauseChordNotes(key_num); ke->accept(); } } @@ -1839,7 +1842,9 @@ void PianoRoll::mousePressEvent(QMouseEvent * me ) { // left click - play the note int v = ( (float) x ) / ( (float) WHITE_KEY_WIDTH ) * MidiDefaultVelocity; - m_pattern->instrumentTrack()->pianoModel()->handleKeyPress( key_num, v ); + m_pattern->instrumentTrack()->pianoModel()->handleKeyPress(key_num, v); + // if a chord is set, play the chords notes as well: + playChordNotes(key_num, v); } } else @@ -1942,7 +1947,10 @@ void PianoRoll::testPlayNote( Note * n ) const int baseVelocity = m_pattern->instrumentTrack()->midiPort()->baseVelocity(); - m_pattern->instrumentTrack()->pianoModel()->handleKeyPress( n->key(), n->midiVelocity( baseVelocity ) ); + m_pattern->instrumentTrack()->pianoModel()->handleKeyPress(n->key(), n->midiVelocity(baseVelocity)); + + // if a chord is set, play the chords notes as well: + playChordNotes(n->key(), n->midiVelocity(baseVelocity)); MidiEvent event( MidiMetaEvent, -1, n->key(), panningToMidi( n->getPanning() ) ); @@ -1965,6 +1973,9 @@ void PianoRoll::pauseTestNotes( bool pause ) { // stop note m_pattern->instrumentTrack()->pianoModel()->handleKeyRelease( note->key() ); + + // if a chord was set, stop the chords notes as well: + pauseChordNotes(note->key()); } else { @@ -1976,19 +1987,56 @@ void PianoRoll::pauseTestNotes( bool pause ) } } +void PianoRoll::playChordNotes(int key, int velocity) +{ + // if a chord is set, play the chords notes beside the base note. + Piano *pianoModel = m_pattern->instrumentTrack()->pianoModel(); + const InstrumentFunctionNoteStacking::Chord & chord = + InstrumentFunctionNoteStacking::ChordTable::getInstance().getChordByName( + m_chordModel.currentText()); + if (!chord.isEmpty()) + { + for (int i = 1; i < chord.size(); ++i) + { + pianoModel->handleKeyPress(key + chord[i], velocity); + } + } +} + +void PianoRoll::pauseChordNotes(int key) +{ + // if a chord was set, stop the chords notes beside the base note. + Piano *pianoModel = m_pattern->instrumentTrack()->pianoModel(); + const InstrumentFunctionNoteStacking::Chord & chord = + InstrumentFunctionNoteStacking::ChordTable::getInstance().getChordByName( + m_chordModel.currentText()); + if (!chord.isEmpty()) + { + for (int i = 1; i < chord.size(); ++i) + { + pianoModel->handleKeyRelease(key + chord[i]); + } + } +} + void PianoRoll::testPlayKey( int key, int velocity, int pan ) { + Piano *pianoModel = m_pattern->instrumentTrack()->pianoModel(); // turn off old key - m_pattern->instrumentTrack()->pianoModel()->handleKeyRelease( m_lastKey ); + pianoModel->handleKeyRelease( m_lastKey ); + // if a chord was set, stop the chords notes as well + pauseChordNotes(m_lastKey); // remember which one we're playing m_lastKey = key; // play new key - m_pattern->instrumentTrack()->pianoModel()->handleKeyPress( key, velocity ); + pianoModel->handleKeyPress( key, velocity ); + // and if a chord is set, play chord notes: + playChordNotes(key, velocity); } @@ -2118,6 +2166,7 @@ void PianoRoll::mouseReleaseEvent( QMouseEvent * me ) { m_pattern->instrumentTrack()->pianoModel()-> handleKeyRelease( note->key() ); + pauseChordNotes(note->key()); note->setIsPlaying( false ); } } @@ -2125,6 +2174,7 @@ void PianoRoll::mouseReleaseEvent( QMouseEvent * me ) // stop playing keys that we let go of m_pattern->instrumentTrack()->pianoModel()-> handleKeyRelease( m_lastKey ); + pauseChordNotes(m_lastKey); } m_currentNote = NULL; @@ -2312,6 +2362,7 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) { // mouse not over this note, stop playing it. m_pattern->instrumentTrack()->pianoModel()->handleKeyRelease( n->key() ); + pauseChordNotes(n->key()); n->setIsPlaying( false ); } @@ -3789,21 +3840,6 @@ void PianoRoll::finishRecordNote(const Note & n ) it->key(), it->getVolume(), it->getPanning() ); n1.quantizeLength( quantization() ); - - //Get selected chord - const InstrumentFunctionNoteStacking::Chord & chord = InstrumentFunctionNoteStacking::ChordTable::getInstance() - .getChordByName( m_chordModel.currentText() ); - - if( !chord.isEmpty() ) - { - for( int i = 1; i < chord.size(); i++ ) - { - Note new_note( n.length(), it->pos(), it->key() + chord[i] ); - new_note.setPanning( it->getPanning() ); - new_note.setVolume( it->getVolume() ); - m_pattern->addNote( new_note ); - } - } m_pattern->addNote( n1 ); update(); m_recordingNotes.erase( it ); From 9c6e2278cef8e8da2edcbe74d95e7b334a0bd9b8 Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Mon, 27 May 2019 21:26:30 +0300 Subject: [PATCH 317/445] SampleTrack: call requestChangesInModel before unref SampleBuffer (#4982) To avoid a race condition between the gui thread which destroys the samplebuffer and the mixer thread which increases the buffer's ref- count, we'll make sure to touch the ref-count only when wh're synced with the mixer. --- src/tracks/SampleTrack.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index faf066e8d..b45f442d1 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -110,7 +110,9 @@ SampleTCO::~SampleTCO() { sampletrack->updateTcos(); } + Engine::mixer()->requestChangeInModel(); sharedObject::unref( m_sampleBuffer ); + Engine::mixer()->doneChangeInModel(); } @@ -133,7 +135,9 @@ const QString & SampleTCO::sampleFile() const void SampleTCO::setSampleBuffer( SampleBuffer* sb ) { + Engine::mixer()->requestChangeInModel(); sharedObject::unref( m_sampleBuffer ); + Engine::mixer()->doneChangeInModel(); m_sampleBuffer = sb; updateLength(); From 46c74d0a8149c741c0a1e1eef4dc8f2563a97735 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Mon, 27 May 2019 23:02:17 +0100 Subject: [PATCH 318/445] Making clearer the hierarchy. (#4967) Add `override` keyword --- include/TempoSyncKnobModel.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/TempoSyncKnobModel.h b/include/TempoSyncKnobModel.h index 52fab30bb..9aaf48fea 100644 --- a/include/TempoSyncKnobModel.h +++ b/include/TempoSyncKnobModel.h @@ -52,10 +52,10 @@ public: const float _max, const float _step, const float _scale, Model * _parent, const QString & _display_name = QString() ); - virtual ~TempoSyncKnobModel(); + virtual ~TempoSyncKnobModel() override; - void saveSettings( QDomDocument & _doc, QDomElement & _this, const QString& name ); - void loadSettings( const QDomElement & _this, const QString& name ); + void saveSettings( QDomDocument & _doc, QDomElement & _this, const QString& name ) override; + void loadSettings( const QDomElement & _this, const QString& name ) override; TempoSyncMode syncMode() const { From fad89d6be77b97f1237dc3b8188840907e613cea Mon Sep 17 00:00:00 2001 From: liushuyu Date: Tue, 28 May 2019 15:12:29 -0600 Subject: [PATCH 319/445] i18n: update translations from Transifex --- data/locale/cs.ts | 8341 +++++++++++++++++++++++++++------------- data/locale/en.ts | 593 +-- data/locale/ko.ts | 8732 ++++++++++++++++++++++++++++-------------- data/locale/ru.ts | 7346 ++++++++++++++++++++++++----------- data/locale/sv.ts | 7493 ++++++++++++++++++++++++------------ data/locale/uk.ts | 6765 ++++++++++++++++++++++---------- data/locale/zh_TW.ts | 6856 +++++++++++++++++++++++---------- 7 files changed, 31457 insertions(+), 14669 deletions(-) diff --git a/data/locale/cs.ts b/data/locale/cs.ts index cf55f760f..ae1dcb2cd 100644 --- a/data/locale/cs.ts +++ b/data/locale/cs.ts @@ -2,93 +2,112 @@ AboutDialog + About LMMS O LMMS - Version %1 (%2/%3, Qt %4, %5) - Verze %1 (%2/%3, Qt %4, %5) - - - About - O LMMS - - - LMMS - easy music production for everyone - LMMS – snadné vytváření hudby pro každého - - - Authors - Autoři - - - Translation - Překlad - - - 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! - Aktuální jazyk není přeložen (nebo se jedná o angličtinu). - -Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit existující překlad, Vaše pomoc bude vítána! Stačí jen kontaktovat vývojáře! - - - License - Licence - - + LMMS LMMS - Involved - Spolupracovníci + + Version %1 (%2/%3, Qt %4, %5) + Verze %1 (%2/%3, Qt %4, %5) - Contributors ordered by number of commits: - Přispěvovatelé řazeni podle počtu příspěvků + + About + O LMMS + + LMMS - easy music production for everyone + LMMS – snadné vytváření hudby pro každého + + + Copyright © %1 Copyright © %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 + Autoři + + + + Involved + Spolupracovníci + + + + Contributors ordered by number of commits: + Přispěvatelé řazení podle počtu příspěvků: + + + + Translation + Překlad + + + + 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! + Chcete-li vylepšit stávající překlad, Vaše pomoc bude vítána! Stačí jen kontaktovat vývojáře! + + + + License + Licence AmplifierControlDialog + VOL HLA + Volume: Hlasitost: + PAN PAN + Panning: Panoráma: + LEFT LEVÝ + Left gain: Zesílení vlevo: + RIGHT PRAVÝ + Right gain: Zesílení vpravo: @@ -96,18 +115,22 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis AmplifierControls + Volume Hlasitost + Panning Panoráma + Left gain Zesílení vlevo + Right gain Zesílení vpravo @@ -115,10 +138,12 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis AudioAlsaSetupWidget + DEVICE ZAŘÍZENÍ + CHANNELS KANÁLY @@ -126,78 +151,98 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis AudioFileProcessorView + Open other sample Otevřít jiný sampl + 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. - Kliknutím sem můžete otevřít jiný audio soubor. Zobrazí se dialog, pomocí kterého si soubor můžete vybrat. Nastavení smyčky, počátečního a koncového bodu, zesílení apod. zůstanou nezměněná, takže to nemusí znít jako původní sampl. + Klepnutím sem můžete otevřít jiný audio soubor. Zobrazí se dialog, pomocí kterého si soubor můžete vybrat. Nastavení smyčky, počátečního a koncového bodu, zesílení apod. zůstanou nezměněná, takže to nemusí znít jako původní sampl. + Reverse sample Přehrávat pozpátku + If you enable this button, the whole sample is reversed. This is useful for cool effects, e.g. a reversed crash. Zapnete-li toto tlačítko, celý sampl bude přehráván pozpátku. Tato volba je užitečná pro zajímavé efekty jako např. pozpátku přehraná srážka. - Amplify: - Zesílení: - - - 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!) - Tímto otočným ovladačem můžete nastavit poměr zesílení. Pokud nastavíte hodnotu 100%, sampl se nezmění. Jinak se zesílí nebo ztiší (váš stávající soubor samplu tím nebude nijak ovlivněn!) - - - Startpoint: - Počáteční bod: - - - Endpoint: - Koncový bod: - - - Continue sample playback across notes - Přehrávat sampl napříč tóny - - - 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) - Povolení této možnosti způsobí, že se sampl bude přehrávat přes různé tóny – když změníte výšku tónu nebo když tón skončí před koncem samplu, bude další přehrávaný tón pokračovat tam, kde přestal. Pro obnovení přehrávání od začátku samplu vložte tón do spodní části kláves (< 20 Hz) - - + Disable loop Vypnout smyčku + This button disables looping. The sample plays only once from start to end. Toto tlačítko vypne smyčku. Sampl bude přehrán jen jednou od začátku do konce. + + Enable loop Zapnout smyčku + This button enables forwards-looping. The sample loops between the end point and the loop point. Toto tlačítko zapne smyčku směrem dopředu. Vzorek se bude vracet z koncového bodu na začátek. + This button enables ping-pong-looping. The sample loops backwards and forwards between the end point and the loop point. Toto tlačítko zapne smyčku typu ping-pong. Vzorek bude přehráván dopředu a zpět mezi koncovým bodem a začátkem smyčky. + + Continue sample playback across notes + Pokračovat v přehrávání samplu přes znějící tóny + + + + 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) + Povolení této možnosti způsobí, že se sampl bude přehrávat přes různé tóny – když změníte výšku tónu nebo když tón skončí před koncem samplu, bude další přehrávaný tón pokračovat tam, kde přestal. Pro obnovení přehrávání od začátku samplu vložte tón do spodní části klávesnice (< 20 Hz) + + + + Amplify: + Zesílení: + + + + 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!) + Tímto otočným ovladačem můžete nastavit poměr zesílení. Pokud nastavíte hodnotu 100%, sampl se nezmění. Jinak se zesílí nebo ztiší (váš stávající soubor samplu tím nebude nijak ovlivněn!) + + + + Startpoint: + Začátek samplu: + + + With this knob you can set the point where AudioFileProcessor should begin playing your sample. Tímto otočným ovladačem můžete nastavit bod, od kterého bude AudioFileProcessor přehrávat váš sampl. + + Endpoint: + Konec samplu: + + + With this knob you can set the point where AudioFileProcessor should stop playing your sample. Tímto otočným ovladačem můžete nastavit bod, ve kterém AudioFileProcessor zastaví přehrávání vašeho samplu. + Loopback point: Začátek smyčky: + With this knob you can set the point where the loop starts. Tímto otočným ovladačem můžete nastavit bod, kterým začíná smyčka. @@ -205,6 +250,7 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis AudioFileProcessorWaveView + Sample length: Délka samplu: @@ -212,26 +258,32 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis AudioJack + JACK client restarted Klient JACK je restartován + 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 bylo z nějakého důvodu shozeno JACKem. Proto byl ovladač JACK v LMMS restartován. Musíte znovu provést ruční připojení. + JACK server down - + JACK server byl zastaven + 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. - + Vypnutí a nové spuštění serveru JACK se nezdařilo. LMMS proto nemůže pokračovat. Uložte svůj projekt a restartujte JACK i LMMS. + CLIENT-NAME JMÉNO-KLIENTA + CHANNELS KANÁLY @@ -239,10 +291,12 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis AudioOss::setupWidget + DEVICE ZAŘÍZENÍ + CHANNELS KANÁLY @@ -250,10 +304,12 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis AudioPortAudio::setupWidget + BACKEND - BACKEND + OVLADAČ + DEVICE ZAŘÍZENÍ @@ -261,10 +317,12 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis AudioPulseAudio::setupWidget + DEVICE ZAŘÍZENÍ + CHANNELS KANÁLY @@ -272,6 +330,7 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis AudioSdl::setupWidget + DEVICE ZAŘÍZENÍ @@ -279,10 +338,12 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis AudioSndio::setupWidget + DEVICE ZAŘÍZENÍ + CHANNELS KANÁLY @@ -290,10 +351,12 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis AudioSoundIo::setupWidget + BACKEND - BACKEND + OVLADAČ + DEVICE ZAŘÍZENÍ @@ -301,61 +364,75 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis AutomatableModel + &Reset (%1%2) &Resetovat hodnoty (%1%2) + &Copy value (%1%2) &Kopírovat hodnoty (%1%2) + &Paste value (%1%2) &Vložit hodnoty (%1%2) + Edit song-global automation - Editovat automatizaci pro celou skladbu + Upravit hlavní automatizaci skladby + + Remove song-global automation + Odebrat hlavní automatizaci skladby + + + + Remove all linked controls + Odebrat všechny propojené ovládací prvky + + + Connected to %1 Připojeno k %1 + Connected to controller - Připojeno ke kontroléru + Připojeno k ovladači + Edit connection... - Editovat připojení... + Upravit připojení... + Remove connection Odebrat připojení + Connect to controller... - Připojit ke kontroléru... - - - Remove song-global automation - Odebrat obecnou automatizaci - - - Remove all linked controls - Odebrat všechny propojené ovládací prvky + Připojit k ovladači... AutomationEditor + Please open an automation pattern with the context menu of a control! - Otevřete prosím automatizační pattern pomocí kontextového menu ovládání! + Otevřete prosím automatizační záznam pomocí kontextové nabídky ovládání! + Values copied Hodnoty zkopírovány + All selected values were copied to the clipboard. Všechny označené hodnoty byly zkopírovány do schránky. @@ -363,149 +440,192 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis AutomationEditorWindow + Play/pause current pattern (Space) - Přehrát nebo pozastavit přehrávání aktuálního patternu (mezerník) + Přehrát/Pozastavit přehrávání aktuálního záznamu (mezerník) + 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. - Klikněte zde, pokud chcete přehrát aktuální pattern. To je šikovné při editaci, neboť pattern je automaticky přehráván ve smyčce. + Klepněte sem, pokud chcete přehrát aktuální záznam. To je užitečné při editaci. Záznam je automaticky přehráván ve smyčce. + Stop playing of current pattern (Space) - Zastavit přehrávání aktuálního patternu (mezerník) + Zastavit přehrávání aktuálního záznamu (mezerník) + Click here if you want to stop playing of the current pattern. - Klikněte zde, pokud chcete zastavit přehrávání aktuálního patternu. + Klepněte sem, pokud chcete zastavit přehrávání aktuálního záznamu. + + Edit actions + Akce úprav + + + Draw mode (Shift+D) Režim kreslení (Shift+D) + Erase mode (Shift+E) Režim mazání (Shift+E) + Flip vertically Převrátit vertikálně + Flip horizontally Převrátit horizontálně + Click here and the pattern will be inverted.The points are flipped in the y direction. - Klikněte sem, pokud chcete převrátit pattern. Body budou převráceny v ose y. + Klepněte sem, pokud chcete převrátit záznam. Body budou převráceny v ose y. + Click here and the pattern will be reversed. The points are flipped in the x direction. - Klikněte sem, pokud chcete převrátit pattern. Body budou převráceny v ose x. + Klepněte sem, pokud chcete převrátit záznam. Body budou převráceny v ose 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. - Klikněte sem, pokud chcete aktivovat režim kreslení. V tomto výchozím a nejčastěji užívaném režimu lze přidávat a přesunovat jednotlivé hodnoty. Pro aktivaci můžete využít též klávesové zkratky Shift+D. + Klepněte sem, pokud chcete aktivovat režim kreslení. V tomto výchozím a nejčastěji užívaném režimu lze přidávat a přesunovat jednotlivé hodnoty. Pro aktivaci můžete využít též klávesové zkratky "Shift+D". + 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. - Klikněte sem, pokud chcete aktivovat režim mazání. V tomto režimu lze mazat jednotlivé hodnoty. Pro aktivaci můžete využít též klávesové zkratky Shift+E. - - - Discrete progression - Terasovitý průběh - - - Linear progression - Lineární průběh - - - Cubic Hermite progression - Křivkovitý průběh - - - Tension value for spline - Hodnota napětí pro křivku - - - 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. - Vyšší hodnota napětí vytvoří hladší křivku, ale více se vzdálí od zadaných hodnot. Nižší hodnota napětí upřednostní výchozí sklon křivky v každém kontrolním bodě. - - - 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. - Kliknutím sem vyberete terasovitý vývoj pro tento automatizační pattern. Hodnota připojeného objektu zůstane konstantní mezi ovládacími body a okamžitě nastavena na novou hodnotu, když se dosáhne dalšího ovládacího bodu. - - - 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. - Kliknutím sem vyberete lineární vývoj pro tento automatizační pattern. Hodnota připojeného objektu se změní ve stabilní frekvenci mezi ovládacími body, aby postupně došlo k dosažení dalšího kontrolního bodu. - - - 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. - Kliknutím sem vyberte cubic hermite vývoj pro tento automatizační pattern. Hodnota připojeného objektu se změní po plynulé křivce a lehce přejde do vrchních a spodních bodů. - - - Cut selected values (%1+X) - Vyjmout označené hodnoty (%1+X) - - - Copy selected values (%1+C) - Kopírovat označené hodnoty (%1+C) - - - Paste values from clipboard (%1+V) - Vložit hodnoty ze schránky (%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. - Klikněte zde, pokud chcete označené hodnoty vyjmout a uložit do schránky. Vložit je pak můžete kdekoliv v libovolném patternu pomocí tlačítka Vložit. - - - 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. - Klikněte zde, pokud chcete označené hodnoty zkopírovat do schránky. Vložit je pak můžete kdekoliv v libovolného patternu pomocí tlačítka Vložit. - - - Click here and the values from the clipboard will be pasted at the first visible measure. - Kliknete-li zde, budou hodnoty ze schránky vloženy do prvního viditelného taktu. - - - Tension: - Napětí: - - - Automation Editor - no pattern - Automatizační editor - žádný pattern - - - Automation Editor - %1 - Automatizační editor - %1 - - - Edit actions - Upravit akce + Klepněte sem, pokud chcete aktivovat režim mazání. V tomto režimu lze mazat jednotlivé hodnoty. Pro aktivaci můžete využít též klávesové zkratky "Shift+E". + Interpolation controls Ovládání interpolace - Timeline controls - Ovládání časové osy + + Discrete progression + Terasovitý průběh + + Linear progression + Lineární průběh + + + + Cubic Hermite progression + Křivkovitý průběh + + + + Tension value for spline + Hodnota napětí pro křivku + + + + 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. + Vyšší hodnota napětí vytvoří hladší křivku, ale více se vzdálí od zadaných hodnot. Nižší hodnota napětí upřednostní výchozí sklon křivky v každém kontrolním bodě. + + + + 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. + Klepnutím sem vyberete terasovitý vývoj pro tento automatizační záznam. Hodnota připojeného objektu zůstane neměnná mezi ovládacími body a okamžitě bude nastavena na novou hodnotu, když se dosáhne dalšího ovládacího bodu. + + + + 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. + Klepnutím sem vyberete lineární vývoj pro tento automatizační záznam. Hodnota připojeného objektu bude mezi ovládacími body měněna přímočaře, aby postupně došlo k dosažení dalšího kontrolního bodu. + + + + 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. + Klepnutím sem vyberte vývoj typu cubic hermite pro tento automatizační záznam. Hodnota připojeného objektu se změní po plynulé křivce a hladce přejde do vrchních i spodních bodů. + + + + Tension: + Napětí: + + + + Cut selected values (%1+X) + Vyjmout označené hodnoty (%1+X) + + + + Copy selected values (%1+C) + Kopírovat označené hodnoty (%1+C) + + + + Paste values from clipboard (%1+V) + Vložit hodnoty ze schránky (%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. + Klepněte sem, pokud chcete označené hodnoty vyjmout a uložit do schránky. Vložit je pak můžete kdekoliv v libovolném záznamu pomocí tlačítka Vložit. + + + + 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. + Klepněte sem, pokud chcete označené hodnoty zkopírovat do schránky. Vložit je pak můžete kdekoliv v libovolném záznamu pomocí tlačítka Vložit. + + + + Click here and the values from the clipboard will be pasted at the first visible measure. + Klepnete-li sem, budou hodnoty ze schránky vloženy do prvního viditelného taktu. + + + Zoom controls Ovládání zvětšení + Quantization controls Ovládání kvantizace + + Quantization + Kvantizace + + + + 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. + Kvantizace. Nastaví nejmenší velikost kroku pro body automatizace. Ve výchozím stavu také nastaví délku a vymazává další body v rozsahu. Stisknutím <Ctrl> zrušíte toto chování. + + + + + Automation Editor - no pattern + Editor automatizace – žádný záznam + + + + + Automation Editor - %1 + Editor automatizace – %1 + + + Model is already connected to this pattern. - Model je již k tomuto paternu připojen + Model je již k tomuto záznamu připojen. AutomationPattern + Drag a control while pressing <%1> Ovládací prvek táhni při stisknutém <%1> @@ -513,142 +633,174 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis AutomationPatternView + double-click to open this pattern in automation editor - dvojklikem otevřít tento pattern v automatizačním editoru + dvojklikem otevřít tento pattern v Editoru automatizace + Open in Automation editor - Otevřít v automatizačním editoru + Otevřít v Editoru automatizace + Clear Vyčistit + Reset name - Resetovat jméno + Obnovit výchozí jméno + Change name Změnit jméno + + Set/clear record + Zapnout/Vypnout záznam + + + + Flip Vertically (Visible) + Převrátit vertikálně (viditelné) + + + + Flip Horizontally (Visible) + Převrátit horizontálně (viditelné) + + + %1 Connections %1 Připojení + Disconnect "%1" Odpojit "%1" - Set/clear record - Nastav/vyčisti záznam - - - Flip Vertically (Visible) - Převrátit vertikálně (viditelně) - - - Flip Horizontally (Visible) - Převrátit horizontálně (viditelně) - - + Model is already connected to this pattern. - Model je již k tomuto paternu připojen. + Model je již k tomuto záznamu připojen. AutomationTrack + Automation track - Automatizační stopa + Stopa automatizace BBEditor + Beat+Bassline Editor - Editor bicích a basů + Editor bicích/basů + Play/pause current beat/bassline (Space) - Přehrát/pozastavit přehrávání aktuálního patternu bicích/basů (mezerník) + Přehrát/Pozastavit přehrávání aktuálního záznamu bicích/basů (mezerník) + Stop playback of current beat/bassline (Space) - Zastavit přehrávání aktuálního patternu bicích/basů (mezerník) + Zastavit přehrávání aktuálního záznamu bicích/basů (mezerník) + Click here to play the current beat/bassline. The beat/bassline is automatically looped when its end is reached. - Klikněte sem, pokud chcete přehrát aktuální pattern bicích/basů. Bicí/basy jsou automaticky přehrávány ve smyčce. + Klepněte sem, pokud chcete přehrát aktuální záznam bicích/basů. Bicí/basy jsou automaticky přehrávány ve smyčce. + Click here to stop playing of current beat/bassline. - Klikněte sem, pokud chcete zastavit přehrávání aktuálního patternu bicích/basů. - - - Add beat/bassline - Přidat bicí/basy - - - Add automation-track - Přidat automatizační stopu - - - Remove steps - Odstranit kroky - - - Add steps - Přidat kroky + Klepněte sem, pokud chcete zastavit přehrávání aktuálního záznamu bicích/basů. + Beat selector Výběr rytmu + Track and step actions - Akce stopy a kroku + Akce stopy a kroků + + Add beat/bassline + Přidat bicí/basy + + + + Add sample-track + Přidat stopu samplů + + + + Add automation-track + Přidat stopu automatizace + + + + Remove steps + Odstranit kroky + + + + Add steps + Přidat kroky + + + Clone Steps Klonovat kroky - - Add sample-track - Přidat automatizační stopu - BBTCOView + Open in Beat+Bassline-Editor - Otevřít v editoru bicích a basů + Otevřít v editoru bicích/basů + Reset name Resetovat jméno + Change name Změnit jméno + Change color Změnit barvu + Reset color to default - REsetovat barvy do základních + Obnovit výchozí barvy BBTrack + Beat/Bassline %1 - Bicí a basy %1 + Bicí/basy %1 + Clone of %1 Klon z %1 @@ -656,26 +808,32 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis BassBoosterControlDialog + FREQ FREKV + Frequency: Frekvence: + GAIN - ZISK + ZES + Gain: - Zisk: + Zesílení: + RATIO POMĚR + Ratio: Poměr: @@ -683,14 +841,17 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis BassBoosterControls + Frequency Frekvence + Gain - Zisk + Zesílení + Ratio Poměr @@ -698,82 +859,98 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis BitcrushControlDialog + IN IN + OUT OUT + + GAIN ZISK + Input Gain: - + Zesílení vstupu: - NOIS + + NOISE ŠUM + Input Noise: Vstup šumu: + Output Gain: - + Zesílení výstupu: + CLIP - + OŘÍZ + Output Clip: - - - - Rate - Rychlost + Oříznutí výstupu: + Rate Enabled - + Frekvence zapnuta + Enable samplerate-crushing - - - - Depth - + Zapnout drtič vzorkovací frekvence + Depth Enabled - + Hloubka zapnuta + Enable bitdepth-crushing - + Zapnout drtič bitové hloubky + + FREQ + FREKV + + + Sample rate: - + Vzorkovací frekvence: - STD - + + STEREO + STEREO + Stereo difference: - + Stereo rozdíl: - Levels - Úrovně + + QUANT + KVANT + Levels: Úrovně: @@ -781,501 +958,645 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis CaptionMenu + &Help &Nápověda + Help (not available) - Help (nedostupný) + Nápověda (nedostupná) CarlaInstrumentView + Show GUI Ukázar grafické rozhraní + Click here to show or hide the graphical user interface (GUI) of Carla. - + Klepněte sem pro zobrazení nebo skrytí grafického uživatelského rozhraní (GUI) Carla. Controller + Controller %1 - Kontrolér %1 + Ovladač %1 ControllerConnectionDialog + Connection Settings Nastavení připojení + MIDI CONTROLLER - MIDI KONTROLÉR + MIDI OVLADAČ + Input channel Vstupní kanál + CHANNEL KANÁL + Input controller - Vstupní kontrolér + Vstupní ovladač + CONTROLLER - KONTROLÉR + OVLADAČ + + Auto Detect Autodetekce + MIDI-devices to receive MIDI-events from - MIDI-zařízení k přijmu MIDI-události + MIDI zařízení k přijmu MIDI události + USER CONTROLLER - UŽIVATELSKÝ KONTROLÉR + UŽIVATELSKÝ OVLADAČ + MAPPING FUNCTION MAPOVACÍ FUNKCE + OK OK + Cancel Zrušit + LMMS LMMS + Cycle Detected. - Detekován cyklus. + Zjištěno zacyklení. ControllerRackView + Controller Rack - Kontroléry + Ovladače + Add Přidat + Confirm Delete Potvrdit smazání + Confirm delete? There are existing connection(s) associated with this controller. There is no way to undo. - + Opravdu smazat? Je (jsou) zde propojení na tento ovladač. Nebude možné vrátit se zpět. ControllerView + Controls Ovládací prvky + Controllers are able to automate the value of a knob, slider, and other controls. Kontroléry jsou schopny automatizovat nastavení otočných ovladačů, táhel a dalších řídicích prvků. + Rename controller - Přejmenovat kontrolér + Přejmenovat ovladač + Enter the new name for this controller - Vložte nové jméno pro tento kontrolér - - - &Remove this controller - - - - Re&name this controller - + Vložte nové jméno pro tento ovladač + LFO LFO + + + &Remove this controller + Odst&ranit tento ovladač + + + + Re&name this controller + Přejme&novat tento ovladač + CrossoverEQControlDialog + Band 1/2 Crossover: - + Přechod mezi pásmy 1/2: + Band 2/3 Crossover: - + Přechod mezi pásmy 2/3: + Band 3/4 Crossover: - + Přechod mezi pásmy 3/4: + Band 1 Gain: - + Zesílení pásma 1: + Band 2 Gain: - + Zesílení pásma 2: + Band 3 Gain: - + Zesílení pásma 3: + Band 4 Gain: - + Zesílení pásma 4: + Band 1 Mute - + Ztlumení pásma 1 + Mute Band 1 - + Ztlumit pásmo 1 + Band 2 Mute - + Ztlumení pásma 2 + Mute Band 2 - + Ztlumit pásmo 2 + Band 3 Mute - + Ztlumení pásma 3 + Mute Band 3 - + Ztlumit pásmo 3 + Band 4 Mute - + Ztlumení pásma 4 + Mute Band 4 - + Ztlumit pásmo 4 DelayControls + Delay Samples - Vzorky zpoždění + Zpoždění vzorků + Feedback - + Zpětná vazba + Lfo Frequency - + Frekvence LFO + Lfo Amount - + Hloubka LFO + Output gain - Zisk výstupu + Zesílení výstupu DelayControlsDialog - Lfo Amt - + + DELAY + ZPOŽ + Delay Time Délka zpoždění - Feedback Amount - - - - Lfo - - - - Out Gain - - - - Gain - Zisk - - - DELAY - DELAY - - + FDBK - FDBK + ZPVAZ + + Feedback Amount + Hloubka zpětné vazby + + + RATE - POMĚR + RYCH + + Lfo + LFO + + + AMNT MNOŽ + + + Lfo Amt + Hloubka LFO + + + + Out Gain + Zesílení výstupu + + + + Gain + Zesílení + DualFilterControlDialog - Filter 1 enabled - Filtr 1 zapnutý - - - Filter 2 enabled - - - - Click to enable/disable Filter 1 - - - - Click to enable/disable Filter 2 - - - + + FREQ FREKV + + Cutoff frequency - Frekvence seříznutí + Frekvence oříznutí + + RESO REZON + + Resonance Rezonance + + GAIN - ZISK + ZESIL + + Gain - Zisk + Zesílení + MIX - + POMĚR + Mix - + Poměr + + + + Filter 1 enabled + Filtr 1 zapnutý + + + + Filter 2 enabled + Filtr 2 zapnutý + + + + Click to enable/disable Filter 1 + Klepněte pro zapnutí/vypnutí filtru 1 + + + + Click to enable/disable Filter 2 + Klepněte pro zapnutí/vypnutí filtru 2 DualFilterControls + Filter 1 enabled Filtr 1 zapnutý + Filter 1 type - Filtr 1 typ + Typ filtru 1 + Cutoff 1 frequency - + Frekvence oříznutí 1 + Q/Resonance 1 - + Q/rezonance 1 + Gain 1 - + Zesílení 1 + Mix - + Mix + Filter 2 enabled - + Filtr 1 zapnutý + Filter 2 type - + Typ filtru 2 + Cutoff 2 frequency - + Frekvence oříznutí 2 + Q/Resonance 2 - + Q/rezonance 2 + Gain 2 - + Zesílení 2 + + LowPass - + Dolní propust + + HiPass - + Horní propust + + BandPass csg - + Pásmová propust csg + + BandPass czpg - + Pásmová propust czpg + + Notch - + Pásmová zádrž + + Allpass - + Všepásmový filtr + + Moog - + Moogův filtr + + 2x LowPass - + 2x dolní propust + + RC LowPass 12dB - + RC dolní propust 12dB + + RC BandPass 12dB - + RC pásmová propust 12dB + + RC HighPass 12dB - + RC horní propust 12dB + + RC LowPass 24dB - + RC dolní propust 24dB + + RC BandPass 24dB - + RC pásmová propust 24dB + + RC HighPass 24dB - + RC horní propust 24dB + + Vocal Formant Filter - + Vokální formantový filtr + + 2x Moog - + 2x Moogův filtr + + SV LowPass - + SV dolní propust + + SV BandPass - + SV pásmová propust + + SV HighPass - + SV horní propust + + SV Notch - + SV pásmová zádrž + + Fast Formant - + Rychlý formantový filtr + + Tripole - + Třípólový filtr Editor + + Transport controls + Řízení přenosu + + + Play (Space) - + Přehrát (mezerník) + Stop (Space) - + Zastavit (mezerník) + Record Nahrávat + Record while playing Nahrávat při přehrávání - - Transport controls - Řízení přenosu - Effect + Effect enabled Efekt aktivován + Wet/Dry mix - Wet/Dry mix + Poměr zpracovaného/původního signálu + Gate Brána + Decay - Doznívání + Pokles EffectChain + Effects enabled Efekty aktivovány @@ -1283,10 +1604,12 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis EffectRackView + EFFECTS CHAIN ŘETĚZ EFEKTŮ + Add effect Přidat efekt @@ -1294,22 +1617,28 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis EffectSelectDialog + Add effect Přidat efekt + + Name Název + Type Typ + Description Popis + Author Autor @@ -1317,54 +1646,67 @@ Máte-li zájem o překlad LMMS do jiného jazyka, nebo chcete-li vylepšit exis EffectView + Toggles the effect on or off. Zapnout nebo vypnout efekty. + On/Off Zap/Vyp + W/D - W/D + POM + Wet Level: - Wet Hodnota: + Úroveň zpracovaného signálu: + The Wet/Dry knob sets the ratio between the input signal and the effect signal that forms the output. - Wet/Dry otočný ovladač nastavuje poměr mezi vstupním signálem a signálem efektu, který formuje výstup. + Otočný ovladač Poměr nastavuje poměr mezi vstupním signálem a signálem efektu, který formuje výstup. + DECAY - DOZNÍ + POKLES + Time: - Čas: + Délka: + 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. - Otočný ovladač Doznívání ovládá, kolik bufferů ticha musí projít před tím, než plugin přestane zpracovávat. Menší hodnoty zredukují využití CPU, ale můžou způsobit uříznutí ozvěn. + Otočný ovladač Útlum nastavuje, kolik bufferů ticha musí proběhnout před tím, než plugin přestane zpracovávat. Menší hodnoty zredukují přetížení CPU, ale mohou způsobit oříznutí na konci zpožďovacích a dozvukových efektů. + GATE - BRÁNA + BRÁ + Gate: Brána: + The Gate knob controls the signal level that is considered to be 'silence' while deciding when to stop processing signals. - Otočný ovladač Brána určuje sílu signálu, který je považován za 'ticho' při rozhodování, kdy skončit se zpracováním signálů. + Otočný ovladač Brána určuje sílu signálu, který je považován za "ticho" při rozhodování, kdy skončit se zpracováním signálů. + Controls Ovladače + 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. @@ -1378,17 +1720,33 @@ The Gate knob controls the 'given threshold' for the effect's auto shutdown. Th 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. - + Efektové pluginy fungují jako zřetězená série efektů, kde signál bude postupně zpracováván shora dolů. + +Přepínač Zapnuto/Vypnuto vám umožní v libovolném časovém okamžiku daný plugin odpojit. + +Otočný ovladač Poměr řídí vyvážení mezi vstupním a již zpracovaným signálem ve výsledném výstupu efektu. Vstup je v této fázi shodný s výstupem předchozího efektu. Takže když je Poměr nastaven na nízkou hodnotu, obsahuje signál všechny předchozí efekty. + +Otočný ovladač Útlum určuje, jak dlouho bude zpracovávání signálu pokračovat po skončení noty. Efekt přestane zpracovávat signál, když hlasitost klesne pod hodnotu daného prahu v daném časovém úseku. Tento ovladač nastavuje právě "daný časový úsek". Delší časy vyžadují více výkonu procesoru, takže pro většinu efektů by měla být nastavena nízká hodnota. Naopak je potřeba nastavit vyšší hodnotu pro efekty, které vytvářejí delší úseky ticha, jako je např. echo (delay). +Otočný ovladač Brána určuje "daný práh" pro automatické ukončení efektu. + +Počítání délky "daného časového úseku" začíná bezprostředně poté, co úroveň zpracovávaného signálu poklesne pod úroveň určenou tímto ovladačem. + +Tlačítko Ovladače otevře dialogové okno pro úpravu parametrů efektu. + +Klepnutí pravým tlačítkem myši vyvolá kontextovou nabídku, kde můžete měnit pořadí, ve kterém budou efekty zpracovávány, nebo můžete efekt úplně odstranit. + Move &up Posunout &nahoru + Move &down - Posunout &dolu + Posunout &dolů + &Remove this plugin &Odstranit tento plugin @@ -1396,494 +1754,621 @@ Right clicking will bring up a context menu where you can change the order in wh EnvelopeAndLfoParameters + Predelay - + Předzpoždění + Attack - Nástup + Náběh + Hold - + Držení + Decay - Dozněv + Pokles + Sustain - + Držení + Release - Uvolnění + Doznění + Modulation Modulace + LFO Predelay - + Předzpoždění LFO + LFO Attack - + Náběh LFO + LFO speed - + Rychlost LFO + LFO Modulation - + Modulace LFO + LFO Wave Shape - + Tvar vlny LFO + Freq x 100 Frekvence x 100 + Modulate Env-Amount - Úroveň modulace + Hloubka modulace EnvelopeAndLfoView + + DEL - + PŘED + Predelay: - + Předzpoždění: + Use this knob for setting predelay of the current envelope. The bigger this value the longer the time before start of actual envelope. - + Tento otočný ovladač nastavuje předzpoždění (predelay) aktuální obálky. Zvýšením hodnoty se prodlouží čas před začátkem obálky. + + ATT - + NÁB + Attack: - + Náběh: + 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. - + Tento otočný ovladač nastavuje náběh (attack) u aktuální obálky. Zvýšením hodnoty se prodlouží délka náběhu obálky. Zvolte nižší hodnotu pro nástroje typu piano a vyšší pro smyčce. + HOLD - HOLD + ZADR + Hold: - Hold: + Zadržení: + 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. - + Tento otočný ovladač nastavuje délku držení (hold) u aktuální obálky. Zvýšením hodnoty se prodlouží část obálky, která zůstává na úrovni náběhu (attack) ještě před začátkem útlumu (decay) na úroveň vydržení (sustain). + DEC - DEC + POK + Decay: - Doznívání: + Pokles: + 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. - + Tento otočný ovladač nastavuje délku útlumu (decay) u aktuální obálky. Zvýšením hodnoty se prodlouží část obálky, potřebná k zeslabení z úrovně náběhu (attack) na úroveň vydržení (sustain). Zvolte nižší hodnotu pro nástroje typu piano. + SUST - SUST + DRŽE + Sustain: - Sustain: + Držení: + 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. - + Tento otočný ovladač nastavuje vydržení (sustain) u aktuální obálky. Zvýšením hodnoty se navýší úroveň, na které obálka zůstává před poklesem na nulu. + REL - REL + DOZ + Release: - Release: + Doznění: + 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. - + Tento otočný ovladač nastavuje délku uvolnění (release) u aktuální obálky. Zvýšením hodnoty se prodlouží část obálky, potřebná k zeslabení z úrovně vydržení (sustain) na nulovou úroveň. Zvolte vyšší hodnotu pro nástroje s měkkým zvukem, jako např. smyčce. + + AMT - + MOD + + Modulation amount: Hloubka modulace: + 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. - + Tento otočný ovladač nastavuje hloubku modulace u aktuální obálky. Zvýšení této hodnoty v závislosti na velikosti (např. hlasitosti nebo frekvence odstřihnutí) způsobí větší ovlivnění touto obálkou. + LFO predelay: - + Předzpoždění 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. - + Tento otočný ovladač nastavuje délku předzpoždění (predelay) aktuálního LFO. Zvýšením hodnoty se prodlouží čas před spuštěním kmitání LFO. + LFO- attack: - + Náběh 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. - + Tento otočný ovladač nastavuje délku náběhu (attack) u aktuálního LFO. Zvýšením hodnoty se prodlouží čas potřebný pro zvýšení amplitudy LFO na maximum. + SPD - + RYCH + LFO speed: - + Rychlost 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. - + Tento otočný ovladač nastavuje rychlost u aktuálního LFO. Zvýšením hodnoty se zrychlí kmitání LFO a průběh vašeho efektu. + 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. - + Tento otočný ovladač nastavuje hloubku modulace u aktuálního LFO. Zvýšení hodnoty v závislosti na velikosti (např. hlasitosti nebo frekvence odstřihnutí) způsobí větší ovlivnění tímto LFO. + Click here for a sine-wave. - Klikněte zde pro sinusovou vlnu. + Klepněte sem pro sinusovou vlnu. + Click here for a triangle-wave. - Klikněte zde pro trojúhelníkovou vlnu. + Klepněte sem pro trojúhelníkovou vlnu. + Click here for a saw-wave for current. - Klikněte zde pro pilovitou vlnu. + Klepněte sem pro pilovitou vlnu. + Click here for a square-wave. - Klikněte zde pro pravoúhlou vlnu. + Klepněte sem pro pravoúhlou vlnu. + Click here for a user-defined wave. Afterwards, drag an according sample-file onto the LFO graph. - + Klepněte sem pro vlastní vlnu. Poté přetáhněte zvolený soubor samplu do grafického okna LFO. + + Click here for random wave. + Klepněte sem pro náhodnou vlnu. + + + FREQ x 100 FREKVENCE x 100 + Click here if the frequency of this LFO should be multiplied by 100. - + Klepněte sem, pokud má být frekvence LFO vynásobena x100. + multiply LFO-frequency by 100 - + vynásobit frekvenci LFO x100 + MODULATE ENV-AMOUNT - + MODULOVAT OBÁLKU + Click here to make the envelope-amount controlled by this LFO. - + Klepněte sem, pokud má být množství obálky řízeno tímto LFO. + control envelope-amount by this LFO - + řízení množství obálky tímto LFO + ms/LFO: - + ms/LFO: + Hint Rada + Drag a sample from somewhere and drop it in this window. Sampl odněkud přetáhněte a pusťte jej v tomto okně. - - Click here for random wave. - Klikněte zde pro náhodnou vlnu. - EqControls + Input gain - Zisk vstupu + Zesílení vstupu + Output gain - Zisk výstupu + Zesílení výstupu + Low shelf gain - + Zesílení dolního šelfu + Peak 1 gain - + Zesílení špičky 1 + Peak 2 gain - + Zesílení špičky 2 + Peak 3 gain - + Zesílení špičky 3 + Peak 4 gain - + Zesílení špičky 4 + High Shelf gain - + Zesílení horního šelfu + HP res - + Rezonance horní propusti + Low Shelf res - + Rezonance dolního šelfu + Peak 1 BW - + Šířka pásma špičky 1 + Peak 2 BW - + Šířka pásma špičky 2 + Peak 3 BW - + Šířka pásma špičky 3 + Peak 4 BW - + Šířka pásma špičky 4 + High Shelf res - + Rezonance horního šelfu + LP res - + Rezonance dolní propusti + HP freq - + Frekvence horní propusti + Low Shelf freq - + Frekvence dolního šelfu + Peak 1 freq - + Frekvence špičky 1 + Peak 2 freq - + Frekvence špičky 2 + Peak 3 freq - + Frekvence špičky 3 + Peak 4 freq - + Frekvence špičky 3 + High shelf freq - + Frekvence špičky 4 + LP freq - + Frekvence dolní propusti + HP active - + Horní propust aktivní + Low shelf active - + Dolní šelf aktivní + Peak 1 active - + Špička 1 aktivní + Peak 2 active - + Špička 2 aktivní + Peak 3 active - + Špička 3 aktivní + Peak 4 active - + Špička 4 aktivní + High shelf active - + Horní šelf aktivní + LP active - + Dolní propust aktivní + LP 12 - + DP 12 + LP 24 - + DP 24 + LP 48 - + DP 48 + HP 12 - + HP 12 + HP 24 - + HP 24 + HP 48 - + HP 48 + low pass type - + typ dolní propusti + high pass type - + typ horní propusti + Analyse IN - + Analýza VSTUPU + Analyse OUT - + Analýza VÝSTUPU EqControlsDialog + HP - + HP + Low Shelf - + Dolní šelf + Peak 1 - + Špička 1 + Peak 2 - + Špička 2 + Peak 3 - + Špička 3 + Peak 4 - + Špička 4 + High Shelf - + Horní šelf + LP - + DP + In Gain - + Zesílení vstupu + + + Gain - Zisk + Zesílení + Out Gain - + Zesílení výstupu + Bandwidth: Šířka pásma: + + Octave + oktávy + + + Resonance : Rezonance: + Frequency: Frekvence: + lp grp - + dp skup + hp grp - - - - Octave - Oktáva + hp skup EqHandle + Reso: Rezon: + BW: - + ŠPás: + + Freq: Frekv: @@ -1891,174 +2376,243 @@ Right clicking will bring up a context menu where you can change the order in wh ExportProjectDialog + Export project Exportovat projekt + Output Výstup + File format: Formát souboru: + Samplerate: Vzorkovací frekvence: + 44100 Hz 44100 Hz + 48000 Hz 48000 Hz + 88200 Hz 88200 Hz + 96000 Hz 96000 Hz + 192000 Hz 192000 Hz - Bitrate: - Bitrate: - - - 64 KBit/s - 64 KBit/s - - - 128 KBit/s - 128 KBit/s - - - 160 KBit/s - 160 KBit/s - - - 192 KBit/s - 192 KBit/s - - - 256 KBit/s - 256 KBit/s - - - 320 KBit/s - 320 KBit/s - - + Depth: Hloubka: + 16 Bit Integer - 16 Bit Integer + 16 bitů celočíselně + + 24 Bit Integer + 24 bitů celočíselně + + + 32 Bit Float - 32 Bit Float + 32 bitů s plovoucí čárkou - Please note that not all of the parameters above apply for all file formats. - + + Stereo mode: + Režim stereo: + + Stereo + Stereo + + + + Joint Stereo + Joint stereo + + + + Mono + Mono + + + + Bitrate: + Datový tok: + + + + 64 KBit/s + 64 kbit/s + + + + 128 KBit/s + 128 kbit/s + + + + 160 KBit/s + 160 kbit/s + + + + 192 KBit/s + 192 kbit/s + + + + 256 KBit/s + 256 kbit/s + + + + 320 KBit/s + 320 kbit/s + + + + Use variable bitrate + Použít proměnlivý datový tok + + + Quality settings Nastavení kvality + Interpolation: Interpolace: + Zero Order Hold - + Zero-order hold + Sinc Fastest - + Sinc nejrychlejší + Sinc Medium (recommended) - + Sinc střední (doporučeno) + Sinc Best (very slow!) - + Sinc nejlepší (velmi pomalé!) + Oversampling (use with care!): - Převzorkování (používejte opatrně!) + Převzorkování (používejte opatrně!): + 1x (None) - + 1x (žádné) + 2x 2x + 4x 4x + 8x 8x - Start - + + Export as loop (remove end silence) + Exportovat jako smyčku (odstranění ticha na konci) + + Export between loop markers + Exportovat obsah smyčky + + + + Start + Začít + + + Cancel Zrušit - Export as loop (remove end silence) - Export do smyčky (odstranění ticha na konci) - - - Export between loop markers - Export obsahu smyčky - - + Could not open file Nemohu otevřít soubor + + 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! + Nelze otevřít soubor %1 pro zápis. +Ověřte si prosím, zda máte povolen zápis do souboru a do složky, ve které je umístěn, a zkuste znovu! + + + Export project to %1 Exportovat projekt do %1 + Error Chyba + Error while determining file-encoder device. Please try to choose a different output format. - Chyba při určení souboru zařízení enkodéru. Zkuste prosím vybrat jiný výstupní formát. + Chyba při zjišťování souboru enkodéru. Zkuste prosím vybrat jiný výstupní formát. + Rendering: %1% Renderuji: %1% - - 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! - - Fader + + Please enter a new value between %1 and %2: Vložte prosím novou hodnotu mezi %1 a %2: @@ -2066,6 +2620,7 @@ Please make sure you have write permission to the file and the directory contain FileBrowser + Browser Prohlížeč @@ -2073,123 +2628,151 @@ Please make sure you have write permission to the file and the directory contain FileBrowserTreeWidget + Send to active instrument-track - Poslat do aktivní stopy nástroje - - - Open in new instrument-track/B+B Editor - - - - Loading sample - Načítám sampl - - - Please wait, loading sample for preview... - Počkejte prosím, načítám sampl pro náhled... - - - --- Factory files --- - + Odeslat do aktivní stopy nástroje + Open in new instrument-track/Song Editor - + Otevřít v nové nástrojové stopě / Editoru skladby + + Open in new instrument-track/B+B Editor + Otevřít v nové nástrojové stopě / editoru bicich/basů + + + + Loading sample + Načítám vzorek + + + + Please wait, loading sample for preview... + Počkejte prosím, načítám vzorek pro náhled... + + + Error Chyba + does not appear to be a valid nevypadá, že je platný + file soubor + + + --- Factory files --- + --- Tovární soubory --- + FlangerControls + Delay Samples - Vzorky zpoždění + Zpoždění vzorků + Lfo Frequency - + Frekvence LFO + Seconds Sekund + Regen - + Obnov + Noise Šum + Invert - + Převrátit FlangerControlsDialog + + DELAY + ZPOŽ + + + Delay Time: Délka zpoždění: - Feedback Amount: - Velikost zpětné vazby: - - - White Noise Amount: - Množství bílého šumu: - - - DELAY - DELAY - - + RATE POMĚR - Rate: - Poměr: + + Period: + Perioda: + AMNT MNOŽ + Amount: Množství: + FDBK - FDBK + ZP. VAZ + + Feedback Amount: + Velikost zpětné vazby: + + + NOISE ŠUM + + White Noise Amount: + Množství bílého šumu: + + + Invert - + Převrátit FxLine + Channel send amount - + Množství odeslaného kanálu + 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. @@ -2197,85 +2780,126 @@ In order to route the channel to another channel, select the FX channel and clic You can remove and move FX channels in the context menu, which is accessed by right-clicking the FX channel. - + Efektový (FX) kanál přijímá vstup z jedné nebo více nástrojových stop. +Ten může být následně směrován do dalších efektových kanálů. LMMS automaticky zabraňuje vzniku nekonečných smyček a nedovoluje provést propojení, které by ke vzniku smyčky mohlo vést. + +Chcete-li směrovat kanál do jiného kanálu, vyberte efektový kanál a klepněte na tlačítko "SEND" v kanálu, který chcete odeslat. Otočný ovladač pod tlačítkem "SEND" určuje množství signálu, které bude do kanálu odesláno. + +Efektové kanály můžete odstranit nebo přesunout v kontextové nabídce, která je dostupná po klepnutí pravým tlačítkem myši na efektový kanál. + + Move &left - Přesun do&leva + Přesunout do&leva + Move &right Přesun dop&rava + Rename &channel - + Přejmenovat &kanál + R&emove channel - + Př&esunout kanál + Remove &unused channels - + Odstranit nepo&užívané kanály FxMixer + Master - + Hlavní + + + FX %1 - + Efekt %1 + + + + Volume + Hlasitost + + + + Mute + Ztlumit + + + + Solo + Sólo FxMixerView + FX-Mixer - FX mixážní panel + Efektový mixážní panel + FX Fader %1 - + Efektový fader %1 + Mute Ztlumit + Mute this FX channel - Ztlumit tento FX kanál + Ztlumit tento efektový kanál + Solo Sólo + Solo FX channel - Sólovat FX kanál + Sólovat efektový kanál FxRoute + + Amount to send from channel %1 to channel %2 - + Množství k odeslání z kanálu %1 do kanálu %2 GigInstrument + Bank Banka + Patch Patch + Gain Zisk @@ -2283,46 +2907,58 @@ You can remove and move FX channels in the context menu, which is accessed by ri GigInstrumentView + Open other GIG file Otevřít jiný GIG soubor + Click here to open another GIG file - Klikněte sem pro otevření jiného GIG souboru + Klepněte sem pro otevření jiného GIG souboru + Choose the patch Vybrat patch + Click here to change which patch of the GIG file to use - Klikněte sem pro změnu patche GIG souboru + Klepněte sem pro změnu patche GIG souboru + + Change which instrument of the GIG file is being played Změnit přehrávaný nástroj GIG souboru + Which GIG file is currently being used Který GIG soubor je právě používán + Which patch of the GIG file is currently being used Který patch GIG souboru je právě používán + Gain - Zisk + Zesílení + Factor to multiply samples by - + Vynásobit vzorky x + Open GIG file Otevřít GIG soubor + GIG Files (*.gig) GIG soubory (*.gig) @@ -2330,693 +2966,867 @@ You can remove and move FX channels in the context menu, which is accessed by ri GuiApplication + Working directory Pracovní adresář + The LMMS working directory %1 does not exist. Create it now? You can change the directory later via Edit -> Settings. Pracovní adresář LMMS %1 neexistuje. Chcete jej nyní vytvořit? Změnu adresáře mžete provést později v nabídce Úpravy -> Nastavení. + Preparing UI - Připravuji AI + Připravuji UI + Preparing song editor Připravuji editor skladby + Preparing mixer Připravuji mixážní panel + Preparing controller rack - Připravuji panel kontrolérů + Připravuji panel ovladačů + Preparing project notes Připravuji poznámky k projektu + Preparing beat/bassline editor - Připravuji editor bicích a basů + Připravuji editor bicích/basů + Preparing piano roll - Připravuji piano roll + Připravuji Piano roll + Preparing automation editor - Připravuji editor automatizací + Připravuji Editor automatizace InstrumentFunctionArpeggio + Arpeggio Arpeggio + Arpeggio type Typ arpeggia + Arpeggio range Rozsah arpeggia + + Cycle steps + Počet kroků v cyklu + + + + Skip rate + Míra vynechávání + + + + Miss rate + Míra míjení + + + Arpeggio time Trvání arpeggia + Arpeggio gate Brána arpeggia + Arpeggio direction Směr arpeggia + Arpeggio mode Styl arpeggia + Up Nahoru + Down Dolů + Up and down Nahoru a dolů - Random - Náhodné - - - Free - Volné - - - Sort - Tříděné - - - Sync - Synchronizované - - + Down and up Dolů a nahoru - Skip rate - + + Random + Náhodné - Miss rate - + + Free + Volné - Cycle steps - + + Sort + Tříděné + + + + Sync + Synchronizované 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. - Arpeggio je způsob hraní (zejména na drnkací nástroje), které činí hudbu mnohem živější. Struny těchto nástrojů (např. harfy) jsou rozechvěny jako v akordech. Jediným rozdílem je, že se tak stane sekvenčně, takže tóny nejsou zahrány ve stejnou dobu. Typickým arpeggiem jsou durové a mollové trojzvuky, ale možných dalších akordů, které si můžete vybrat, je spousta. + Arpeggio je způsob hry (zejména na drnkací nástroje), který činí hudbu mnohem živější. Struny těchto nástrojů (např. harfy) jsou rozezněny jako v akordech. Jediným rozdílem je, že se tak stane sekvenčně, takže tóny nejsou zahrány ve stejnou dobu. Typickým arpeggiem jsou durové a mollové trojzvuky, ale možných dalších akordů, které si můžete vybrat, je spousta. + RANGE ROZSAH + Arpeggio range: Rozsah arpeggia: + octave(s) oktáva(y) + Use this knob for setting the arpeggio range in octaves. The selected arpeggio will be played within specified number of octaves. Tento otočný ovladač použijte pro nastavení rozsahu arpeggia v oktávách. Vybrané arpeggio bude zahráno ve zvoleném počtu oktáv. - TIME - TRVÁNÍ - - - Arpeggio time: - Trvání arpeggia: - - - ms - ms - - - Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. - Použijte tento otočný ovladač pro nastavení trvání arpeggia v milisekundách. Trvání arpeggia udává, jak dlouho bude každý tón arpeggia přehráván. - - - GATE - BRÁNA - - - Arpeggio gate: - Brána arpeggia: - - - % - % - - - 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. - Tento otočný ovladač použijte pro nastavení brány arpeggia. Brána arpeggia určuje procento délky jednotlivých arpeggiových tónů, které budou zahrány. Pomocí brány arpeggia můžete udělat skvělé staccatové arpeggio. - - - Chord: - Akord: - - - Direction: - Směr: - - - Mode: - Styl: - - - SKIP - - - - Skip rate: - - - - 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. - - - + CYCLE - + CYKL + Cycle notes: - + Počet not v cyklu: + note(s) nota(y) + 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. - + Skočí přes n kroků v arpeggiu a pokud přesáhne rozsah not, zacyklí se zde. Je-li je celkový rozsah not rovnoměrně dělitelný počtem kroků nad rozdah, uvíznete v kratším arpeggiu nebo dokonce na jedné notě. + + + + SKIP + VYNECH + + + + Skip rate: + Míra vynechávání: + + + + + + % + % + + + + 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. + Funkce vynechávání způsobí, že arpeggiator náhodně pozastaví některý krok. Od počáteční pozice, kde nemá žádný efekt, se po směru hodinových ručiček efekt stupňuje až po maximální nastavení, kdy vynechá vše. + + + + MISS + MÍJ + + + + Miss rate: + Míra míjení: + + + + The miss function will make the arpeggiator miss the intended note. + Funkce míjení způsobí, že arpeggiator netrefí dotyčnou notu. + + + + TIME + TRVÁNÍ + + + + Arpeggio time: + Trvání arpeggia: + + + + ms + ms + + + + Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. + Tento otočný ovladač nastavuje trvání arpeggia v milisekundách. Trvání arpeggia udává, jak dlouho bude každý tón arpeggia přehráván. + + + + GATE + BRÁNA + + + + Arpeggio gate: + Brána arpeggia: + + + + 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. + Tento otočný ovladač nastavuje bránu arpeggia. Brána arpeggia určuje procento délky jednotlivých arpeggiových tónů, které budou zahrány. Pomocí brány arpeggia můžete udělat skvělé staccatové arpeggio. + + + + Chord: + Akord: + + + + Direction: + Směr: + + + + Mode: + Styl: InstrumentFunctionNoteStacking + octave - oktáva + Oktáva + + Major - dur + Dur + Majb5 Maj5b + minor - moll + Moll + minb5 m5b + sus2 sus2 + sus4 sus4 + aug aug + augsus4 aug sus4 + tri tri + 6 6 + 6sus4 6 sus4 + 6add9 6 add9 + m6 m6 + m6add9 m6 add9 + 7 7 + 7sus4 7 sus4 + 7#5 7/5# + 7b5 7/5b + 7#9 7/9# + 7b9 7/9b + 7#5#9 7/5#/9# + 7#5b9 7/5#/9b + 7b5b9 7/5b/9b + 7add11 7 add11 + 7add13 7 add13 + 7#11 7/11# + Maj7 Maj7 + Maj7b5 Maj7/5b + Maj7#5 Maj7/5# + Maj7#11 Maj7/11# + Maj7add13 Maj7 add13 + m7 m7 + m7b5 m7/5b + m7b9 m7/9b + m7add11 m7 add11 + m7add13 m7 add13 + m-Maj7 m-Maj7 + m-Maj7add11 m-Maj7 add11 + m-Maj7add13 m-Maj7 add13 + 9 9 + 9sus4 9 sus4 + add9 add9 + 9#5 9/5# + 9b5 9/5b + 9#11 9/11# + 9b13 9/13b + Maj9 Maj9 + Maj9sus4 Maj9 sus4 + Maj9#5 Maj9/5# + Maj9#11 Maj9/11# + m9 m9 + madd9 m add9 + m9b5 m9/5b + m9-Maj7 m9-Maj7 + 11 11 + 11b9 11/9b + Maj11 Maj11 + m11 m11 + m-Maj11 m-Maj11 + 13 13 + 13#9 13/9# + 13b9 13/9b + 13b5b9 13/9b/5b + Maj13 Maj13 + m13 m13 + m-Maj13 m-Maj13 + Harmonic minor - mollová harmonická + Mollová harmonická + Melodic minor - mollová melodická + Mollová melodická + Whole tone - celotónová stupnice + Celotónová stupnice + Diminished - zmenšená + Zmenšená + Major pentatonic - durová pentatonika + Durová pentatonika + Minor pentatonic - mollová pentatonika + Mollová pentatonika + Jap in sen - japonská (in sen) + Japonská (in sen) stupnice + Major bebop - durová bebopová + Durová bebopová + Dominant bebop - dominantní bebopová + Dominantní bebopová + Blues - bluesová + Bluesová stupnice + Arabic - arabská + Arabská + Enigmatic - enigmatická + Enigmatická + Neopolitan - neapolská + Neapolská + Neopolitan minor - mollová neapolská + Mollová neapolská + Hungarian minor - mollová maďarská + Mollová maďarská + Dorian - dórská + Dórská - Phrygolydian - frygická + + Phrygian + Frygický + Lydian - lydická + Lydická + Mixolydian - mixolydická + Mixolydická + Aeolian - aiolská + Aiolská + Locrian - lokrická - - - Chords - Akordy - - - Chord type - Typ akordu - - - Chord range - Rozsah akordu + Lokrická + Minor - moll + Moll + Chromatic - chromatická + Chromatická + Half-Whole Diminished - zmenšená (půltón – celý tón) + Zmenšená (půltón–celý tón) + 5 5 + Phrygian dominant - + Frygická dominanta + Persian - perská + Perská + + + + Chords + Akordy + + + + Chord type + Typ akordu + + + + Chord range + Rozsah akordu InstrumentFunctionNoteStackingView - RANGE - ROZSAH - - - Chord range: - Rozsah akordu: - - - octave(s) - oktáva(y) - - - Use this knob for setting the chord range in octaves. The selected chord will be played within specified number of octaves. - Tento otočný ovladač použijte pro nastavení rozsahu akordů v oktávách. Vybraný akord bude zahrán ve zvoleném počtu oktáv. - - + STACKING VRSTVENÍ + Chord: Akord: + + + RANGE + ROZSAH + + + + Chord range: + Rozsah akordu: + + + + octave(s) + oktáva(y) + + + + Use this knob for setting the chord range in octaves. The selected chord will be played within specified number of octaves. + Tento otočný ovladač nastavuje rozsah akordů v oktávách. Vybraný akord bude zahrán ve zvoleném počtu oktáv. + InstrumentMidiIOView + ENABLE MIDI INPUT POVOLIT MIDI VSTUP + + CHANNEL KANÁL + + VELOCITY DYNAM + ENABLE MIDI OUTPUT POVOLIT MIDI VÝSTUP + PROGRAM - - - - MIDI devices to receive MIDI events from - MIDI zařízení pro přijímání MIDI událostí - - - MIDI devices to send MIDI events to - MIDI zařízení pro odesílání MIDI událostí + PROGRAM + NOTE NOTA + + MIDI devices to receive MIDI events from + MIDI zařízení pro přijímání MIDI událostí + + + + MIDI devices to send MIDI events to + MIDI zařízení pro odesílání MIDI událostí + + + CUSTOM BASE VELOCITY VLASTNÍ VÝCHOZÍ DYNAMIKA + Specify the velocity normalization base for MIDI-based instruments at 100% note velocity Udává výchozí úroveň dynamiky pro MIDI nástroje při 100 % dynamiky tónu + BASE VELOCITY VÝCHOZÍ DYNAMIKA @@ -3024,400 +3834,503 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentMiscView + MASTER PITCH - HLAVNÍ LADĚNÍ + TRANSPOZICE + Enables the use of Master Pitch - Umožní použití hlavního ladění + Umožní použití transpozice InstrumentSoundShaping + VOLUME HLASITOST + Volume Hlasitost + CUTOFF SEŘÍZNUTÍ + + Cutoff frequency - Frekvence seříznutí + Frekvence oříznutí + RESO REZONANCE + Resonance Rezonance + Envelopes/LFOs - + Obálky/LFO + Filter type Typ filtru + Q/Resonance - + Q/rezonance + LowPass - + Dolní propust + HiPass - + Horní propust + BandPass csg - + Pásmová propust csg + BandPass czpg - + Pásmová propust czpg + Notch - + Pásmová zádrž + Allpass - + Všepásmový filtr + Moog - + Moogův filtr + 2x LowPass - + 2x dolní propust + RC LowPass 12dB - + RC dolní propust 12dB + RC BandPass 12dB - + RC pásmová propust 12dB + RC HighPass 12dB - + RC horní propust 12dB + RC LowPass 24dB - + RC dolní propust 24dB + RC BandPass 24dB - + RC pásmová propust 24dB + RC HighPass 24dB - + RC horní propust 24dB + Vocal Formant Filter - + Vokální formantový filtr + 2x Moog - + 2x Moogův filtr + SV LowPass - + SV dolní propust + SV BandPass - + SV pásmová propust + SV HighPass - + SV horní propust + SV Notch - + SV pásmová zádrž + Fast Formant - + Rychlý formantový filtr + Tripole - + Třípólový filtr InstrumentSoundShapingView + TARGET CÍL: + 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...! - + Tato stránka obsahuje obálky. Ty jsou velmi důležité pro úpravu zvuku a obvykle také i nezbytné pro rozdílovou (subtraktivní) syntézu. Pokud máte například obálku hlasitosti, můžete nastavit, kdy má mít zvuk jakou sílu. Pokud chcete vytvořit něco jako smyčce, váš zvuk by měl mít velmi měkké nasazení i ukončení tónu. Toho dosáhneme nastavením dlouhého času náběhu i uvolnění. Totéž se týká ostatních druhů obálek, jako je obálka panorámatu, frekvence odříznutí pro použití u filtrů apod. Prostě si s tím můžete vyhrát dle libosti! Můžete vytvořit opravdu úžasné zvuky třeba jen z pilovité vlny pomocí vhodných obálek...! + FILTER FILTR + 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. Zde si můžete vybrat z vestavěných filtrů, které chcete použít pro tuto stopu nástroje. Filtry jsou velmi důležité pro změnu charakteristiky zvuku. - 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 - REZON - - - Resonance: - Rezonance: - - - 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. - - - + FREQ FREKV + cutoff frequency: - frekvence seříznutí: + Frekvence oříznutí: + + 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... + Tento otočný ovladač nastavuje frekvenci odříznutí pro vybraný filtr. Frekvence odříznutí určuje frekvenci pro odříznutí signálu filtrem. Například filtr typu dolní propust (low-pass) odstřihne všechny frekvence, které jsou vyšší než frekvence odříznutí. Filtr typu horní propust (high-pass) odstřihne všechny frekvence, které jsou nižší než frekvence odříznutí atd... + + + + RESO + REZON + + + + Resonance: + Rezonance: + + + + 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. + Tento otočný ovladač nastavuje Q/rezonanci pro vybraný filtr. Q/rezonance určuje, jak hodně filtr zesílí frekvence poblíž frekvence oříznutí. + + + Envelopes, LFOs and filters are not supported by the current instrument. - + Obálky, LFO a filtry nejsou podporovány stávajícím nástrojem. InstrumentTrack - unnamed_track - nepojmenovaná_stopa - - - Volume - Hlasitost - - - Panning - Panoráma - - - Pitch - Ladění - - - FX channel - FX kanál - - - Default preset - Výchozí předvolba - - + With this knob you can set the volume of the opened channel. Tímto otočným ovladačem můžete nastavit hlasitost otevřeného kanálu. + + + unnamed_track + nepojmenovaná_stopa + + + Base note Základní nota - Pitch range - + + Volume + Hlasitost + + Panning + Panoráma + + + + Pitch + Ladění + + + + Pitch range + Výškový rozsah + + + + FX channel + Efektový kanál + + + Master Pitch - Hlavní ladění + Transpozice + + + + + Default preset + Výchozí předvolba InstrumentTrackView + Volume Hlasitost + Volume: Hlasitost: + VOL HLA + Panning Panoráma + Panning: Panoráma: + PAN PAN + MIDI MIDI + Input Vstup + Output Výstup + FX %1: %2 - FX %1: %2 + Efekt %1: %2 InstrumentTrackWindow + GENERAL SETTINGS HLAVNÍ NASTAVENÍ + + Use these controls to view and edit the next/previous track in the song editor. + Použije tyto ovládací prvky pro zobrazení a editaci další/předchozí stopy v editoru skladby. + + + Instrument volume Hlasitost nástroje + Volume: Hlasitost: + VOL HLA + Panning Panoráma + Panning: Panoráma: + PAN PAN + Pitch Ladění + Pitch: Ladění: + cents centů + PITCH LADĚNÍ - FX channel - FX kanál - - - ENV/LFO - ENV/LFO - - - FUNC - FUNKCE - - - FX - FX - - - MIDI - MIDI - - - Save preset - Uložit předvolbu - - - XML preset file (*.xpf) - XML soubor předvoleb (*.xpf) - - - PLUGIN - PLUGIN - - + Pitch range (semitones) Rozsah výšky (v půltónech) + RANGE ROZSAH + + FX channel + Efektový kanál + + + + FX + EFEKT + + + Save current instrument track settings in a preset file Uložit aktuální nastavení nástrojové stopy do souboru předvoleb + 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. - Klikněte sem, chcete-li uložit aktuální nastavení nástrojové stopy do souboru předvoleb. Později můžete nahrát tuto předvolbu dvojitým kliknutím na prohlížeč předvoleb. - - - MISC - RŮZNÉ - - - Use these controls to view and edit the next/previous track in the song editor. - Použije tyto ovládací prvky pro zobrazení a editaci další/předchozí stopy v editoru skladby + Klepněte sem, chcete-li uložit aktuální nastavení nástrojové stopy do souboru předvoleb. Později můžete nahrát tuto předvolbu poklepáním na prohlížeč předvoleb. + SAVE ULOŽIT + + + Envelope, filter & LFO + Obálka, filtr a LFO + + + + Chord stacking & arpeggio + Vrstvení akordů a arpeggio + + + + Effects + Efekty + + + + MIDI settings + MIDI nastavení + + + + Miscellaneous + Různé + + + + Save preset + Uložit předvolbu + + + + XML preset file (*.xpf) + XML soubor předvoleb (*.xpf) + + + + Plugin + Plugin + Knob + Set linear Lineární zobrazení + Set logarithmic Logaritmické zobrazení + Please enter a new value between -96.0 dBFS and 6.0 dBFS: Zadejte prosím novou hodnotu mezi -96.0 dBFS a 6.0 dBFS: + Please enter a new value between %1 and %2: Vložte prosím novou hodnotu mezi %1 a %2: @@ -3425,6 +4338,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaControl + Link channels Propojit kanály @@ -3432,10 +4346,12 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaControlDialog + Link Channels Propojit kanály + Channel Kanál @@ -3443,14 +4359,17 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaControlView + Link channels Propojit kanály + Value: Hodnota: + Sorry, no help available. Promiňte, nápověda není k dispozici. @@ -3458,13 +4377,15 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaEffect + Unknown LADSPA plugin %1 requested. - + Je požadován neznámý LADSPA plugin %1. LcdSpinBox + Please enter a new value between %1 and %2: Vložte prosím novou hodnotu mezi %1 a %2: @@ -3472,18 +4393,26 @@ You can remove and move FX channels in the context menu, which is accessed by ri LeftRightNav + + + Previous Předchozí + + + Next Další + Previous (%1) Předchozí (%1) + Next (%1) Další (%1) @@ -3491,30 +4420,37 @@ You can remove and move FX channels in the context menu, which is accessed by ri LfoController + LFO Controller Ovladač LFO + Base value Základní hodnota + Oscillator speed Rychlost oscilátoru + Oscillator amount Míra oscilátoru + Oscillator phase Fáze oscilátoru + Oscillator waveform Vlna oscilátoru + Frequency Multiplier Frekvenční multiplikátor @@ -3522,115 +4458,142 @@ You can remove and move FX channels in the context menu, which is accessed by ri LfoControllerDialog + LFO LFO + LFO Controller Ovladač LFO + BASE - + ZÁKL + Base amount: Základní míra: + todo - + udělat + SPD - + RYCH + LFO-speed: - + Rychlost LFO: + Use this knob for setting speed of the LFO. The bigger this value the faster the LFO oscillates and the faster the effect. - + Tento otočný ovladač nastavuje rychlost LFO. Zvýšením hodnoty se zrychlí kmitání LFO a průběh efektu. + + AMNT + MNOŽ + + + Modulation amount: Hloubka modulace: + 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. - + Tento otočný ovladač nastavuje množství modulace LFO. Čím vyšší bude tato hodnota, tím více budou propojené parametry (např. hlasitost nebo frekvence odříznutí) ovlivněny LFO. + PHS - + FÁZ + Phase offset: - + Posun fáze: + degrees - stupně + stupňů + 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. - + Tímto otočným ovladačem můžete nastavit fázový posun LFO. To znamená, že můžete posunout bod, ve kterém oscilátor začne kmitat. Například pokud máte sinusovou vlnu s fázovým posunem 180 stupňů, vlna půjde nejdříve dolů. Totéž se stane u vlny pravoúhlé. + Click here for a sine-wave. - Klikněte sem pro sinusovou vlnu. + Klepněte sem pro sinusovou vlnu. + Click here for a triangle-wave. - Klikněte sem pro trojúhelníkovou vlnu. + Klepněte sem pro trojúhelníkovou vlnu. + Click here for a saw-wave. - Klikněte sem pro pilovitou vlnu. + Klepněte sem pro pilovitou vlnu. + Click here for a square-wave. - Klikněte sem pro pravoúhlou vlnu. + Klepněte sem pro pravoúhlou vlnu. + + Click here for a moog saw-wave. + Klepněte sem pro pilovitou vlnu typu Moog. + + + Click here for an exponential wave. - Klikněte sem pro exponenciální vlnu. + Klepněte sem pro exponenciální vlnu. + Click here for white-noise. - Klikněte sem pro bílý šum. + Klepněte sem pro bílý šum. + Click here for a user-defined shape. Double click to pick a file. - Klikněte sem pro uživatelem definovaný tvar. -Dvojklik pro výběr souboru. - - - Click here for a moog saw-wave. - - - - AMNT - MNOŽ + Klepněte sem pro uživatelem definovaný tvar. +Poklepejte pro výběr souboru. LmmsCore + Generating wavetables Generuji vlny + Initializing data structures Inicializuji datové struktury + Opening audio and midi devices Spouštím zvuková a MIDI zařízení + Launching mixer threads Spouštím vlákna mixážního panelu @@ -3638,405 +4601,500 @@ Dvojklik pro výběr souboru. MainWindow - Could not save config-file - Nemohu uložit konfigurační soubor + + Configuration file + Soubor nastavení - Could not save configuration file %1. You're probably not permitted to write to this file. -Please make sure you have write-access to the file and try again. - Nemohu uložit konfigurační soubor %1. Pravděpodobně nemáte právo k zápisu do tohoto souboru. -Ujistěte se prosím, že máte k souboru právo zápisu a zkuste to znovu. + + Error while parsing configuration file at line %1:%2: %3 + Chyba při kontrole konfiguračního souboru na řádku %1:%2: %3 + + Could not open file + Nemohu otevřít soubor + + + + 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! + Nelze otevřít soubor %1 pro zápis. +Ujistěte se prosím, zda máte povolen zápis do souboru a do složky obsahující soubor a zkuste znovu! + + + + Project recovery + Obnovení projektu + + + + 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? + Je k dispozici soubor pro obnovu. Zdá se, že poslední práce nebyla správně ukončena nebo že je již spuštěna jiná instance LMMS. Chcete obnovit tuto verzi projektu? + + + + + + Recover + Obnovit + + + + Recover the file. Please don't run multiple instances of LMMS when you do this. + Obnovit soubor. Před dokončením prosím nespouštějte další instance LMMS. + + + + + + Discard + Zrušit + + + + Launch a default session and delete the restored files. This is not reversible. + Spustit LMMS do výchozího stavu a smazat obnovené soubory. Tento krok je nevratný. + + + + Version %1 + Verze %1 + + + + Preparing plugin browser + Připravuji prohlížeč pluginů + + + + Preparing file browsers + Připravuji prohlížeč souborů + + + + My Projects + Moje projekty + + + + My Samples + Moje samply + + + + My Presets + Moje předvolby + + + + My Home + Domů + + + + Root directory + Kořenový adresář + + + + Volumes + Hlasitosti + + + + My Computer + Můj počítač + + + + Loading background artwork + Načítám grafiku prostředí + + + + &File + &Soubor + + + &New &Nový + + New from template + Nový z šablony + + + &Open... &Otevřít... + + &Recently Opened Projects + &Naposledy otevřené projekty + + + &Save &Uložit + Save &As... Uložit &jako... + + Save as New &Version + Uložit jako novou &verzi + + + + Save as default template + Uložit jako výchozí šablonu + + + Import... Importovat... + E&xport... E&xportovat... + + E&xport Tracks... + E&xportovat stopy... + + + + Export &MIDI... + &Exportovat MIDI... + + + &Quit &Ukončit + &Edit Úpr&avy + + Undo + Zpět + + + + Redo + Znovu + + + Settings Nastavení + + &View + &Zobrazení + + + &Tools &Nástroje + &Help &Nápověda + + Online Help + Nápověda online + + + Help Nápověda - What's this? + + What's This? Co je to? + About O LMMS + Create new project Vytvořit nový projekt + Create new project from template Vytvořit nový projekt ze šablony + Open existing project Otevřít existující projekt + Recently opened projects Naposledy otevřené projekty + Save current project Uložit aktuální projekt + Export current project Exportovat aktuální projekt - Song Editor - Editor skladby + + What's this? + Co je to? + + Toggle metronome + Zapnout/Vypnout metronom + + + + Show/hide Song-Editor + Zobrazit/Skrýt editor skladby + + + 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. - Zmačknutím tohoto tlačítka zobrazíte nebo schováte Editor skladby. S jeho pomocí můžete editovat playlist skladby a specifikovat, kdy a která stopa má být přehrána. Můžete také vložit a přesunovat samply (např. rapové) přímo do playlistu. + Stisknutím tohoto tlačítka zobrazíte nebo skryjete Editor skladby. S jeho pomocí můžete upravovat playlist skladby a určit, kdy a která stopa má být přehrána. Můžete také vkládat a přesunovat samply (např. rapové) přímo do playlistu. - Beat+Bassline Editor - Editor bicích a basů + + Show/hide Beat+Bassline Editor + Zobrazit/Skrýt editor bicích/basů + 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. - Stisknutím tohoto tlačítka zobrazíte nebo skryjete editor bicích a basů. Tento editor je nezbytný pro tvorbu beatů, otevírání, přidávání či odebírání kanálů a dále pro vyjímání, kopírování a vkládání beatů, bicích/basových patternů apod. + Stisknutím tohoto tlačítka zobrazíte nebo skryjete editor bicích/basů. Tento editor je nezbytný pro tvorbu beatů, otevírání, přidávání či odebírání kanálů a dále pro vyjímání, kopírování a vkládání beatů, bicích/basových záznamů apod. - Piano Roll - Piano Roll + + Show/hide Piano-Roll + Zobrazit/Skrýt Piano roll + Click here to show or hide the Piano-Roll. With the help of the Piano-Roll you can edit melodies in an easy way. - Klikněte sem, pokud chcete ukázat nebo schovat Piano-Roll. S pomocí Piano Roll můžete jednoduchým způsobem editovat melodie. + Klepněte sem, pokud chcete ukázat nebo skrýt Piano roll. S pomocí Piano rollu můžete jednoduchým způsobem upravovat melodie. - Automation Editor - Automatizační editor + + Show/hide Automation Editor + Zobrazit/Skrýt Editor automatizace + 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. - Klikněte sem, pokud chcete ukázat nebo schovat Automatizační editor. S pomocí Automatizačního editoru můžete jednoduchým způsobem editovat dynamické hodnoty. + Klepněte sem, pokud chcete ukázat nebo skrýt Editor automatizace. S pomocí Editoru automatizace můžete jednoduchým způsobem upravovat proměnlivý průběh hodnot. - FX Mixer - FX mixážní panel + + Show/hide FX Mixer + Zobrazit/Skrýt efektový mixážní panel + 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. - Klikněte sem, pokud chcete ukázat nebo skrýt FX mixážní panel. FX mixážní panel je velmi silný nástroj pro správu efektů ve vaší skladbě. Efekty můžete vkládat do různých efektových kanálů. + Klepněte sem, pokud chcete ukázat nebo skrýt efektový (FX) mixážní panel. Efektový mixážní panel je velmi výkonný nástroj pro správu efektů ve vaší skladbě. Efekty můžete vkládat do různých efektových kanálů. - Project Notes - Poznámky k projektu + + Show/hide project notes + Zobrazit/Skrýt poznámky k projektu + Click here to show or hide the project notes window. In this window you can put down your project notes. - Klikněte sem, pokud chcete ukázat nebo schovat okno pro poznámky. V tomto okně lze vkládat vaše poznámky k projektu. + Klepněte sem, pokud chcete ukázat nebo schovat okno pro poznámky. V tomto okně lze vkládat vaše poznámky k projektu. - Controller Rack - Panel kontrolérů + + Show/hide controller rack + Zobrazit/Skrýt panel ovladačů + Untitled Nepojmenovaný + + Recover session. Please save your work! + Obnovit projekt. Uložte prosím svou práci! + + + LMMS %1 LMMS %1 + + Recovered project not saved + Obnovený projekt není uložen + + + + 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? + Tento projekt byl obnoven z minulého spuštění LMMS. Zatím není uložen a pokud tak neučiníte, práce bude ztracena. Chcete jej nyní uložit? + + + Project not saved Projekt není uložen + The current project was modified since last saving. Do you want to save it now? Aktuální projekt byl od posledního uložení změněn. Chcete jej nyní uložit? + + Open Project + Otevřít projekt + + + + LMMS (*.mmp *.mmpz) + LMMS (*.mmp *.mmpz) + + + + Save Project + Uložit projekt + + + + LMMS Project + Projekt LMMS + + + + LMMS Project Template + Šablona projektu LMMS + + + + Save project template + Uložit šablonu projektu + + + + Overwrite default template? + Přepsat výchozí šablonu? + + + + This will overwrite your current default template. + Tímto se přepíše vaše nynější výchozí šablona. + + + Help not available Nápověda není dostupná + Currently there's no help available in LMMS. Please visit http://lmms.sf.net/wiki for documentation on LMMS. V současnosti není v LMMS nápověda dostupná. Navštivte prosím stránku s dokumentací k LMMS na adrese http://lmms.sf.net/wiki. - LMMS (*.mmp *.mmpz) - LMMS (*.mmp *.mmpz) + + Song Editor + Editor skladby - Version %1 - Verze %1 + + Beat+Bassline Editor + Editor bicích/basů - Configuration file - Soubor nastavení + + Piano Roll + Piano roll - Error while parsing configuration file at line %1:%2: %3 - + + Automation Editor + Editor automatizace - Volumes - + + FX Mixer + Efektový mixážní panel - Undo - Zpět + + Project Notes + Poznámky k projektu - Redo - Znovu - - - My Projects - Moje projekty - - - My Samples - Moje samply - - - My Presets - Moje předvolby - - - My Home - Domů - - - My Computer - Můj počítač - - - &File - &Soubor - - - &Recently Opened Projects - &Naposledy otevřené projekty - - - Save as New &Version - Uložit jako novou &verzi - - - E&xport Tracks... - E&xportovat stopy... - - - Online Help - Nápověda online - - - What's This? - Co je to? - - - Open Project - Otevřít projekt - - - Save Project - Uložit projekt - - - 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. - - - - Ignore - - - - Launch LMMS as usual but with automatic backup disabled to prevent the present recover file from being overwritten. - - - - Discard - - - - Launch a default session and delete the restored files. This is not reversible. - - - - Preparing plugin browser - Připravuji prohlížeč pluginů - - - Preparing file browsers - Připravuji prohlížeč souborů - - - Root directory - Kořenový adresář - - - Loading background artwork - Načítám grafiku prostředí - - - New from template - Nový z šablony - - - Save as default template - Uložit jako výchozí šablonu - - - &View - &Zobrazení - - - Toggle metronome - - - - Show/hide Song-Editor - Zobrazit/skrýt editor skladby - - - Show/hide Beat+Bassline Editor - Zobrazit/skrýt editor bicích a basů - - - Show/hide Piano-Roll - Zobrazit/skrýt piano-roll - - - Show/hide Automation Editor - Zobrazit/skrýt editor automatizace - - - Show/hide FX Mixer - Zobrazit/skrýt FX mixážní panel - - - Show/hide project notes - Zobrazit/skrýt poznámky k projektu - - - Show/hide controller rack - Zobrazit/skrýt panel ovladačů - - - Recover session. Please save your work! - - - - Automatic backup disabled. Remember to save your work! - - - - Recovered project not saved - Obnovený projekt není uložen - - - 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? - - - - LMMS Project - - - - LMMS Project Template - - - - Overwrite default template? - - - - This will overwrite your current default template. - + + Controller Rack + Panel ovladačů + Volume as dBFS - Hlasitost jako dBFS + Hlasitost v dBFS + Smooth scroll Plynulé posouvání + Enable note labels in piano roll - Povolit názvy tónů v piano rollu - - - Save project template - + Povolit názvy tónů v Piano rollu MeterDialog + + Meter Numerator - + Počet dob v taktu + + Meter Denominator - + Délka doby v taktu + TIME SIG METRUM @@ -4044,40 +5102,49 @@ Navštivte prosím stránku s dokumentací k LMMS na adrese http://lmms.sf.net/w MeterModel + Numerator - + Počet dob + Denominator - + Délka doby MidiController + MIDI Controller - MIDI kontrolér + MIDI ovladač + unnamed_midi_controller - nepojmenovaný_midi_kontrolér + nepojmenovaný_midi_ovladač MidiImport + + Setup incomplete Nastavení není dokončeno + 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. Nemáte nastaven výchozí soundfont v dialogovém okně (Edit-> Nastavení). Z tohoto důvodu nebude po importu MIDI souboru přehráván žádný zvuk. Stáhněte si nějaký General MIDI soundfont, zadejte jej v dialogovém okně nastavení a zkuste to znovu. + 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. - + Nelze zkompilovat LMMS s podporou přehrávače SoundFont2, který je použitý k přidání výchozího zvuku do importovaných MIDI souborů. Proto nebude po importování tohoto MIDI souboru přehráván žádný zvuk. + Track Stopa @@ -4085,66 +5152,80 @@ Navštivte prosím stránku s dokumentací k LMMS na adrese http://lmms.sf.net/w MidiJack + JACK server down When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (title) - + JACK server zhavaroval + The JACK server seems to be shuted down. When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (dialog message) - + Zdá se, že JACK server zhavaroval. MidiPort + Input channel Vstupní kanál + Output channel Výstupní kanál + Input controller - Vstupní kontrolér + Vstupní ovladač + Output controller - Výstupní kontrolér + Výstupní ovladač + Fixed input velocity Pevná vstupní dynamika + Fixed output velocity Pevná výstupní dynamika - Output MIDI program - Výstupní MIDI program - - - Receive MIDI-events - Přijímat MIDI události - - - Send MIDI-events - Posílat MIDI události - - + Fixed output note Pevná výstupní nota + + Output MIDI program + Výstupní MIDI program + + + Base velocity Výchozí dynamika + + + Receive MIDI-events + Přijímat MIDI události + + + + Send MIDI-events + Posílat MIDI události + MidiSetupWidget + DEVICE ZAŘÍZENÍ @@ -4152,753 +5233,1045 @@ Navštivte prosím stránku s dokumentací k LMMS na adrese http://lmms.sf.net/w MonstroInstrument + Osc 1 Volume Osc 1 hlasitost + Osc 1 Panning - Panoráma Osc 1 + Osc 1 panoráma + Osc 1 Coarse detune Osc 1 hrubé rozladění + Osc 1 Fine detune left Osc 1 jemné rozladění vlevo + Osc 1 Fine detune right Osc 1 jemné rozladění vpravo + Osc 1 Stereo phase offset Osc 1 posun stereo fáze + Osc 1 Pulse width Osc 1 délka pulzu + Osc 1 Sync send on rise - + Osc 1 synchronizace při nárůstu + Osc 1 Sync send on fall - + Osc 1 synchronizace při poklesu + Osc 2 Volume Osc 2 hlasitost + Osc 2 Panning - Panoráma Osc 2 + Osc 2 panoráma + Osc 2 Coarse detune Osc 2 hrubé rozladění + Osc 2 Fine detune left Osc 2 jemné rozladění vlevo + Osc 2 Fine detune right Osc 2 jemné rozladění vpravo + Osc 2 Stereo phase offset Osc 2 posun stereo fáze + Osc 2 Waveform Osc 2 vlna + Osc 2 Sync Hard - + Osc 2 pevná synchronizace + Osc 2 Sync Reverse - + Osc 2 reverzní synchronizace + Osc 3 Volume Osc 3 hlasitost + Osc 3 Panning - Panoráma Osc 3 + Osc 3 panoráma + Osc 3 Coarse detune Osc 3 hrubé rozladění + Osc 3 Stereo phase offset Osc 3 posun stereo fáze + Osc 3 Sub-oscillator mix - + Osc 3 smíchání se sub-oscilátorem + Osc 3 Waveform 1 Osc 3 vlna 1 + Osc 3 Waveform 2 Osc 3 vlna 2 + Osc 3 Sync Hard - + Osc 3 pevná synchronizace + Osc 3 Sync Reverse - + Osc 3 reverzní synchronizace + LFO 1 Waveform - + LFO 1 vlna + LFO 1 Attack - + LFO 1 náběh + LFO 1 Rate - + LFO 1 rychlost + LFO 1 Phase - + LFO 1 fáze + LFO 2 Waveform - + LFO 2 vlna + LFO 2 Attack - + LFO 2 náběh + LFO 2 Rate - + LFO 2 rychlost + LFO 2 Phase - + LFO 2 fáze + Env 1 Pre-delay - + Obálka 1 předzpoždění + Env 1 Attack - + Obálka 1 náběh + Env 1 Hold - + Obálka 1 držení + Env 1 Decay - + Obálka 1 útlum + Env 1 Sustain - + Obálka 1 vydržení + Env 1 Release - + Obálka 1 uvolnění + Env 1 Slope - + Obálka 1 sklon + Env 2 Pre-delay - + Obálka 2 předzpoždění + Env 2 Attack - + Obálka 2 náběh + Env 2 Hold - + Obálka 2 držení + Env 2 Decay - + Obálka 2 útlum + Env 2 Sustain - + Obálka 2 vydržení + Env 2 Release - + Obálka 2 uvolnění + Env 2 Slope - + Obálka 2 sklon + Osc2-3 modulation Osc 2–3 modulace + Selected view - + Zvolený pohled + Vol1-Env1 - + Hla1-Obá1 + Vol1-Env2 - + Hla1-Obá2 + Vol1-LFO1 - + Hla1-LFO1 + Vol1-LFO2 - + Hla1-LFO2 + Vol2-Env1 - + Hla2-Obá1 + Vol2-Env2 - + Hla2-Obá2 + Vol2-LFO1 - + Hla2-LFO1 + Vol2-LFO2 - + Hla2-LFO2 + Vol3-Env1 - + Hla3-Obá1 + Vol3-Env2 - + Hla3-Obá2 + Vol3-LFO1 - + Hla3-LFO1 + Vol3-LFO2 - + Hla3-LFO2 + Phs1-Env1 - + Fáz1-Obá1 + Phs1-Env2 - + Fáz1-Obá2 + Phs1-LFO1 - + Fáz1-LFO1 + Phs1-LFO2 - + Fáz1-LFO2 + Phs2-Env1 - + Fáz2-Obá1 + Phs2-Env2 - + Fáz2-Obá2 + Phs2-LFO1 - + Fáz2-LFO1 + Phs2-LFO2 - + Fáz2-LFO2 + Phs3-Env1 - + Fáz3-Obá1 + Phs3-Env2 - + Fáz3-Obá2 + Phs3-LFO1 - + Fáz3-LFO1 + Phs3-LFO2 - + Fáz3-LFO2 + Pit1-Env1 - + Výš1-Obá1 + Pit1-Env2 - + Výš1-Obá2 + Pit1-LFO1 - + Výš1-LFO1 + Pit1-LFO2 - + Výš1-LFO2 + Pit2-Env1 - + Výš2-Obá1 + Pit2-Env2 - + Výš2-Obá2 + Pit2-LFO1 - + Výš2-LFO1 + Pit2-LFO2 - + Výš2-LFO2 + Pit3-Env1 - + Výš3-Obá1 + Pit3-Env2 - + Výš3-Obá2 + Pit3-LFO1 - + Výš3-LFO1 + Pit3-LFO2 - + Výš3-LFO2 + PW1-Env1 - + Pul1-Obá1 + PW1-Env2 - + Pul1-Obá2 + PW1-LFO1 - + Pul1-LFO1 + PW1-LFO2 - + Pul1-LFO2 + Sub3-Env1 - + Sub3-Obá1 + Sub3-Env2 - + Sub3-Obá2 + Sub3-LFO1 - + Sub3-LFO1 + Sub3-LFO2 - + Sub3-LFO2 + + Sine wave Sinusová vlna + Bandlimited Triangle wave - + Pásmově zúžená trojúhelníková vlna + Bandlimited Saw wave - + Pásmově zúžená pilovitá vlna + Bandlimited Ramp wave - + Pásmově zúžená šikmá vlna + Bandlimited Square wave - + Pásmově zúžená pravoúhlá vlna + Bandlimited Moog saw wave - + Pásmově zúžená pilovitá vlna typu Moog + + Soft square wave - + Zaoblená pravoúhlá vlna + Absolute sine wave - + Absolutní sinusová vlna + + Exponential wave - + Exponenciální vlna + White noise Bílý šum + Digital Triangle wave Digitální trojúhelníková vlna + Digital Saw wave Digitální pilovitá vlna + Digital Ramp wave - + Digitální šikmá vlna + Digital Square wave - + Digitální pravoúhlá vlna + Digital Moog saw wave - + Digitální pilovitá vlna typu Moog + Triangle wave Trojúhelníková vlna + Saw wave Pilovitá vlna + Ramp wave - + Šikmá vlna + Square wave - Pravoúhlá (square) vlna + Pravoúhlá vlna + Moog saw wave - + Pilovitá vlna typu Moog + Abs. sine wave - + Abs. sinusová vlna + Random - Náhodně + Náhodná + Random smooth - + Vyhlazená náhodná MonstroView + Operators view - Pohled operátora + Zobrazení operátorů + 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. - + Zobrazení operátorů obsahuje všechny operátory. Toto společně zahrnuje jak přímo slyšitelné operátory (oscilátory), tak i neslyšitelné operátory nebo modulátory: generátory nízkých kmitů (LFO) a obálek. + +Otočné ovladače a další ovládací prvky v Zobrazení operátorů mají své vlastní textové popisky, takže můžete získat bližší nápovědu, co který konkrétně dělá. + Matrix view - Maticový pohled + Zobrazení matrice + 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. - - - - 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. - - - - 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. + Zobrazení matrice obsahuje modulační matrici. Zde můžete nadefinovat modulační vazby mezi různými operátory: každý slyšitelný operátor (oscilátory 1–3) má 3–4 vlastnosti, které mohou být modulovány dalšími modulátory. Použití více modulací spotřebovává více výkonu procesoru. -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. +Okno je rozděleno na cíle modulace, seskupené podle cílových oscilátorů. Dostupné cíle jsou: hlasitost, výška, fáze, délka pulzu a poměr sub-oscilátoru. Poznámka: některé cíle jsou dostupné pouze pro určitý oscilátor. -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. - +Každý cíl modulace má 4 otočné ovladače, jeden pro každý modulátor. Výchozí stav ovladačů je 0, tedy bez modulace. Otočení ovladače na 1 způsobí, že modulátor bude působit na cíl nejvíce, jak je možno. Otočení na -1 způsobí totéž, ale modulace bude inverzně obrácena. + + + Volume Hlasitost + + + Panning Panoráma + + + Coarse detune Hrubé rozladění + + + semitones půltónů + + Finetune left Jemné rozladění vlevo + + + + cents centů + + Finetune right Jemné rozladění vpravo + + + Stereo phase offset Posun stereo fáze + + + + + deg - + stupňů + Pulse width Délka pulzu + Send sync on pulse rise - + Synchronizace při nárůstu pulzu + Send sync on pulse fall - + Synchronizace při poklesu pulzu + Hard sync oscillator 2 - + Pevně synchronizovat oscilátor 2 + Reverse sync oscillator 2 - + Reverzně synchronizovat oscilátor 2 + Sub-osc mix - + Míchání sub-osc + Hard sync oscillator 3 - + Pevně synchronizovat oscilátor 3 + Reverse sync oscillator 3 - + Reverzně synchronizovat oscilátor 3 + + + + Attack - Nástup + Náběh + + Rate - Rychlost + Typ + + Phase Fáze + + Pre-delay - + Předzpoždění + + Hold - + Držení + + Decay - Doznívání + Pokles + + Sustain - + Držení + + Release - Uvolnění + Doznění + + Slope - Stoupání + Strmost + + Mix Osc2 with Osc3 + Smíchat Osc2 a Osc3 + + + + Modulate amplitude of Osc3 with Osc2 + Modulovat amplitudu Osc3 pomocí Osc2 + + + + Modulate frequency of Osc3 with Osc2 + Modulovat frekvenci Osc3 pomocí Osc2 + + + + Modulate phase of Osc3 with Osc2 + Modulovat fázi Osc3 pomocí Osc2 + + + + The CRS knob changes the tuning of oscillator 1 in semitone steps. + Otočný ovladač CRS mění ladění oscilátoru 1 v půltónových krocích. + + + + The CRS knob changes the tuning of oscillator 2 in semitone steps. + Otočný ovladač CRS mění ladění oscilátoru 2 v půltónových krocích. + + + + The CRS knob changes the tuning of oscillator 3 in semitone steps. + Otočný ovladač CRS mění ladění oscilátoru 3 v půltónových krocích. + + + + + + + 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. + FTL a FTR změní jemné ladění oscilátoru pro levý a pravý kanál. To přidává oscilátoru stereo rozladění, které rozšíří stereo obraz a vytvoří dojem prostoru. + + + + + + The SPO knob modifies the difference in phase between left and right channels. Higher difference creates a wider stereo image. + Otočný ovladač SPO upravuje rozdíl ve fázi mezi levým a pravým kanálem. Větší rozdíl vytváří širší stereofonní obraz. + + + + 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. + Otočný ovladač PW řídí šířku pulzu, jinak též pracovní cyklus, oscilátoru 1. Oscilátor 1 je digitální generátor pulzních vln, který nevytváří pásmově omezený výstup, což znamená, že jej sice můžete použít jako zdroj slyšitelného signálu, ale způsobuje aliasing. Můžete jej ale také využít jako neslyšitelný zdroj synchronizačního signálu, který může sloužit k synchronizaci oscilátorů 2 a 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. + Zaslání synchronizačního signálu při nárůstu: je-li zapnuto, bude synchronizační signál zasílán pokaždé, když bude stav oscilátoru 1 změněn na vyšší, např. když se amplituda změní z -1 na 1. Výška, fáze a šířka pulzu oscilátoru 1 mohou mít vliv na časování synchronizace, ale jejich množství zde nemá žádný efekt. Synchronizační signály jsou odesílány nezávisle pro levý a pravý kanál. + + + + 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. + Zaslání synchronizačního signálu při poklesu: je-li zapnuto, bude synchronizační signál zasílán pokaždé, když bude stav oscilátoru 1 změněn na nižší, např. když se amplituda změní z 1 na -1. Výška, fáze a šířka pulzu oscilátoru 1 mohou mít vliv na časování synchronizace, ale jejich množství zde nemá žádný efekt. Synchronizační signály jsou odesílány nezávisle pro levý a pravý kanál. + + + + + Hard sync: Every time the oscillator receives a sync signal from oscillator 1, its phase is reset to 0 + whatever its phase offset is. + Pevná synchronizace: pokaždé, když oscilátor přijme synchronizační signál z oscilátoru 1, jeho fáze bude nastavena na 0, bez ohledu na jeho fázový posun. + + + + + Reverse sync: Every time the oscillator receives a sync signal from oscillator 1, the amplitude of the oscillator gets inverted. + Reverzní synchronizace: pokaždé, když oscilátor přijme synchronizační signál z oscilátoru 1, jeho amplituda bude převrácena. + + + + Choose waveform for oscillator 2. + Vyberte vlnu pro oscilátor 2. + + + + Choose waveform for oscillator 3's first sub-osc. Oscillator 3 can smoothly interpolate between two different waveforms. + Vyberte vlnu pro první suboscilátor oscilátoru 3. Oscilátor 3 může plynule interpolovat mezi dvěma různými vlnovými průběhy. + + + + Choose waveform for oscillator 3's second sub-osc. Oscillator 3 can smoothly interpolate between two different waveforms. + Vyberte vlnu pro druhý suboscilátor oscilátoru 3. Oscilátor 3 může plynule interpolovat mezi dvěma různými vlnovými průběhy. + + + + 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. + Otočný ovladač SUB mění poměr směšování mezi dvěma suboscilátory oscilátoru 3. Každý suboscilátor může být nastaven tak, aby vytvářel jiný vlnový průběh, a oscilátor 3 může plynule interpolovat mezi nimi. Všechny příchozí modulace oscilátoru 3 jsou shodným způsobem aplikovány na oba suboscilátory / vlnové průběhy. + + + + 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. + Kromě vyhrazených modulátorů Monstro umožňuje oscilátor 3 modulovat výstupem oscilátoru 2. + +Režim směšování znamená bez modulace: výstupy oscilátorů se jednoduše smíchají. + + + + 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. + Kromě vyhrazených modulátorů Monstro umožňuje oscilátor 3 modulovat výstupem oscilátoru 2. + +AM znamená amplitudovou modulaci: Amplituda (hlasitost) oscilátoru 3 je modulována oscilátorem 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. + Kromě vyhrazených modulátorů Monstro umožňuje oscilátor 3 modulovat výstupem oscilátoru 2. + +FM znamená frekvenční modulaci: frekvence (výška) oscilátoru 3 je modulována oscilátorem 2. Frekvenční modulace je implementována jako fázová modulace, která poskytuje stabilnější výslednou výšku než "čistá" frekvenční modulace. + + + + 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. + Kromě vyhrazených modulátorů Monstro umožňuje oscilátor 3 modulovat výstupem oscilátoru 2. + +PM znamená fázovou modulaci: fáze oscilátoru 3 je modulována oscilátorem 2. To se liší od frekvenční modulace tím, že fázové změny nejsou kumulativní. + + + + 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... + Vyberte tvar vlny pro LFO 1. +"Náhodná" a "Vyhlazená náhodná" jsou speciální vlny: produkují náhodný výstup, kde rychlost LFO řídí, jak často se mění stav LFO. Vyhlazená verze interpoluje mezi těmito stavy kosinovou interpolací. Tyto náhodné režimy mohou být použity k oživení vašich předvoleb – přidávají něco z analogové nepředvídatelnosti... + + + + 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... + Vyberte tvar vlny pro LFO 2. +"Náhodná" a "Vyhlazená náhodná" jsou speciální vlny: produkují náhodný výstup, kde rychlost LFO řídí, jak často se mění stav LFO. Vyhlazená verze interpoluje mezi těmito stavy kosinovou interpolací. Tyto náhodné režimy mohou být použity k oživení vašich předvoleb – přidávají něco z analogové nepředvídatelnosti... + + + + + Attack causes the LFO to come on gradually from the start of the note. + Náběh způsobí, že LFO najede postupně od začátku noty. + + + + + Rate sets the speed of the LFO, measured in milliseconds per cycle. Can be synced to tempo. + Rate nastavuje rychlost LFO, měřenou v milisekundách za cyklus. Lze synchronizovat s tempem. + + + + + PHS controls the phase offset of the LFO. + PHS řídí fázový posun LFO. + + + + + PRE, or pre-delay, delays the start of the envelope from the start of the note. 0 means no delay. + PRE nebo předzpoždění (PRE, predelay) zpozdí začátek obálky oproti začátku noty. Hodnota 0 znamená bez zpoždění. + + + + + ATT, or attack, controls how fast the envelope ramps up at start, measured in milliseconds. A value of 0 means instant. + NÁB nebo náběh určuje, jak rychle vystoupá začátek obálky do špičky, měřeno v milisekundách. Hodnota 0 znamená okamžitý náběh. + + + + + HOLD controls how long the envelope stays at peak after the attack phase. + Držení určuje, jak dlouho obálka zůstane na špičce po fázi náběhu. + + + + + 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. + ÚTL nebo útlum (DEC, decoy) řídí rychlost poklesu obálky ze špičky do nulové úrovně (měřeno v milisekundách). Aktuální útlum může být kratší, pokud je použito podržení (sustain). + + + + + 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. + POD nebo podržení (SUS, sustain) řídí úroveň podržení v obálce. Fáze útlumu (decoy) nemůže jít pod tuto úroveň, dokud je nota držená. + + + + + 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. + UVO nebo uvolnění určuje, jak dlouhé bude ukončení noty, tedy jak dlouho bude trvat zeslabení ze špičky na nulu. Skutečná délka uvolnění může být kratší v závislosti na tom, ve které fázi je nota ukončena. + + + + + 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. + Otočný ovladač sklon řídí křivku a tvar obálky. Hodnota 0 vytváří přímý nárůst i pokles. Záporné hodnoty vytvářejí křivku, která začíná pomalu, rychle dosáhne špičky a opět pomalu klesá. Pozitivní hodnoty vytvářejí křivku, která začíná a končí rychle a udržuje se v blízkosti špičky. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Modulation amount Hloubka modulace @@ -4906,34 +6279,42 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator MultitapEchoControlDialog + Length Délka + Step length: Délka kroku: + Dry - + Poměr + Dry Gain: - + Poměr zdrojového zvuku: + Stages - + Úrovně + Lowpass stages: - + Počet úrovní dolní propusti: + Swap inputs Přepnout vstupy + Swap left and right input channel for reflections Přepnout levý a pravý vstupní kanál pro odrazy @@ -4941,82 +6322,102 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator NesInstrument + Channel 1 Coarse detune Kanál 1 hrubé rozladění + Channel 1 Volume - Kanál 1 hlasitost + Hlasitost kanálu 1 + Channel 1 Envelope length Kanál 1 délka obálky + Channel 1 Duty cycle Kanál 1 pracovní cyklus + Channel 1 Sweep amount - + Kanál 1 množství sweepu + Channel 1 Sweep rate - + Kanál 1rychlost sweepu + Channel 2 Coarse detune Kanál 2 hrubé rozladění + Channel 2 Volume - Kanál 2 hlasitost + Hlasitost kanálu 2 + Channel 2 Envelope length Kanál 2 délka obálky + Channel 2 Duty cycle Kanál 2 pracovní cyklus + Channel 2 Sweep amount - + Kanál 2 množství sweepu + Channel 2 Sweep rate - + Kanál 2 rychlost sweepu + Channel 3 Coarse detune Kanál 3 hrubé rozladění + Channel 3 Volume - Kanál 3 hlasitost + Hlasitost kanálu 3 + Channel 4 Volume - Kanál 4 hlasitost + Hlasitost kanálu 4 + Channel 4 Envelope length Kanál 4 délka obálky + Channel 4 Noise frequency Kanál 4 frekvence šumu + Channel 4 Noise frequency sweep - + Kanál 4 sweep frekvence šumu + Master volume Hlavní hlasitost + Vibrato Vibráto @@ -5024,114 +6425,155 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator NesInstrumentView + + + + Volume Hlasitost + + + Coarse detune Hrubé rozladění + + + Envelope length Délka obálky + Enable channel 1 Zapnout kanál 1 + Enable envelope 1 Zapnout obálku 1 + Enable envelope 1 loop - + Zapnout smyčku obálky 1 + Enable sweep 1 - + Zapnout sweep 1 + + Sweep amount - + Množství sweepu + + Sweep rate - + Rychlost sweepu + + 12.5% Duty cycle - + 12.5% pracovního cyklu + + 25% Duty cycle - + 25% pracovního cyklu + + 50% Duty cycle - + 50% pracovního cyklu + + 75% Duty cycle - + 75% pracovního cyklu + Enable channel 2 Zapnout kanál 2 + Enable envelope 2 Zapnout obálku 2 + Enable envelope 2 loop - + Zapnout smyčku obálky 2 + Enable sweep 2 - + Zapnout sweep 2 + Enable channel 3 Zapnout kanál 3 + Noise Frequency Frekvence šumu + Frequency sweep - + Frekvence sweepu + Enable channel 4 Zapnout kanál 4 + Enable envelope 4 Zapnout obálku 4 + Enable envelope 4 loop - + Zapnout smyčku obálky 4 + Quantize noise frequency when using note frequency - + Kvantizovat frekvenci šumu při použití frekvence noty + Use note frequency for noise - + Použít frekvenci pro šum + Noise mode Typ šumu + Master Volume Hlavní hlasitost + Vibrato Vibráto @@ -5139,81 +6581,103 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator OscillatorObject - Osc %1 volume - Osc %1 hlasitost - - - Osc %1 panning - Panoráma Osc %1 - - - Osc %1 coarse detuning - Osc %1 hrubé rozladění - - - Osc %1 fine detuning left - Osc %1 jemné rozladění vlevo - - - Osc %1 fine detuning right - Osc %1 jemné rozladění vpravo - - - Osc %1 phase-offset - Osc %1 posun fáze - - - Osc %1 stereo phase-detuning - Osc %1 rozladění stereo fáze - - - Osc %1 wave shape - Osc %1 forma vlny - - - Modulation type %1 - - - + Osc %1 waveform Osc %1 vlna + Osc %1 harmonic - + Osc %1 harmonické + + + + + Osc %1 volume + Osc %1 hlasitost + + + + + Osc %1 panning + Osc %1 panoráma + + + + + Osc %1 fine detuning left + Osc %1 jemné rozladění vlevo + + + + Osc %1 coarse detuning + Osc %1 hrubé rozladění + + + + Osc %1 fine detuning right + Osc %1 jemné rozladění vpravo + + + + Osc %1 phase-offset + Osc %1 posun fáze + + + + Osc %1 stereo phase-detuning + Osc %1 rozladění stereo fáze + + + + Osc %1 wave shape + Osc %1 forma vlny + + + + Modulation type %1 + Typ modulace %1 PatchesDialog + Qsynth: Channel Preset Qsynth: Předvolba kanálu + Bank selector Výběr banky + Bank Banka + Program selector Výběr programu + Patch Patch + Name Název + OK OK + Cancel Zrušit @@ -5221,85 +6685,105 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PatmanView + Open other patch Otevřít jiný patch + Click here to open another patch-file. Loop and Tune settings are not reset. - Klikněte sem, pokud chcete otevřít další patch-soubor. Nastavení smyčky a režimu ladění budou zachována. + Klepněte sem, pokud chcete otevřít další patch-soubor. Nastavení smyčky a režimu ladění zůstanou zachována. + Loop Smyčka + Loop mode Režim smyčky + Here you can toggle the Loop mode. If enabled, PatMan will use the loop information available in the file. - + Zde můžete přepínat režim smyčky. Je-li zapnutá, PatMan použije informace o smyčce dostupné v souboru. + Tune Ladění + Tune mode Režim ladění + Here you can toggle the Tune mode. If enabled, PatMan will tune the sample to match the note's frequency. - + Zde můžete přepínat režim ladění. Je-li zapnut, PatMan naladí vzorek tak, aby odpovídal frekvenci noty. + No file selected - + Není vybrán žádný soubor + Open patch file - + Otevřít soubor patch + Patch-Files (*.pat) - + Soubor patch (*.pat) PatternView - Open in piano-roll - Otevřít v piano-roll - - - Clear all notes - Vymazat všechny noty - - - Reset name - Resetovat jméno - - - Change name - Změnit jméno - - - Add steps - Přidat kroky - - - Remove steps - Odstranit kroky - - + use mouse wheel to set velocity of a step použijte kolečko myši pro nastavení dynamiky kroku + double-click to open in Piano Roll - + poklepáním otevřete v Piano rollu + + Open in piano-roll + Otevřít v Piano rollu + + + + Clear all notes + Vymazat všechny noty + + + + Reset name + Resetovat jméno + + + + Change name + Změnit jméno + + + + Add steps + Přidat kroky + + + + Remove steps + Odstranit kroky + + + Clone Steps Klonovat kroky @@ -5307,25 +6791,30 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PeakController + Peak Controller - + Ovladač špičky + Peak Controller Bug - + Chyba ovladače špičky + 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. - + Z důvodu chyby ve starší verzi LMMS nemusí být ovladače špiček správně připojeny. Ujistěte se prosím, zda jsou ovladače špiček správně připojeny a znovu uložte tento soubor. Omlouváme se za způsobené nepříjemnosti. PeakControllerDialog + PEAK - + ŠPIČ + LFO Controller Ovladač LFO @@ -5333,306 +6822,382 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PeakControllerEffectControlDialog + BASE - + ZÁKL + Base amount: Základní míra: - Modulation amount: - Hloubka modulace: - - - Attack: - - - - Release: - Release: - - + AMNT MNOŽ + + Modulation amount: + Hloubka modulace: + + + MULT - + NÁSB + Amount Multiplicator: - + Násobič množství: + ATCK - + NÁBH + + Attack: + Náběh: + + + DCAY - + POKL - Treshold: - + + Release: + Doznění: + TRSH - + PRÁH + + + + Treshold: + Práh: PeakControllerEffectControls + Base value Základní hodnota + Modulation amount Hloubka modulace - Mute output - - - + Attack - Nástup + Náběh + Release - Uvolnění - - - Abs Value - - - - Amount Multiplicator - + Doznění + Treshold - + Práh + + + + Mute output + Ztlumit výstup + + + + Abs Value + Abs hodnota + + + + Amount Multiplicator + Násobič množství PianoRoll - Please open a pattern by double-clicking on it! - Otevřete prosím pattern jeho dvojitým poklepáním! - - - Last note - Podle poslední noty - - - Note lock - Zamknout notu - - + Note Velocity Dynamika noty + Note Panning Panoráma noty + Mark/unmark current semitone - Zvýraznit/skrýt zvolený tón + Zvýraznit/Skrýt zvolený tón + + Mark/unmark all corresponding octave semitones + Zvýraznit/Skrýt zvolený tón ve všech oktávách + + + Mark current scale Zvýraznit zvolenou stupnici + Mark current chord Zvýraznit zvolený akord + Unmark all Skrýt vše + + Select all notes on this key + Vybrat všechny noty zvolené výšky + + + + Note lock + Zamknout notu + + + + Last note + Podle poslední noty + + + No scale Žádná stupnice + No chord Žádný akord + Velocity: %1% Dynamika: %1% + Panning: %1% left Panoráma: %1% vlevo + Panning: %1% right Panoráma: %1% vpravo + Panning: center - Panoráma: %1% střed + Panoráma: střed + + Please open a pattern by double-clicking on it! + Otevřete prosím záznam poklepáním! + + + + Please enter a new value between %1 and %2: Vložte prosím novou hodnotu mezi %1 a %2: - - Mark/unmark all corresponding octave semitones - Zvýraznit/skrýt zvolený tón ve všech oktávách - - - Select all notes on this key - Vybrat všechny noty zvolené výšky - PianoRollWindow + Play/pause current pattern (Space) - Přehrát nebo pozastavit přehrávání aktuálního patternu (mezerník) + Přehrát/Pozastavit přehrávání aktuálního záznamu (mezerník) + Record notes from MIDI-device/channel-piano - Nahrávat z MIDI zařízení nebo z virtuální klávesnice + Nahrávat z MIDI zařízení / virtuální klávesnice + Record notes from MIDI-device/channel-piano while playing song or BB track - Nahrávat z MIDI zařízení nebo z virtuální klávesnice při přehrávání skladby nebo BB stopy + Nahrávat z MIDI zařízení / virtuální klávesnice při přehrávání skladby nebo stopy bicích/basů + Stop playing of current pattern (Space) - Zastavit přehrávání aktuálního patternu (mezerník) + Zastavit přehrávání aktuálního záznamu (mezerník) + Click here to play the current pattern. This is useful while editing it. The pattern is automatically looped when its end is reached. - Klikněte sem, pokud chcete přehrát aktuální pattern. To je užitečné při editaci. Pattern je automaticky přehráván ve smyčce. + Klepněte sem, pokud chcete přehrát aktuální záznam. To je užitečné při editaci. Záznam je automaticky přehráván ve smyčce. + 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. - Klikněte sem, pokud chcete nahrávat z MIDI zařízení nebo z virtuální klávesnice příslušného kanálového okna do aktuálního patternu. Při nahrávání se zaznamenají všechny zahrané noty do tohoto patternu, a následně je můžete přehrát nebo upravit. + Klepněte sem, pokud chcete nahrávat z MIDI zařízení nebo z virtuální klávesnice příslušného kanálového okna do aktuálního záznamu. Při nahrávání se zapíší všechny zahrané noty do tohoto záznamu, a následně je můžete přehrát nebo upravit. + 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. - Klikněte sem, pokud chcete nahrávat z MIDI zařízení nebo z virtuální klávesnice příslušného kanálového okna do aktuálního patternu. Při nahrávání se zaznamenají všechny zahrané noty do tohoto patternu a na pozadí uslyšíte skladbu nebo BB stopu. + Klepněte sem, pokud chcete nahrávat z MIDI zařízení nebo z virtuální klávesnice příslušného kanálového okna do aktuálního záznamu. Při nahrávání se zapíší všechny zahrané noty do tohoto záznamu a na pozadí uslyšíte skladbu nebo stopu bicích/basů. + Click here to stop playback of current pattern. - Klikněte sem, pokud chcete zastavit přehrávání aktuálního patternu. + Klepněte sem, pokud chcete zastavit přehrávání aktuálního záznamu. + + Edit actions + Akce úprav + + + Draw mode (Shift+D) Režim kreslení (Shift+D) + Erase mode (Shift+E) Režim mazání (Shift+E) + Select mode (Shift+S) Režim výběru (Shift+S) - Detune mode (Shift+T) - Režim úpravy ladění (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. - + Klepněte sem pro aktivaci režimu kreslení. V tomto režimu můžete přidávat, měnit a přesouvat noty. Toto je výchozí režim, který se používá nejčastěji. Pro aktivaci tohoto režimu můžete také stisknout "Shift+D" na klávesnici. V tomto režimu podržte %1 pro dočasné přepnutí do režimu výběru. + 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. - + Klepněte sem pro aktivaci režimu mazání. V tomto režimu můžete vymazávat noty. Pro aktivaci tohoto režimu můžete také stisknout tlačítko "Shift+E" na klávesnici. + 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. - + Klepněte sem pro aktivaci režimu výběru. V tomto režimu můžete vybírat noty. Alternativně můžete v režimu kreslení držet %1 pro dočasné přepnutí do režimu výběru. - 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) + Režim ohýbání výšky (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. + Klepněte sem pro aktivaci režimu ohýbání výšky tónu. V tomto režimu můžete klepnutím na notu otevřít její automatizované rozladění. To můžete využít ke sklouznutí z jedné noty na jinou. Pro aktivaci tohoto režimu můžete také stisknout klávesu "Shift+T" na klávesnici. + + + + Quantize + Kvantizace + + + + Copy paste controls + Ovládání kopírování a vkládání + + + Cut selected notes (%1+X) Vyjmout označené noty (%1+X) + Copy selected notes (%1+C) Kopírovat označené noty (%1+C) + Paste notes from clipboard (%1+V) Vložit noty ze schránky (%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. - Klikněte sem, pokud chcete označené noty vyjmout a uložit do schránky. Vložit je pak můžete kdekoliv v libovolném patternu pomocí tlačítka Vložit. + Klepněte sem, pokud chcete označené noty vyjmout a uložit do schránky. Vložit je pak můžete kdekoliv v libovolném záznamu pomocí tlačítka Vložit. + 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. - Klikněte sem, pokud chcete označené noty zkopírovat do schránky. Vložit je pak můžete kdekoliv v libovolného patternu pomocí tlačítka Vložit. + Klepněte sem, pokud chcete označené noty zkopírovat do schránky. Vložit je pak můžete kdekoliv v libovolném záznamu pomocí tlačítka Vložit. + Click here and the notes from the clipboard will be pasted at the first visible measure. - Kliknete-li sem, budou noty ze schránky vloženy do prvního viditelného taktu. - - - 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. - - - - Edit actions - Upravit akce - - - Copy paste controls - + Klepnete-li sem, budou noty ze schránky vloženy do prvního viditelného taktu. + Timeline controls Ovládání časové osy + Zoom and note controls - + Lupa a ovládání not + + 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. + Tímto se ovládá zvětšení osy. To může být užitečné při volbě zvětšení pro konkrétní úkol. Při běžné úpravě by mělo být zvětšení použito na vaše nejmenší noty. + + + + 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. + "Q" znamená kvantizaci, která ovládá mřížku velikosti not a kontrolní body krokování. S menšími hodnotami kvantizace můžete kreslit kratší noty v Piano rollu a přesnější kontrolní body v editoru automatizace. + + + + 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 + Tímto je možno vybrat délku nových not. "Poslední nota" znamená, že LMMS použije délku naposledy upravované noty. + + + + 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! + Funkce je přímo propojena s kontextovou nabídkou na virtuální klávesnici vlevo v Piano rollu. Poté, co jste v rozbalovací nabídce zvolili stupnici, můžete klepnout pravým tlačítkem na požadovanou klávesu na virtuální klávesnici, a pak zvolit "Zvýraznit zvolenou stupnici". LMMS zvýrazní všechny noty, které patří do zvolené stupnice, a to od klávesy, kterou jste vybrali! + + + + 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. + Vyberte si akord, který pak LMMS může nakreslit nebo zvýraznit. V rozbalovací nabídce najdete nejčastěji používané akordy. Po výběru akordu klepněte kamkoliv pro umístění akordu, klepnutím pravým tlačítkem na virtuální klávesnici pak otevřete kontextové menu a zvýrazníte akord. Chcete-li se vrátit k práci s jednotlivými notami, musíte v rozbalovací nabídce zvolit možnost "Žádný akord". + + + + Piano-Roll - %1 - + Piano roll – %1 + + Piano-Roll - no pattern - - - - Quantize - + Piano roll – žádný záznam PianoView + Base note Základní nota @@ -5640,20 +7205,24 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator Plugin + Plugin not found Plugin nenalezen + The plugin "%1" wasn't found or could not be loaded! Reason: "%2" Plugin "%1" nebyl nalezen nebo nemůže být načten! Důvod: "%2" + Error while loading plugin Při načítání pluginu došlo k chybě + Failed to load plugin "%1"! Načtení pluginu "%1" selhalo! @@ -5661,144 +7230,178 @@ Důvod: "%2" PluginBrowser + + Instrument Plugins + Nástrojové pluginy + + + Instrument browser Prohlížeč nástrojů + Drag an instrument into either the Song-Editor, the Beat+Bassline Editor or into an existing instrument track. - Nástroj přetáhněte do editoru skladby, editoru bicích a basů nebo do existující nástrojové stopy. - - - Instrument Plugins - + Nástroj přetáhněte do editoru skladby, editoru bicích/basů nebo do existující nástrojové stopy. PluginFactory + Plugin not found. Plugin nebyl nalezen. + LMMS plugin %1 does not have a plugin descriptor named %2! - + U LMMS pluginu %1 chybí popisovač pluginu s názvem %2! ProjectNotes - Project notes + + Project Notes Poznámky k projektu - Put down your project notes here. - Do tohoto okna můžete vkládat Vaše poznámky k projektu. + + Enter project notes here + Sem zapište poznámky k projektu + Edit Actions - + Provedené úpravy + &Undo &Zpět + %1+Z %1+Z + &Redo &Znovu + %1+Y %1+Z + &Copy &Kopírovat + %1+C %1+C + Cu&t &Vyjmout + %1+X %1+X + &Paste V&ložit + %1+V %1+V + Format Actions Formátování + &Bold &Tučné + %1+B %1+B + &Italic &Kurzíva + %1+I %1+I + &Underline &Podtržené + %1+U %1+U + &Left &Vlevo + %1+L %1+L + C&enter &Na střed + %1+E %1+E + &Right V&pravo + %1+R %1+R + &Justify &Do bloku + %1+J %1+J + &Color... &Barva... @@ -5806,184 +7409,326 @@ Důvod: "%2" ProjectRenderer + WAV-File (*.wav) WAV soubor (*.wav) + Compressed OGG-File (*.ogg) - Komprimovaný soubor OGG (*.ogg) + Komprimovaný OGG soubor (*.ogg) + + + + Compressed MP3-File (*.mp3) + Komprimovaný soubor MP3 (*.mp3) QWidget + + + Name: - Název: + Název: + + Maker: - Tvůrce: + Tvůrce: + + Copyright: - Copyright: + Autorská práva: + + Requires Real Time: - Vyžadován Real Time: + Vyžaduje běh v reálném čase: + + + + + + Yes Ano + + + + + + No Ne + + Real Time Capable: - Real time schopnost: + Schopnost běhu v reálném čase: + + In Place Broken: - + Na místě poškozeného: + + Channels In: - Kanály vstup: + Vstupní kanály: + + Channels Out: - Kanály výstup: - - - File: - Soubor: + Výstupní kanály: + File: %1 - + Soubor: %1 + + + + File: + Soubor: RenameDialog + Rename... Přejmenovat... + + ReverbSCControlDialog + + + Input + Vstup + + + + Input Gain: + Zesílení vstupu: + + + + Size + Velikost + + + + Size: + Velikost: + + + + Color + Barva + + + + Color: + Barva: + + + + Output + Výstup + + + + Output Gain: + Zesílení výstupu: + + + + ReverbSCControls + + + Input Gain + Vstupní úroveň + + + + Size + Velikost + + + + Color + Barva + + + + Output Gain + Zesílení výstupu + + SampleBuffer + + Fail to open file + Chyba otevírání souboru + + + + Audio files are limited to %1 MB in size and %2 minutes of playing time + Audio soubory jsou omezeny na %1 MB velikosti a %2 minut délky + + + Open audio file Otevřít audio soubor - Wave-Files (*.wav) - Wav soubory (*.wav) + + All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + Všechny audio soubory (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + + Wave-Files (*.wav) + WAV soubory (*.wav) + + + OGG-Files (*.ogg) OGG soubory (*.ogg) + DrumSynth-Files (*.ds) DrumSynth soubory (*.ds) + FLAC-Files (*.flac) FLAC soubory (*.flac) + SPEEX-Files (*.spx) SPEEX soubory (*.spx) + VOC-Files (*.voc) VOC soubory (*.voc) + AIFF-Files (*.aif *.aiff) - + Soubory AIFF (*.aif *.aiff) + AU-Files (*.au) AU soubory (*.au) + RAW-Files (*.raw) RAW soubory (*.raw) - - All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) - Všechny audio soubory (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) - SampleTCOView + double-click to select sample - dvojitým kliknutím vyberte sampl + poklepáním vyberte sampl + Delete (middle mousebutton) Smazat (prostřední tlačítko myši) + Cut Vyjmout + Copy Kopírovat + Paste Vložit + Mute/unmute (<%1> + middle click) - Ztlumit/neztlumit (<%1> + prostřední klik) + Ztlumit/Odtlumit (<%1> + prostřední tlačítko) SampleTrack - Sample track - Stopa samplů - - + Volume Hlasitost + Panning Panoráma + + + + Sample track + Stopa samplů + SampleTrackView + Track volume Hlasitost stopy + Channel volume: Hlasitost kanálu: + VOL HLA + Panning Panoráma + Panning: Panoráma: + PAN PAN @@ -5991,496 +7736,659 @@ Důvod: "%2" SetupDialog + Setup LMMS Nastavení LMMS + + General settings Hlavní nastavení + BUFFER SIZE VELIKOST VYR. PAMĚTI + + Reset to default-value Nastavit výchozí hodnoty + MISC - RŮZNÉ + JINÉ + Enable tooltips Zapnout bublinovou nápovědu + Show restart warning after changing settings Zobrazit výzvu k restartu po změně nastavení + Display volume as dBFS - Zobrazit hlasitost jako dBFS + Zobrazit hlasitost v dBFS + Compress project files per default Komprimovat soubory s projekty + One instrument track window mode Režim jedné stopy pro nástroje + HQ-mode for output audio-device HQ režim pro výstup audio zařízení + Compact track buttons Malá tlačítka u stop + Sync VST plugins to host playback Synchronizace VST pluginů s hostujícím přehráváním + Enable note labels in piano roll - Povolit názvy tónů v piano rollu + Povolit názvy tónů v Piano rollu + Enable waveform display by default Povolit zobrazení vlny ve výchozím nastavení + Keep effects running even without input Nechat efekty spuštěné i bez vstupu + Create backup file when saving a project Při ukládání projektu vytvořit záložní soubor + + Reopen last project on start + Po spuštění otevřít poslední projekt + + + + Use built-in NaN handler + Použít vestavěný NaN handler + + + + PLUGIN EMBEDDING + VLOŽENÍ PLUGINU + + + + No embedding + Nevkládat + + + + Embed using Qt API + Vložit pomocí rozhraní Qt + + + + Embed using native Win32 API + Vložit pomocí nativního rozhraní Win32 + + + + Embed using XEmbed protocol + Vložit pomocí protokolu XEmbed + + + LANGUAGE Jazyk + + Paths Cesty + + Directories + Adresáře + + + LMMS working directory Pracovní adresář LMMS - VST-plugin directory - Adresář pro VST pluginy + + Themes directory + Adresář pro témata + Background artwork Obrázek na pozadí + + VST-plugin directory + Adresář pro VST pluginy + + + + GIG directory + Adresář pro GIG + + + + SF2 directory + Adresář pro SF2 + + + + LADSPA plugin directories + Adresář pro LADSPA pluginy + + + STK rawwave directory Adresář pro STK rawwave + Default Soundfont File Výchozí Soundfont soubor + + Performance settings Nastavení výkonu + + Auto save + Automatické ukládání + + + + Enable auto-save + Povolit automatické ukládání + + + + Allow auto-save while playing + Povolit automatické ukládání během přehrávání + + + UI effects vs. performance Efekty uživatelského rozhraní vs. výkon + Smooth scroll in Song Editor Plynulé posouvání v Song Editoru + Show playback cursor in AudioFileProcessor Zobrazit přehrávací kurzor v AudioFileProcessoru + + Audio settings Audio nastavení + AUDIO INTERFACE AUDIO ROZHRANÍ + + MIDI settings MIDI nastavení + MIDI INTERFACE MIDI ROZHRANÍ + OK OK + Cancel Zrušit + Restart LMMS Restartovat LMMS + Please note that most changes won't take effect until you restart LMMS! Mnohé změny nastavení se projeví až po restartu LMMS! + Frames: %1 Latency: %2 ms Rámce: %1 Zpoždění %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. Zde můžete nastavit interní velikost vyrovnávací paměti, která je užívána LMMS. Nízké hodnoty vedou k menšímu zpoždění, ale také způsobují nepoužitelný zvuk nebo špatný výkon, zejména na starých počítačích či systémech s jádrem nepodporujícím real time. + Choose LMMS working directory Vyberte pracovní adresář LMMS - Choose your VST-plugin directory - Vyberte adresář pro VST pluginy - - - Choose artwork-theme directory - Vyberte adresář s tématy - - - Choose LADSPA plugin directory - Vyberte adresář pro LADSPA pluginy - - - Choose STK rawwave directory - Vyberte adresář pro STK rawwave - - - Choose default SoundFont - Vyberte výchozí SoundFont - - - Choose background artwork - Vyberte obrázek na pozadí - - - 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. - Zde vyberte preferované audio rozhraní. V závislosti na konfiguraci Vašeho systému při kompilaci můžete volit mezi ALSA, JACK, OSS a dalšími. Níže vidíte políčko, které nabízí možnost nastavení vybraného audio rozhraní. - - - 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. - Zde vyberte preferované MIDI rozhraní. V závislosti na konfiguraci Vašeho systému při kompilaci můžete volit mezi ALSA OSS a dalšími. Níže vidíte políčko, které nabízí možnost nastavení vybraného MIDI rozhraní. - - - Reopen last project on start - Po spuštění otevřít poslední projekt - - - Directories - Adresáře - - - Themes directory - Adresář pro témata - - - GIG directory - Adresář pro GIG - - - SF2 directory - Adresář pro SF2 - - - LADSPA plugin directories - Adresář pro LADSPA pluginy - - - Auto save - Automatické ukládání - - + Choose your GIG directory Vyberte svůj adresář pro GIG soubory + Choose your SF2 directory Vyberte svůj adresář pro SF2 soubory + + Choose your VST-plugin directory + Vyberte adresář pro VST pluginy + + + + Choose artwork-theme directory + Vyberte adresář s tématy + + + + Choose LADSPA plugin directory + Vyberte adresář pro LADSPA pluginy + + + + Choose STK rawwave directory + Vyberte adresář pro STK rawwave + + + + Choose default SoundFont + Vyberte výchozí SoundFont + + + + Choose background artwork + Vyberte obrázek na pozadí + + + minutes minut + minute minuta - Enable auto-save - - - - Allow auto-save while playing - - - + Disabled - + Vypnuto + Auto-save interval: %1 - + Interval automatického ukládání: %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. - + Nastavte čas mezi automatickým zálohováním na %1. +Nezapomeňte také svůj projekt uložit ručně. Můžete si vybrat, zda nechcete během přehrávání zakázat ukládání, což je problematické pro některé starší systémy. + + + + 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. + Zde vyberte preferované audio rozhraní. V závislosti na konfiguraci Vašeho systému při kompilaci můžete volit mezi ALSA, JACK, OSS a dalšími. Níže vidíte políčko, které nabízí možnost nastavení vybraného audio rozhraní. + + + + 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. + Zde vyberte preferované MIDI rozhraní. V závislosti na konfiguraci Vašeho systému při kompilaci můžete volit mezi ALSA OSS a dalšími. Níže vidíte políčko, které nabízí možnost nastavení vybraného MIDI rozhraní. Song + Tempo Tempo + Master volume Hlavní hlasitost + Master pitch - Hlavní ladění + Transpozice + + LMMS Error report + Chybové hlášení LMMS + + + Project saved Projekt uložen + The project %1 is now saved. Projekt %1 je nyní uložen. + Project NOT saved. Projekt NENÍ uložen. + The project %1 was not saved! Projekt %1 nebyl uložen! + Import file Importovat soubor + MIDI sequences MIDI sekvence + Hydrogen projects Projekty Hydrogen + All file types Všechny typy souborů + + Empty project Prázdný projekt + + This project is empty so exporting makes no sense. Please put some items into Song Editor first! Tento projekt je prázdný, jeho exportování nemá smysl. Nejdříve prosím vložte nějaké položky do Editoru skladby! + Select directory for writing exported tracks... Vyberte adresář pro zápis exportovaných stop... + + untitled nepojmenovaný + + Select file for project-export... - + Vyberte soubor pro export projektu... - The following errors occured while loading: - Během načítání se vyskytly tyto chyby: + + Save project + Uložit projekt + MIDI File (*.mid) MIDI soubor (*.mid) - LMMS Error report - - - - Save project - + + The following errors occured while loading: + Během načítání se vyskytly tyto chyby: SongEditor + Could not open file Nemohu otevřít soubor - Could not write file - Nemohu zapsat soubor - - + 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. Nelze otevřít soubor %1. Pravděpodobně nemáte oprávnění číst tento soubor. Ujistěte se prosím, že máte oprávnění alespoň číst tento soubor a zkuste to znovu. - Error in file - Chyba v souboru - - - The file %1 seems to contain errors and therefore can't be loaded. - Soubor %1 pravděpodobně obsahuje chyby, a proto nemohl být načten. - - - Tempo - Tempo - - - TEMPO/BPM - TEMPO/BPM - - - tempo of song - tempo skladby - - - 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). - Tempo skladby je uvedeno v úderech za minutu (BPM). Chcete-li změnit tempo skladby, změňte tuto hodnotu. Každý takt má čtyři doby (beats), takže tempo v BPM specifikuje kolik taktů / 4 bude za minutu přehráno (nebo kolik taktů bude přehráno ve čtyřech minutách). - - - High quality mode - Režim vysoké kvality - - - Master volume - Hlavní hlasitost - - - master volume - hlavní hlasitost - - - Master pitch - Hlavní ladění - - - master pitch - hlavní ladění - - - Value: %1% - Hodnota: %1% - - - Value: %1 semitones - Hodnota: %1 půltónů + + Could not write file + Nemohu zapsat soubor + 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. Nelze zapisovat do souboru %1. Pravděpodobně nemáte oprávnění zapisovat do tohoto souboru. Ujistěte se prosím, že máte oprávnění zapisovat do tohoto souboru a zkuse to znovu. + + Error in file + Chyba v souboru + + + + The file %1 seems to contain errors and therefore can't be loaded. + Soubor %1 pravděpodobně obsahuje chyby, a proto nemohl být načten. + + + + Version difference + Rozdíl verzí + + + + This %1 was created with LMMS %2. + %1 byl vytvořen v LMMS %2. + + + template šablona + project projekt - Version difference - + + Tempo + Tempo - This %1 was created with LMMS %2. - + + TEMPO/BPM + TEMPO/BPM + + + + tempo of song + tempo skladby + + + + 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). + Tempo skladby je uvedeno v úderech za minutu (BPM). Chcete-li změnit tempo skladby, změňte tuto hodnotu. Každý takt má čtyři doby (beats), takže tempo v BPM specifikuje kolik taktů / 4 bude za minutu přehráno (nebo kolik taktů bude přehráno ve čtyřech minutách). + + + + High quality mode + Režim vysoké kvality + + + + + Master volume + Hlavní hlasitost + + + + master volume + hlavní hlasitost + + + + + Master pitch + Transpozice + + + + master pitch + transpozice + + + + Value: %1% + Hodnota: %1% + + + + Value: %1 semitones + Hodnota: %1 půltónů SongEditorWindow + Song-Editor Editor skladby + Play song (Space) Přehrát skladbu (mezerník) + Record samples from Audio-device Nahrát samply z audio zařízení + Record samples from Audio-device while playing song or BB track - Nahrát samply z audio zařízení při přehrávání skladby nebo BB stopy + Nahrát samply z audio zařízení při přehrávání skladby nebo stopy bicích/basů + Stop song (Space) Zastavit přehrávání (mezerník) + + 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. + Klepněte sem, pokud chcete přehrát celou skladbu. Přehrávání začne v místě kde se nalézá zelený označovač pozice, se kterým lze též při přehrávání pohybovat. + + + + Click here, if you want to stop playing of your song. The song-position-marker will be set to the start of your song. + Klepněte sem, pokud chcete zastavit přehrávání skladby. Označovač pozice bude nastaven na začátek skladby. + + + + Track actions + Akce stopy + + + Add beat/bassline Přidat bicí/basy + Add sample-track Přidat stopu samplů + Add automation-track - Přidat automatizační stopu + Přidat stopu automatizace + + Edit actions + Akce úprav + + + Draw mode Režim kreslení + Edit mode (select and move) Režim úprav (označit a přesunout) - 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. - Klikněte sem, pokud chcete přehrát celou skladbu. Přehrávání začne v místě kde se nalézá zelený označovač pozice, se kterým lze též při přehrávání pohybovat. - - - Click here, if you want to stop playing of your song. The song-position-marker will be set to the start of your song. - Klikněte sem, pokud chcete zastavit přehrávání skladby. Označovač pozice bude nastaven na začátek skladby. - - - Track actions - - - - Edit actions - Upravit akce - - + Timeline controls Ovládání časové osy + Zoom controls Ovládání zvětšení @@ -6488,10 +8396,12 @@ Remember to also save your project manually. You can choose to disable saving wh SpectrumAnalyzerControlDialog + Linear spectrum Lineární spektrum + Linear Y axis Lineární osa Y @@ -6499,14 +8409,17 @@ Remember to also save your project manually. You can choose to disable saving wh SpectrumAnalyzerControls + Linear spectrum Lineární spektrum + Linear Y axis Lineární osa Y + Channel mode Režim kanálu @@ -6514,14 +8427,17 @@ Remember to also save your project manually. You can choose to disable saving wh SubWindow + Close Zavřít + Maximize Maximalizovat + Restore Obnovit @@ -6529,81 +8445,102 @@ Remember to also save your project manually. You can choose to disable saving wh TabWidget + + Settings for %1 - + Nastavení rpo %1 TempoSyncKnob + + Tempo Sync Synchronizace tempa + No Sync Nesynchronizovat + Eight beats Osm dob + Whole note Celá nota + Half note Půlová nota + Quarter note Čtvrťová nota + 8th note Osminová nota + 16th note Šestnáctinová nota + 32nd note Dvaatřicetinová nota + Custom... Vlastní... + Custom Vlastní + Synced to Eight Beats Synchronizováno k osmi dobám + Synced to Whole Note Synchronizováno k celé notě + Synced to Half Note Synchronizováno k půlové notě + Synced to Quarter Note Synchronizováno ke čtvrťové notě + Synced to 8th Note Synchronizováno k osminové notě + Synced to 16th Note Synchronizováno k šestnáctinové notě + Synced to 32nd Note Synchronizováno k dvaatřicetinové notě @@ -6611,76 +8548,94 @@ Remember to also save your project manually. You can choose to disable saving wh TimeDisplayWidget + click to change time units - kliknutí změní časové jednotky + klepněte pro změnu časových jednotek + MIN - + MIN + SEC - + S + MSEC - + MS + BAR - + TAKT + BEAT DOBA + TICK - + TIK TimeLineWidget + Enable/disable auto-scrolling - Povolit/zakázat automatický posun + Povolit/Zakázat automatický posun + Enable/disable loop-points - Povolit/zakázat body přehrávání ve smyčce + Povolit/Zakázat body přehrávání ve smyčce + After stopping go back to begin Po skončení přetočit zpět na začátek + After stopping go back to position at which playing was started Po skončení přetočit zpět na pozici, ze které přehrávání začalo + After stopping keep position Po skončení zachovat pozici + + Hint Rada + Press <%1> to disable magnetic loop points. - + Stiskněte <%1> pro vypnutí magnetických bodů smyčky. + Hold <Shift> to move the begin loop point; Press <%1> to disable magnetic loop points. - + Držte <Shift> pro přesouvání počátečního bodu smyčky; stiskněte <%1> pro vypnutí magnetických bodů smyčky. Track + Mute Ztlumit + Solo Sólo @@ -6688,38 +8643,63 @@ Remember to also save your project manually. You can choose to disable saving wh TrackContainer + Couldn't import file Nemohu importovat soubor + Couldn't find a filter for importing file %1. You should convert this file into a format supported by LMMS using another software. Nemohu najít filtr pro import souboru %1. Měli byste tento soubor převést do formátu podporovaného LMMS pomocí jiného software. + Couldn't open file Nemohu otevřít soubor + 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! Nemohu otevřít soubor %1 pro čtení. Přesvědčte se prosím, že máte právo ke čtení tohoto souboru a příslušného adresáře a zkuste to znovu! + Loading project... Načítám projekt... + + Cancel Zrušit + + Please wait... Prosím čekejte... + + Loading cancelled + Načítání zrušeno + + + + Project loading was cancelled. + Načítání projektu bylo zrušeno. + + + + Loading Track %1 (%2/Total %3) + Načítám Stopu %1 (%2/celkem %3) + + + Importing MIDI-file... Importuji MIDI soubor... @@ -6727,6 +8707,7 @@ Přesvědčte se prosím, že máte právo ke čtení tohoto souboru a příslu TrackContentObject + Mute Ztlumit @@ -6734,240 +8715,303 @@ Přesvědčte se prosím, že máte právo ke čtení tohoto souboru a příslu TrackContentObjectView + Current position Aktuální pozice + + Hint Rada + Press <%1> and drag to make a copy. K vytvoření kopie stiskněte <%1> a táhněte myší. + Current length Aktuální délka + Press <%1> for free resizing. Stiskněte <%1> pro volnou změnu velikosti. + + %1:%2 (%3:%4 to %5:%6) %1:%2 (%3:%4 do %5:%6) + Delete (middle mousebutton) Smazat (prostřední tlačítko myši) + Cut Vyjmout + Copy Kopírovat + Paste Vložit + Mute/unmute (<%1> + middle click) - Ztlumit/odtlumit (<%1> + prostřední tlačítko myši) + Ztlumit/Odtlumit (<%1> + prostřední tlačítko myši) TrackOperationsWidget + Press <%1> while clicking on move-grip to begin a new drag'n'drop-action. - + Při klepnutí na úchop držte <%1> pro zkopírování přetahované stopy. + Actions for this track Akce pro tuto stopu + Mute Ztlumit + + Solo Sólo + Mute this track Ztlumit tuto stopu + Clone this track Klonovat tuto stopu + Remove this track Odstranit tuto stopu + Clear this track - Klonovat tuto stopu + Smazat tuto stopu + FX %1: %2 - FX %1: %2 - - - Turn all recording on - - - - Turn all recording off - Zastavit veškeré nahrávání + Efekt %1: %2 + Assign to new FX Channel - + Přiřadit k novému efektovému kanálu + + + + Turn all recording on + Spustit všechna nahrávání + + + + Turn all recording off + Zastavit všechna nahrávání TripleOscillatorView + Use phase modulation for modulating oscillator 1 with oscillator 2 - + Použít fázovou modulaci pro modulování oscilátoru 1 oscilátorem 2 + Use amplitude modulation for modulating oscillator 1 with oscillator 2 - + Použít amplitudovou modulaci pro modulování oscilátoru 1 oscilátorem 2 + Mix output of oscillator 1 & 2 - + Smíchat výstupy oscilátorů 1 a 2 + Synchronize oscillator 1 with oscillator 2 - + Synchronizovat oscilátor 1 oscilátorem 2 + Use frequency modulation for modulating oscillator 1 with oscillator 2 - + Použít frekvenční modulaci pro modulování oscilátoru 1 oscilátorem 2 + Use phase modulation for modulating oscillator 2 with oscillator 3 - + Použít fázovou modulaci pro modulování oscilátoru 2 oscilátorem 3 + Use amplitude modulation for modulating oscillator 2 with oscillator 3 - + Použít amplitudovou modulaci pro modulování oscilátoru 2 oscilátorem 3 + Mix output of oscillator 2 & 3 - + Smíchat výstupy oscilátorů 2 a 3 + Synchronize oscillator 2 with oscillator 3 - + Synchronizovat oscilátor 2 oscilátorem 3 + Use frequency modulation for modulating oscillator 2 with oscillator 3 - + Použít frekvenční modulaci pro modulování oscilátoru 2 oscilátorem 3 + Osc %1 volume: Osc %1 hlasitost: + 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. Tímto otočným ovladačem můžete nastavit hlasitost oscilátoru %1. Když nastavíte hodnotu 0, oscilátor bude vypnutý. Jinak uslyšíte oscilátor tak hlasitě, jak si ho zde nastavíte. + Osc %1 panning: - Panoráma Osc %1: + Osc %1 panoráma: + 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. Tímto otočným ovladačem můžete nastavit panoráma oscilátoru %1. Hodnota -100 znamená maximálně doleva, zatímco hodnota 100 přesouvá výstup oscilátoru doprava. + Osc %1 coarse detuning: - + Osc %1 hrubé rozladění: + semitones půltónů + 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. - + Tímto otočným ovladačem můžete provést hrubé rozladění oscilátoru %1. Můžete oscilátor rozladit o 24 půltónů (2 oktávy) nahoru nebo dolů. To je dobré pro vytvoření zvuku v akordu. + Osc %1 fine detuning left: Osc %1 jemné rozladění vlevo: + + cents centů + 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. - + Tímto otočným ovladačem můžete provést jemné rozladění oscilátoru %1 v levém kanálu. Rozsah jemného rozladění je mezi -100 a +100 centy. To je dobré pro vytvoření "tlustého" zvuku. + Osc %1 fine detuning right: Osc %1 jemné rozladění vpravo: + 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. - + Tímto otočným ovladačem můžete provést jemné rozladění oscilátoru %1 v pravém kanálu. Rozsah jemného rozladění je mezi -100 a +100 centy. To je dobré pro vytvoření "tlustého" zvuku. + Osc %1 phase-offset: Osc %1 posun fáze: + + degrees - stupně + stupňů + 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. - + Tímto otočným ovladačem můžete nastavit fázový posun oscilátoru %1. To znamená, že můžete posunout bod, ve kterém oscilátor začne kmitat. Například pokud máte sinusovou vlnu s fázovým posunem 180 stupňů, vlna půjde nejdříve dolů. Totéž se stane u vlny pravoúhlé. + Osc %1 stereo phase-detuning: Osc %1 rozladění stereo fáze: + 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. - + Tímto otočným ovladačem můžete nastavit rozladění fáze oscilátoru %1. Rozladění stereo fáze určuje velikost rozdílu mezi fázovým posunem levého a pravého kanálu. To je velmi dobré pro vytvoření širokého stereo zvuku. + Use a sine-wave for current oscillator. Použít sinusovou vlnu pro aktuální oscilátor. + Use a triangle-wave for current oscillator. Použít trojúhelníkovou vlnu pro aktuální oscilátor. + Use a saw-wave for current oscillator. - Klikněte sem pro pilovitou vlnu. + Použít pilovitou vlnu pro aktuální oscilátor. + Use a square-wave for current oscillator. - Klikněte sem pro pilovitou vlnu. + Klepněte sem pro pravoúhlou vlnu. + Use a moog-like saw-wave for current oscillator. - + Použít pilovitou vlnu typu Moog pro tento oscilátor. + Use an exponential wave for current oscillator. - + Použít exponenciální vlnu pro aktuální oscilátor. + Use white-noise for current oscillator. Použít bílý šum pro aktuální oscilátor. + Use a user-defined waveform for current oscillator. Použít vlastní vlnu pro aktuální oscilátor. @@ -6975,688 +9019,883 @@ Přesvědčte se prosím, že máte právo ke čtení tohoto souboru a příslu VersionedSaveDialog + Increment version number - + Zvýšit číslo verze + Decrement version number - + Snížení čísla verze + already exists. Do you want to replace it? - + již existuje. Přejete si jej přepsat? VestigeInstrumentView + Open other VST-plugin Otevřít jiný 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. - Klikněte sem, pokud chcete otevřít jiný VST plugin. Po kliknutí na toto tlačítko se objeví okno, ve kterém můžete soubor vybrat. - - - Show/hide GUI - Zobrazit/skrýt grafické rozhraní - - - Click here to show or hide the graphical user interface (GUI) of your VST-plugin. - Klikněte sem pro zobrazení nebo skrytí grafického rozhraní (GUI) pro vaše VST pluginy. - - - Turn off all notes - Vypnout všechny noty - - - Open VST-plugin - Otevřít jiný VST plugin - - - DLL-files (*.dll) - DLL soubory (*.dll) - - - EXE-files (*.exe) - EXE soubory (*.exe) - - - No VST-plugin loaded - Není načten VST plugin + Klepněte sem, pokud chcete otevřít jiný VST plugin. Po klepnutí na toto tlačítko se objeví okno, ve kterém můžete soubor vybrat. + Control VST-plugin from LMMS host - + Ovládání VST pluginu hostitelským programem LMMS + Click here, if you want to control VST-plugin from host. - + Klepněte sem, pokud chcete ovládat VST plugin hostitelským programem. + Open VST-plugin preset Otevřít předvolbu VST pluginu + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. - Klikněte sem, chcete-li otevřít jinou *.fxp, *.fxb předvolbu VST pluginu. + Klepněte sem, chcete-li otevřít jinou *.fxp, *.fxb předvolbu VST pluginu. + Previous (-) - + Předchozí (-) + + Click here, if you want to switch to another VST-plugin preset program. - Klikněte sem, chcete-li přepnout na jiný přednastavený VST program. + Klepněte sem, chcete-li přepnout na jiný přednastavený VST program. + Save preset Uložit předvolbu + Click here, if you want to save current VST-plugin preset program. - Klikněte sem, chcete-li uložit aktuální předvolbu programu VST pluginu. + Klepněte sem, chcete-li uložit aktuální předvolbu programu VST pluginu. + Next (+) Další (+) + Click here to select presets that are currently loaded in VST. - Klikněte sem, chcete-li vybrat předvolby, které jsou aktuálně nahrány ve VST. + Klepněte sem, chcete-li vybrat předvolby, které jsou aktuálně nahrány ve VST. + + Show/hide GUI + Zobrazit/Skrýt grafické rozhraní + + + + Click here to show or hide the graphical user interface (GUI) of your VST-plugin. + Klepněte sem pro zobrazení nebo skrytí grafického rozhraní (GUI) pro vaše VST pluginy. + + + + Turn off all notes + Vypnout všechny noty + + + + Open VST-plugin + Otevřít jiný VST plugin + + + + DLL-files (*.dll) + DLL soubory (*.dll) + + + + EXE-files (*.exe) + EXE soubory (*.exe) + + + + No VST-plugin loaded + VST plugin není nahrán + + + Preset Předvolba + by - + od + - VST plugin control - + – ovládání VST pluginu VisualizationWidget + click to enable/disable visualization of master-output - klikněte pro zapnutí/vypnutí vizualizace hlavního výstupu + klepněte pro zapnutí/vypnutí vizualizace hlavního výstupu + Click to enable - Klikněte pro zapnutí + Klepněte pro zapnutí VstEffectControlDialog + Show/hide - Ukázat/skrýt + Ukázat/Skrýt + Control VST-plugin from LMMS host - + Ovládání VST pluginu hostitelským programem LMMS + Click here, if you want to control VST-plugin from host. - + Klepněte sem, pokud chcete ovládat VST plugin hostitelským programem. + Open VST-plugin preset Otevřít předvolbu VST pluginu + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. - Klikněte sem, chcete-li otevřít jinou *.fxp, *.fxb předvolbu VST pluginu. + Klepněte sem, chcete-li otevřít jinou *.fxp, *.fxb předvolbu VST pluginu. + Previous (-) - + Předchozí (-) + + Click here, if you want to switch to another VST-plugin preset program. - Klikněte sem, chcete-li přepnout na jiný přednastavený VST program. + Klepněte sem, chcete-li přepnout na jiný přednastavený VST program. + Next (+) Další (+) + Click here to select presets that are currently loaded in VST. - Klikněte sem, chcete-li vybrat předvolbu, která je aktuálně nahraná ve VST. + Klepněte sem, chcete-li vybrat předvolby, které jsou aktuálně nahrány ve VST. + Save preset Uložit předvolbu + Click here, if you want to save current VST-plugin preset program. - Klikněte sem, chcete-li uložit aktuální předvolbu programu VST pluginu. + Klepněte sem, chcete-li uložit aktuální předvolbu programu VST pluginu. + + Effect by: - + Efekt od: + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> - + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> VstPlugin - Loading plugin - Načítám plugin + + + The VST plugin %1 could not be loaded. + VST plugin %1 nelze načíst. + Open Preset Otevřít předvolbu + + Vst Plugin Preset (*.fxp *.fxb) Předvolba VST pluginu (*.fxp *.fxb) + : default - + : výchozí + " - + " + ' - + ' + Save Preset Uložit předvolbu + .fxp .fxp + .FXP .FXP + .FXB .FXB + .fxb .fxb - Please wait while loading VST plugin... - Počkejte prosím, než se načte VST plugin... + + Loading plugin + Načítám plugin - The VST plugin %1 could not be loaded. - VST plugin %1 nelze načíst. + + Please wait while loading VST plugin... + Počkejte prosím, než se načte VST plugin... WatsynInstrument + Volume A1 Hlasitost A1 + Volume A2 Hlasitost A2 + Volume B1 Hlasitost B1 + Volume B2 Hlasitost B2 + Panning A1 Panoráma A1 + Panning A2 Panoráma A2 + Panning B1 Panoráma B1 + Panning B2 Panoráma B2 + Freq. multiplier A1 - + Násobič frekv. A1 + Freq. multiplier A2 - + Násobič frekv. A2 + Freq. multiplier B1 - + Násobič frekv. B1 + Freq. multiplier B2 - + Násobič frekv. B2 + Left detune A1 - + Rozladění vlevo A1 + Left detune A2 - + Rozladění vlevo A2 + Left detune B1 - + Rozladění vlevo B1 + Left detune B2 - + Rozladění vlevo B2 + Right detune A1 - + Rozladění vpravo A1 + Right detune A2 - + Rozladění vpravo A2 + Right detune B1 - + Rozladění vpravo B1 + Right detune B2 - + Rozladění vpravo B2 + A-B Mix - + Směšovač A-B + A-B Mix envelope amount - + Množství obálky směšovače A-B + A-B Mix envelope attack - + Náběh obálky směšovače A-B + A-B Mix envelope hold - + Množství zadržení směšovače A-B + A-B Mix envelope decay - + Pokles obálky směšovače A-B + A1-B2 Crosstalk - + Přeslech A1-B2 + A2-A1 modulation - + Modulace A1-B2 + B2-B1 modulation - + Modulace B2-B1 + Selected graph - + Zvolený graf WatsynView - Select oscillator A1 - - - - Select oscillator A2 - - - - Select oscillator B1 - - - - Select oscillator B2 - - - - Mix output of A2 to A1 - - - - Modulate amplitude of A1 with output of A2 - - - - Ring-modulate A1 and A2 - - - - Modulate phase of A1 with output of A2 - - - - Mix output of B2 to B1 - - - - Modulate amplitude of B1 with output of B2 - - - - Ring-modulate B1 and B2 - - - - Modulate phase of B1 with output of B2 - - - - Draw your own waveform here by dragging your mouse on this graph. - Kreslení vlastní křivky tahem myši na tomto grafu. - - - Load waveform - Načíst vlnu - - - Click to load a waveform from a sample file - Klikněte pro načtení vlny ze souboru samplů. - - - Phase left - - - - Click to shift phase by -15 degrees - - - - Phase right - - - - Click to shift phase by +15 degrees - - - - Normalize - Normalizovat - - - Click to normalize - - - - Invert - - - - Click to invert - - - - Smooth - Uhladit - - - Click to smooth - Klikněte pro vyhlazení - - - Sine wave - Sinusová vlna - - - Click for sine wave - Klikněte pro sinusovou vlnu - - - Triangle wave - Trojúhelníková vlna - - - Click for triangle wave - Klikněte pro trojúhelníkovou vlnu - - - Click for saw wave - Klikněte pro pilovitou vlnu - - - Square wave - Pravoúhlá vlna - - - Click for square wave - Klikněte pro pravoúhlou vlnu - - + + + + Volume Hlasitost + + + + Panning Panoráma + + + + Freq. multiplier - Frekv. multiplikátor + Násobič frekv. + + + + Left detune - + Rozladění vlevo + + + + + + + + cents centů + + + + Right detune - + Rozladění vpravo + A-B Mix - + Směšovač A-B + Mix envelope amount - + Množství obálky směšovače + Mix envelope attack - + Náběh obálky směšovače + Mix envelope hold - + Zadržení obálky směšovače + Mix envelope decay - + Pokles obálky směšovače + Crosstalk - + Přeslech + + + + Select oscillator A1 + Vybrat oscilátor A1 + + + + Select oscillator A2 + Vybrat oscilátor A2 + + + + Select oscillator B1 + Vybrat oscilátor B1 + + + + Select oscillator B2 + Vybrat oscilátor B2 + + + + Mix output of A2 to A1 + Přimíchat výstup A1 do A2 + + + + Modulate amplitude of A1 with output of A2 + Modulovat amplitudu A1 výstupem A2 + + + + Ring-modulate A1 and A2 + Kruhově modulovat A1 a A2 + + + + Modulate phase of A1 with output of A2 + Modulovat fázi A1 výstupem A2 + + + + Mix output of B2 to B1 + Přimíchat výstup B1 do B2 + + + + Modulate amplitude of B1 with output of B2 + Modulovat amplitudu B1 výstupem B2 + + + + Ring-modulate B1 and B2 + Kruhově modulovat B1 a B2 + + + + Modulate phase of B1 with output of B2 + Modulovat fázi B1 výstupem B2 + + + + + + + Draw your own waveform here by dragging your mouse on this graph. + Kreslení vlastní křivky tahem myši na tomto grafu. + + + + Load waveform + Načíst vlnu + + + + Click to load a waveform from a sample file + Klepněte pro načtení vlny ze souboru samplů + + + + Phase left + Fáze vlevo + + + + Click to shift phase by -15 degrees + Klepněte pro posun fáze o -15 stupňů + + + + Phase right + Fáze vpravo + + + + Click to shift phase by +15 degrees + Klepněte pro posun fáze o +15 stupňů + + + + Normalize + Normalizovat + + + + Click to normalize + Klepněte pro normalizaci + + + + Invert + Převrátit + + + + Click to invert + Klepněte pro převrácení + + + + Smooth + Uhladit + + + + Click to smooth + Klepněte pro vyhlazení + + + + Sine wave + Sinusová vlna + + + + Click for sine wave + Klepněte pro sinusovou vlnu + + + + + Triangle wave + Trojúhelníková vlna + + + + Click for triangle wave + Klepněte pro trojúhelníkovou vlnu + + + + Click for saw wave + Klepněte pro pilovitou vlnu + + + + Square wave + Pravoúhlá vlna + + + + Click for square wave + Klepněte pro pravoúhlou vlnu ZynAddSubFxInstrument + Portamento - + Portamento + Filter Frequency - + Frekvence filtru + Filter Resonance - + Rezonance filtru + Bandwidth Šířka pásma + FM Gain - + Zesílení FM + Resonance Center Frequency - + Střední frekvence rezonance + Resonance Bandwidth - Pásmo rezonance + Šířka pásma rezonance + Forward MIDI Control Change Events - + Odesílat události MIDI Control Change ZynAddSubFxView - Show GUI - Ukázar grafické rozhraní - - - Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. - - - + Portamento: - + Portamento: + PORT - + PORT + Filter Frequency: Frekvence filtru: + FREQ FREKV + Filter Resonance: Rezonance filtru: + RES - + REZ + Bandwidth: Šířka pásma: + BW - + ŠP + FM Gain: - + Zesílení FM: + FM GAIN - + ZISK FM + Resonance center frequency: - + Střední frekvence rezonance: + RES CF - + SF REZ + Resonance bandwidth: Šířka pásma rezonance: + RES BW - + ŠP REZ + Forward MIDI Control Changes - + Odesílat MIDI Control Change + + + + Show GUI + Ukázar grafické rozhraní + + + + Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. + Klepněte sem pro zobrazení nebo skrytí grafického uživatelského rozhraní (GUI) ZynAddSubFX. audioFileProcessor + Amplify Zesílení + Start of sample Začátek samplu + End of sample Konec samplu + + Loopback point + Začátek smyčky + + + Reverse sample Přehrávat pozpátku - Stutter - - - - Loopback point - - - + Loop mode Režim smyčky + + Stutter + Pokračování v přehrávání samplu při změně noty + + + Interpolation mode Režim interpolace + None Žádný + Linear Lineární + Sinc Sinusový + Sample not found: %1 - + Vzorek nenalezen: %1 bitInvader + Samplelength Délka samplu @@ -7664,206 +9903,254 @@ Přesvědčte se prosím, že máte právo ke čtení tohoto souboru a příslu bitInvaderView + Sample Length Délka samplu - Sine wave - Sinusová vlna - - - Triangle wave - Trojúhelníková vlna - - - Saw wave - Pilovitá vlna - - - Square wave - Pravoúhlá (square) vlna - - - White noise wave - Bílý šum - - - User defined wave - Vlna definovaná uživatelem - - - Smooth - Uhladit - - - Click here to smooth waveform. - Pro uhlazení vlny klikněte zde. - - - Interpolation - Interpolovat - - - Normalize - Normalizovat - - + Draw your own waveform here by dragging your mouse on this graph. Kreslení vlastní křivky tahem myši na tomto grafu. + + Sine wave + Sinusová vlna + + + Click for a sine-wave. - Klikněte sem pro sinusovou vlnu. + Klepněte sem pro sinusovou vlnu. + + Triangle wave + Trojúhelníková vlna + + + Click here for a triangle-wave. - Klikněte sem pro trojúhelníkovou vlnu. + Klepněte sem pro trojúhelníkovou vlnu. + + Saw wave + Pilovitá vlna + + + Click here for a saw-wave. - Klikněte sem pro pilovitou vlnu. + Klepněte sem pro pilovitou vlnu. + + Square wave + Pravoúhlá vlna + + + Click here for a square-wave. - Klikněte sem pro pravoúhlou vlnu. + Klepněte sem pro pravoúhlou vlnu. + + White noise wave + Bílý šum + + + Click here for white-noise. - Klikněte sem pro bílý šum. + Klepněte sem pro bílý šum. + + User defined wave + Vlna definovaná uživatelem + + + Click here for a user-defined shape. - Klikněte sem pro uživatelem definovaný tvar. + Klepněte sem pro uživatelem definovaný tvar. + + + + Smooth + Vyhladit + + + + Click here to smooth waveform. + Klepněte sem pro vyhlazení vlny. + + + + Interpolation + Interpolovat + + + + Normalize + Normalizovat dynProcControlDialog + INPUT VSTUP + Input gain: - Zisk vstupu: + Zesílení vstupu: + OUTPUT VÝSTUP + Output gain: - Zisk výstupu: + Zesílení výstupu: + ATTACK - + NÁBĚH + Peak attack time: - + Délka náběhu špičky: + RELEASE - + DOZNĚNÍ + Peak release time: - + Délka doznění špičky: + Reset waveform - Obnovit vlnu + Obnovení vlny + Click here to reset the wavegraph back to default - + Klepněte sem pro obnovení zobrazení křivky zpět do výchozího stavu + Smooth waveform - Vyhlazená vlna + Vyhlazení vlny + Click here to apply smoothing to wavegraph - Klikněte zde pro použití vyhlazení vlny grafu + Klepněte sem pro vyhlazení křivky + Increase wavegraph amplitude by 1dB - + Zvýšení amplitudy křivky o 1 dB + Click here to increase wavegraph amplitude by 1dB - Zde klikněte pro zvýšení amplitudy vlny o 1dB + Klepněte sem pro zvýšení amplitudy křivky o 1 dB + Decrease wavegraph amplitude by 1dB - + Snížení amplitudy křivky o 1 dB + Click here to decrease wavegraph amplitude by 1dB - Zde klikněte pro snížení amplitudy vlny o 1dB + Klepněte sem pro snížení amplitudy křivky o 1 dB + Stereomode Maximum - + Režim maximálního sterea + Process based on the maximum of both stereo channels - + Zpracování vycházející z maxima obou stereo kanálů + Stereomode Average - + Režim průměru sterea + Process based on the average of both stereo channels - + Zpracování vycházející z průměru obou stereo kanálů + Stereomode Unlinked - + Režim nepropojeného sterea + Process each stereo channel independently - + Zpracování každého stereo kanálu zvlášť dynProcControls + Input gain - Zisk vstupu + Zesílení vstupu + Output gain - Zisk výstupu + Zesílení výstupu + Attack time - + Doba náběhu + Release time - + Délka doznění + Stereo mode - + Režim sterea fxLineLcdSpinBox + Assign to: - + Přiřadit k: + New FX Channel - Nový FX kanál + Nový efektový kanál graphModel + Graph Graf @@ -7871,93 +10158,115 @@ Přesvědčte se prosím, že máte právo ke čtení tohoto souboru a příslu kickerInstrument + Start frequency Počáteční frekvence + End frequency Konečná frekvence - Gain - Zisk - - + Length Délka + Distortion Start Začátek zkreslení + Distortion End Konec zkreslení - Envelope Slope - + + Gain + Zisk + + Envelope Slope + Sklon frekvence + + + Noise Šum + Click Klik + Frequency Slope - + Sklon frekvence + Start from note - + Začít od noty + End to note - + Skončit na notě kickerInstrumentView + Start frequency: Počáteční frekvence: + End frequency: Konečná frekvence: + + Frequency Slope: + Sklon frekvence: + + + Gain: Zisk: - Frequency Slope: - - - + Envelope Length: Délka obálky: + Envelope Slope: - + Sklon obálky: + Click: Klik: + Noise: Šum: + Distortion Start: Začátek zkreslení: + Distortion End: Konec zkreslení: @@ -7965,26 +10274,37 @@ Přesvědčte se prosím, že máte právo ke čtení tohoto souboru a příslu ladspaBrowserView + + Available Effects Dostupné efekty + + Unavailable Effects Nedostupné efekty + + Instruments Nástroje + + Analysis Tools Analyzační nástroje + + Don't know Neznámé + 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. @@ -8001,7 +10321,7 @@ Double clicking any of the plugins will bring up information on the ports.Toto dialogové okno zobrazuje informace o všech LADSPA pluginech, které bylo LMMS schopno nalézt. Zásuvné moduly jsou rozděleny do pěti kategorií podle portů a názvů. -K dispozici jsou ty efekty, které mohou být použity v LMMS. Aby v LMMS bylo možné užít efektu, musí se o efekt skutečně jednat, to znamená, že musí mít oba vstupní a výstupní kanály. LMMS identifikuje vstupní kanál jako audio podle 'in' v názvu. Výstupní kanály jsou identifikovány pole označení písmeny 'out'. Kromě toho efekt musí mít stejný počet vstupů a výstupů a být real time kompatibilní. +K dispozici jsou ty efekty, které mohou být použity v LMMS. Aby v LMMS bylo možné užít efektu, musí se o efekt skutečně jednat, to znamená, že musí mít oba vstupní a výstupní kanály. LMMS identifikuje vstupní kanál jako audio podle "n" v názvu. Výstupní kanály jsou identifikovány pole označení písmeny "out". Kromě toho efekt musí mít stejný počet vstupů a výstupů a být real time kompatibilní. Nedostupné efekty jsou ty, které byly identifikovány jako efekty, ale buď nemají stejný počet vstupních a výstupních kanálů nebo nejsou real time kompatibilní. @@ -8011,9 +10331,10 @@ Analyzační nástroje jsou pluginy u kterých byly identifikovány pouze vstupn Neznámé jsou pluginy, pro které nebyly identifikovány žádné vstupní nebo výstupní kanály. -Dvojitým kliknutím na kterýkoli z modulů se zobrazí informace o portech. +Poklepáním na kterýkoliv modul se zobrazí informace o portech. + Type: Typ: @@ -8021,10 +10342,12 @@ Dvojitým kliknutím na kterýkoli z modulů se zobrazí informace o portech. ladspaDescription + Plugins Pluginy + Description Popis @@ -8032,66 +10355,83 @@ Dvojitým kliknutím na kterýkoli z modulů se zobrazí informace o portech. ladspaPortDialog + Ports Porty + Name Název + Rate - Rychlost + Druh + Direction Směr + Type Typ + Min < Default < Max Min < Výchozí < Max + Logarithmic Logaritmický + SR Dependent - + SR závislý + Audio - Audio + Zvuk + Control Ovládání + Input Vstup + Output Výstup + Toggled Zapnuto + Integer - + Celočíselný + Float - + S plovoucí čárkou + + Yes Ano @@ -8099,438 +10439,546 @@ Dvojitým kliknutím na kterýkoli z modulů se zobrazí informace o portech. lb302Synth + VCF Cutoff Frequency VCF frekvence vypnutí + VCF Resonance VCF rezonance + VCF Envelope Mod - + VCF modulace obálky + VCF Envelope Decay - + VCF pokles obálky + Distortion Zkreslení + Waveform Vlna + Slide Decay - + Pokles sklouznutí + Slide - Klouzání + Sklouznutí + Accent Důraz + Dead - + Dead + 24dB/oct Filter - + Filtr 24dB/okt lb302SynthView + Cutoff Freq: - Frek. vypnutí: + Frekvence odstřihnutí: + Resonance: Rezonance: + Env Mod: - + Modulace obálky: + Decay: - Doznívání: + Pokles: + 303-es-que, 24dB/octave, 3 pole filter - + 3pólový filtr 303-es-que, 24dB/okt + Slide Decay: - + Pokles sklouznutí: + DIST: - + Zkreslení: + Saw wave Pilovitá vlna + Click here for a saw-wave. - Klikněte zde pro pilovitou vlnu. + Klepněte sem pro pilovitou vlnu. + Triangle wave Trojúhelníková vlna + Click here for a triangle-wave. - Klikněte zde pro trojúhelníkovou vlnu. + Klepněte sem pro trojúhelníkovou vlnu. + Square wave - Pravoúhlá (square) vlna + Pravoúhlá vlna + Click here for a square-wave. - Klikněte zde pro pravoúhlou vlnu. + Klepněte sem pro pravoúhlou vlnu. + Rounded square wave Oblá pravoúhlá vlna + Click here for a square-wave with a rounded end. - Klikněte sem pro pravoúhlou vlnu s oblým zakončením. + Klepněte sem pro pravoúhlou vlnu s oblým zakončením. + Moog wave - + Vlna typu Moog + Click here for a moog-like wave. - + Klepněte sem pro vlnu typu Moog. + Sine wave Sinusová vlna + Click for a sine-wave. - Klikněte sem pro sinusovou vlnu. + Klepněte sem pro sinusovou vlnu. + + White noise wave Bílý šum + Click here for an exponential wave. - Klikněte zde pro exponenciální vlnu. + Klepněte sem pro exponenciální vlnu. + Click here for white-noise. - Klikněte sem pro bílý šum. + Klepněte sem pro bílý šum. + Bandlimited saw wave Pásmově omezená pilovitá vlna + Click here for bandlimited saw wave. - Klikněte sem pro pásmově omezenou pilovitou vlnu. + Klepněte sem pro pásmově omezenou pilovitou vlnu. + Bandlimited square wave - + Pásmově zúžená pravoúhlá vlna + Click here for bandlimited square wave. - + Klepněte sem pro pásmově zúženou pravoúhlou vlnu. + Bandlimited triangle wave - + Pásmově zúžená trojúhelníková vlna + Click here for bandlimited triangle wave. - + Klepněte sem pro pásmově zúženou trojúhelníkovou vlnu. + Bandlimited moog saw wave - + Pásmově zúžená pilovitá vlna typu Moog + Click here for bandlimited moog saw wave. - + Klepněte sem pro úzkopásmovou pilovitou vlnu typu Moog. malletsInstrument + Hardness Tvrdost + Position Pozice + Vibrato Gain Zisk vibráta + Vibrato Freq Frekvence vibráta + Stick Mix - + Mix paliček + Modulator Modulátor + Crossfade Prolínání (crossfade) + LFO Speed LFO Rychlost + LFO Depth LFO Hloubka + ADSR ADSR + Pressure Tlak + Motion Pohyb + Speed Rychlost + Bowed - + Smyčcem + Spread - Rozsah + Šíře + Marimba Marimba + Vibraphone Vibrafon + Agogo Agogo + Wood1 - + Dřevo1 + Reso - Rezon + Rezo + Wood2 - + Dřevo2 + Beats - Beats + Údery + Two Fixed - + Dvě spojené + Clump - + Svazek + Tubular Bells Trubicové zvony + Uniform Bar - + Obyčejná tyč + Tuned Bar - + Laděná tyč + Glass - + Sklo + Tibetan Bowl - Tibetská mísa + Tibetská zpívající mísa malletsInstrumentView + Instrument Nástroj + Spread - Rozsah + Šíře + Spread: - Rozsah: - - - Hardness - Tvrdost - - - Hardness: - Tvrdost: - - - Position - Pozice - - - Position: - Pozice: - - - Vib Gain - Vib zisk - - - Vib Gain: - Vib zisk: - - - Vib Freq - Vib frekv - - - Vib Freq: - Vib frekv: - - - Stick Mix - - - - Stick Mix: - - - - Modulator - Modulátor - - - Modulator: - Modulátor: - - - Crossfade - Prolínání (crossfade) - - - Crossfade: - Prolínání (crossfade): - - - LFO Speed - LFO Rychlost - - - LFO Speed: - LFO Rychlost: - - - LFO Depth - LFO Hloubka - - - LFO Depth: - LFO Hloubka: - - - ADSR - ADSR - - - ADSR: - ADSR: - - - Pressure - Tlak - - - Pressure: - Tlak: - - - Speed - Rychlost - - - Speed: - Rychlost: + Šíře: + Missing files Chybějící soubory + Your Stk-installation seems to be incomplete. Please make sure the full Stk-package is installed! - + Zdá se, že instalace Stk není kompletní. Ujistěte se prosím, že je nainstalován celý balík Stk! + + + + Hardness + Tvrdost + + + + Hardness: + Tvrdost: + + + + Position + Pozice + + + + Position: + Pozice: + + + + Vib Gain + Vib zisk + + + + Vib Gain: + Vib zisk: + + + + Vib Freq + Vib frekv + + + + Vib Freq: + Vib frekv: + + + + Stick Mix + Mix paliček + + + + Stick Mix: + Mix paliček: + + + + Modulator + Modulátor + + + + Modulator: + Modulátor: + + + + Crossfade + Prolínání (crossfade) + + + + Crossfade: + Prolínání (crossfade): + + + + LFO Speed + LFO Rychlost + + + + LFO Speed: + LFO Rychlost: + + + + LFO Depth + LFO Hloubka + + + + LFO Depth: + LFO Hloubka: + + + + ADSR + ADSR + + + + ADSR: + ADSR: + + + + Pressure + Tlak + + + + Pressure: + Tlak: + + + + Speed + Rychlost + + + + Speed: + Rychlost: manageVSTEffectView + - VST parameter control - + - řízení parametrů VST + VST Sync VST synch + Click here if you want to synchronize all parameters with VST plugin. - Klikněte sem, chcete-li synchronizovat všechny parametry s VST pluginem. + Klepněte sem, chcete-li synchronizovat všechny parametry s VST pluginem. + + Automated - + Automaticky + Click here if you want to display automated parameters only. - Klikněte sem, pokud chcete pouze zobrazit automatizační parametry. + Klepněte sem, pokud chcete pouze zobrazit parametry automatizace. + Close Zavřít + Close VST effect knob-controller window. Zavřít okno otočných ovladačů VST efektu. @@ -8538,30 +10986,39 @@ Dvojitým kliknutím na kterýkoli z modulů se zobrazí informace o portech. manageVestigeInstrumentView + + - VST plugin control - + - ovládání VST pluginu + VST Sync VST synch + Click here if you want to synchronize all parameters with VST plugin. - Klikněte sem, chcete-li synchronizovat všechny parametry s VST pluginem. + Klepněte sem, chcete-li synchronizovat všechny parametry s VST pluginem. + + Automated - + Automaticky + Click here if you want to display automated parameters only. - Klikněte sem, pokud chcete pouze zobrazit automatizační parametry. + Klepněte sem, pokud chcete pouze zobrazit parametry automatizace. + Close Zavřít + Close VST plugin knob-controller window. Zavřít okno otočných ovladačů VST pluginu. @@ -8569,118 +11026,147 @@ Dvojitým kliknutím na kterýkoli z modulů se zobrazí informace o portech. opl2instrument + Patch Patch + Op 1 Attack - + Op 1 náběh + Op 1 Decay - + Op 1 útlum + Op 1 Sustain - + Op 1 vydržení + Op 1 Release - + Op 1 uvolnění + Op 1 Level - + Op 1 úroveň + Op 1 Level Scaling - + Op 1 škálování úrovně + Op 1 Frequency Multiple - + Op 1 násobení frekvence + Op 1 Feedback - + Op 1 zpětná vazba + Op 1 Key Scaling Rate - + Op 1 rychlost podle výšky klávesy + Op 1 Percussive Envelope - + Op 1 perkusivní obálka + Op 1 Tremolo - + Op 1 tremolo + Op 1 Vibrato - + Op 1 vibrato + Op 1 Waveform - + Op 1 vlna + Op 2 Attack - + Op 2 náběh + Op 2 Decay - + Op 2 útlum + Op 2 Sustain - + Op 2 vydržení + Op 2 Release - + Op 2 uvolnění + Op 2 Level - + Op 2 úroveň + Op 2 Level Scaling - + Op 2 škálování úrovně + Op 2 Frequency Multiple - + Op 2 násobení frekvence + Op 2 Key Scaling Rate - + Op 2 rychlost podle výšky klávesy + Op 2 Percussive Envelope - + Op 2 perkusivní obálka + Op 2 Tremolo - + Op 2 tremolo + Op 2 Vibrato - + Op 2 vibrato + Op 2 Waveform - + Op 2 tvar vlny + FM FM + Vibrato Depth Hloubka vibráta + Tremolo Depth Hloubka tremola @@ -8688,29 +11174,39 @@ Dvojitým kliknutím na kterýkoli z modulů se zobrazí informace o portech. opl2instrumentView + + Attack - Nástup + Náběh + + Decay - Doznívání + Pokles + + Release - Uvolnění + Doznění + + Frequency multiplier - + Násobič frekvence organicInstrument + Distortion Zkreslení + Volume Hlasitost @@ -8718,351 +11214,458 @@ Dvojitým kliknutím na kterýkoli z modulů se zobrazí informace o portech. organicInstrumentView + Distortion: Zkreslení: + + The distortion knob adds distortion to the output of the instrument. + Otočný ovladač zkreslení přidá zkreslení k výstupu nástroje. + + + Volume: Hlasitost: + + The volume knob controls the volume of the output of the instrument. It is cumulative with the instrument window's volume control. + Otočný ovladač hlasitosti ovládá hlasitost výstupu nástroje. Sčítá se s ovládáním hlasitosti okna nástroje. + + + Randomise Nastavit náhodně + + The randomize button randomizes all knobs except the harmonics,main volume and distortion knobs. + Tlačítko Randomize náhodně nastaví všechny ovladače kromě ovladače harmonických, hlavní hlasitosti a zkreslení. + + + + Osc %1 waveform: Osc %1 vlna: + Osc %1 volume: Osc %1 hlasitost: + Osc %1 panning: - Panoráma Osc %1: + Osc %1 panoráma: + + Osc %1 stereo detuning + Osc %1 rozladění sterea + + + cents centů - The distortion knob adds distortion to the output of the instrument. - - - - The volume knob controls the volume of the output of the instrument. It is cumulative with the instrument window's volume control. - - - - The randomize button randomizes all knobs except the harmonics,main volume and distortion knobs. - - - - Osc %1 stereo detuning - - - + Osc %1 harmonic: - + Osc %1 harmonické: papuInstrument + Sweep time - + Trvání sweepu + Sweep direction - + Směr sweepu + Sweep RtShift amount - + Úroveň pro změnu frekvence sweepu + + Wave Pattern Duty - + Pracovní cyklus vlnového vzorce + Channel 1 volume - Kanál 1 hlasitost + Hlasitost kanálu 1 + + + Volume sweep direction - + Směr hlasitosti sweepu + + + Length of each step in sweep - + Délka každého kroku ve sweepu + Channel 2 volume - Kanál 2 hlasitost + Hlasitost kanálu 2 + Channel 3 volume - Kanál 3 hlasitost + Hlasitost kanálu 3 + Channel 4 volume - Kanál 4 hlasitost + Hlasitost kanálu 4 + + Shift Register width + Posun šířky registru + + + Right Output level - + Úroveň pravého výstupu + Left Output level - + Úroveň levého výstupu + Channel 1 to SO2 (Left) - + Kanál 1 do SO2 (pravý) + Channel 2 to SO2 (Left) - + Kanál 2 do SO2 (pravý) + Channel 3 to SO2 (Left) - + Kanál 3 do SO2 (pravý) + Channel 4 to SO2 (Left) - + Kanál 4 do SO2 (pravý) + Channel 1 to SO1 (Right) - + Kanál 1 do SO1 (pravý) + Channel 2 to SO1 (Right) - + Kanál 2 do SO1 (pravý) + Channel 3 to SO1 (Right) - + Kanál 3 do SO1 (pravý) + Channel 4 to SO1 (Right) - + Kanál 4 do SO1 (pravý) + Treble Výšky + Bass Basy - - Shift Register width - - papuInstrumentView + Sweep Time: - + Trvání sweepu: + Sweep Time - + Trvání sweepu + + The amount of increase or decrease in frequency + Množství zvýšení nebo snížení frekvence + + + Sweep RtShift amount: - + Úroveň pro změnu frekvence sweepu: + Sweep RtShift amount - + Úroveň pro změnu frekvence sweepu + + The rate at which increase or decrease in frequency occurs + Úroveň, při které dojde ke zvýšení nebo snížení frekvence + + + + Wave pattern duty: - + Pracovní cyklus vlnového vzorce: + Wave Pattern Duty - + Pracovní cyklus vlnového vzorce + + + The duty cycle is the ratio of the duration (time) that a signal is ON versus the total period of the signal. + Pracovní cyklus je poměr mezi dobou trvání (časem), kdy je signál zapnut, a celkovou délkou signálu. + + + + Square Channel 1 Volume: - + Hlasitost pulzního kanálu 1: + + Square Channel 1 Volume + Hlasitost pulzního kanálu 1 + + + + + Length of each step in sweep: - + Délka každého kroku ve sweepu: + + + Length of each step in sweep - + Délka každého kroku ve sweepu + + + + The delay between step change + Zpoždění mezi změnou kroku + + + Wave pattern duty - + Pracovní cyklus vlnového vzorce + Square Channel 2 Volume: - + Hlasitost pulzního kanálu 2: + + Square Channel 2 Volume - + Hlasitost pulzního kanálu 2 + Wave Channel Volume: - + Hlasitost vlnového kanálu: + + Wave Channel Volume - + Hlasitost vlnového kanálu + Noise Channel Volume: - + Hlasitost šumového kanálu: + + Noise Channel Volume - + Hlasitost šumového kanálu + SO1 Volume (Right): - + Hlasitost SO1 (pravý): + SO1 Volume (Right) - + Hlasitost SO1 (pravý) + SO2 Volume (Left): - + Hlasitost SO2 (levý): + SO2 Volume (Left) - + Hlasitost SO2 (levý) + Treble: Výšky: + Treble Výšky + Bass: Basy: + Bass Basy + Sweep Direction - + Směr sweepu + + + + + Volume Sweep Direction - + Směr hlasitosti sweepu + Shift Register Width - + Posun šířky registru + Channel1 to SO1 (Right) - + Kanál 1 do SO1 (pravý) + Channel2 to SO1 (Right) - + Kanál 2 do SO1 (pravý) + Channel3 to SO1 (Right) - + Kanál 3 do SO1 (pravý) + Channel4 to SO1 (Right) - + Kanál 4 do SO1 (pravý) + Channel1 to SO2 (Left) - + Kanál 1 do SO2 (levý) + Channel2 to SO2 (Left) - + Kanál 2 do SO2 (levý) + Channel3 to SO2 (Left) - + Kanál 3 do SO2 (levý) + Channel4 to SO2 (Left) - + Kanál 4 do SO2 (levý) + Wave Pattern - - - - The amount of increase or decrease in frequency - - - - The rate at which increase or decrease in frequency occurs - - - - 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 - - - - The delay between step change - + Vlnový vzorec + Draw the wave here - + Nakreslete vlnu zde patchesDialog + Qsynth: Channel Preset Qsynth: Předvolba kanálu + Bank selector Výběr banky + Bank Banka + Program selector Výběr programu + Patch Patch + Name Název + OK OK + Cancel Zrušit @@ -9070,238 +11673,302 @@ Dvojitým kliknutím na kterýkoli z modulů se zobrazí informace o portech. pluginBrowser + no description bez popisu - Incomplete monophonic imitation tb303 - Nekompletní monofonní imitace tb303 + + A native amplifier plugin + Nativní plugin zesilovače - Plugin for freely manipulating stereo output - + + Simple sampler with various settings for using samples (e.g. drums) in an instrument-track + Jednoduchý sampler s bohatým nastavením pro používání samplů (např. bicích nástrojů) v nástrojové stopě - Plugin for controlling knobs with sound peaks - + + Boost your bass the fast and simple way + Zesílení vašeho basu rychlým a snadným způsobem - Plugin for enhancing stereo separation of a stereo input file - Plugin pro zlepšení stereo separace vstupních stereo souborů + + Customizable wavetable synthesizer + Upravitelný tabulkový syntezátor + + An oversampling bitcrusher + Bitcrusher založený na převzorkování + + + + Carla Patchbay Instrument + Nástroj Carla Patchbay + + + + Carla Rack Instrument + Nástroj Carla Rack + + + + A 4-band Crossover Equalizer + 4 pásmový crossover ekvalizér + + + + A native delay plugin + Nativní plugin delay + + + + A Dual filter plugin + Plugin duální filtr + + + + plugin for processing dynamics in a flexible way + plugin pro flexibilní práci s dynamikou + + + + A native eq plugin + Nativní plugin ekvalizér + + + + A native flanger plugin + Nativní plugin flanger + + + + Player for GIG files + Přehrávač GIG souborů + + + + Filter for importing Hydrogen files into LMMS + Filtr pro import souborů Hydrogen do LMMS + + + + Versatile drum synthesizer + Univerzální syntezátor bicích nástrojů + + + List installed LADSPA plugins Seznam nainstalovaných LADSPA pluginů - GUS-compatible patch instrument - GUS kompatibilní patch instrument - - - Additive Synthesizer for organ-like sounds - Aditivní syntezátor pro zvuky podobné varhanám - - - Tuneful things to bang on - Libozvučná klepátka - - - VST-host for using VST(i)-plugins within LMMS - VST host pro užití VST(i) pluginů v LMMS - - - Vibrating string modeler - Vibrační modelátor strun - - + plugin for using arbitrary LADSPA-effects inside LMMS. plugin pro užití libovolných LADSPA efektů uvnitř LMMS. + + Incomplete monophonic imitation tb303 + Nekompletní monofonní imitace tb303 + + + + Filter for exporting MIDI-files from LMMS + Filtr pro export souborů MIDI z LMMS + + + Filter for importing MIDI-files into LMMS Filtr pro import MIDI souborů do LMMS + + Monstrous 3-oscillator synth with modulation matrix + 3oscilátorový syntezátor Monstrous s modulační matricí + + + + A multitap echo delay plugin + Plugin multi-tap delay + + + + A NES-like synthesizer + Syntetizér typu NES + + + + 2-operator FM Synth + 2 operátorová FM syntéza + + + + Additive Synthesizer for organ-like sounds + Aditivní syntezátor pro zvuky podobné varhanám + + + + Emulation of GameBoy (TM) APU + Emulace APU GameBoye (TM) + + + + GUS-compatible patch instrument + GUS kompatibilní patch instrument + + + + Plugin for controlling knobs with sound peaks + Plugin pro řízení otočných ovladačů zvukovými špičkami + + + + Reverb algorithm by Sean Costello + Algoritmus dozvuku od Seana Costello + + + + Player for SoundFont files + Přehrávač SoundFont souborů + + + + LMMS port of sfxr + LMMS port sfxr + + + Emulation of the MOS6581 and MOS8580 SID. This chip was used in the Commodore 64 computer. - - - - Player for SoundFont files - - - - Emulation of GameBoy (TM) APU - - - - Customizable wavetable synthesizer - - - - Embedded ZynAddSubFX - - - - 2-operator FM Synth - - - - Filter for importing Hydrogen files into LMMS - - - - LMMS port of sfxr - - - - Monstrous 3-oscillator synth with modulation matrix - - - - Three powerful oscillators you can modulate in several ways - - - - A native amplifier plugin - - - - Carla Rack Instrument - - - - 4-oscillator modulatable wavetable synth - - - - plugin for waveshaping - - - - Boost your bass the fast and simple way - - - - Versatile drum synthesizer - - - - Simple sampler with various settings for using samples (e.g. drums) in an instrument-track - - - - plugin for processing dynamics in a flexible way - - - - Carla Patchbay Instrument - - - - plugin for using arbitrary VST effects inside LMMS. - + Emulace MOS6581 a MOS8580 SID. +Tento čip byl používán v počítačích Commodore 64. + Graphical spectrum analyzer plugin - + Plugin pro grafickou analýzu spektra - A NES-like synthesizer - + + Plugin for enhancing stereo separation of a stereo input file + Plugin pro zlepšení stereo separace vstupních stereo souborů - A native delay plugin - + + Plugin for freely manipulating stereo output + Plugin pro volné úpravy stereo výstupu - Player for GIG files - + + Tuneful things to bang on + Melodické bicí nástroje - A multitap echo delay plugin - + + Three powerful oscillators you can modulate in several ways + 3 silné oscilátory, které můžete různými způsoby modulovat - A native flanger plugin - + + VST-host for using VST(i)-plugins within LMMS + VST host pro užití VST(i) pluginů v LMMS - An oversampling bitcrusher - + + Vibrating string modeler + Vibrační modelátor strun - A native eq plugin - + + plugin for using arbitrary VST effects inside LMMS. + Plugin pro použití libovolného VST efektu v LMMS. - A 4-band Crossover Equalizer - + + 4-oscillator modulatable wavetable synth + 4oscilátorový modulovatelný tabulkový syntezátor - A Dual filter plugin - + + plugin for waveshaping + plugin pro tvarování vln - Filter for exporting MIDI-files from LMMS - + + Embedded ZynAddSubFX + Vestavěný ZynAddSubFX sf2Instrument + Bank Banka + Patch Patch + Gain Zisk + Reverb Dozvuk + Reverb Roomsize - + Velikost dozvukového prostoru + Reverb Damping - + Útlum dozvuku + Reverb Width - + Délka dozvuku + Reverb Level - + Úroveň dozvuku + Chorus Chorus + Chorus Lines - + Počet linií chorusu + Chorus Level - + Úroveň chorusu + Chorus Speed - + Rychlost chorusu + Chorus Depth Hloubka chorusu + A soundfont %1 could not be loaded. Soundfont %1 nelze načíst. @@ -9309,254 +11976,319 @@ This chip was used in the Commodore 64 computer. sf2InstrumentView + Open other SoundFont file Otevřít jiný SoundFont soubor + Click here to open another SF2 file - + Klepněte sem pro otevření jiného SF2 souboru + Choose the patch Vybrat patch + Gain - Zisk + Zesílení + Apply reverb (if supported) Použít dozvuk (je-li podporován) + This button enables the reverb effect. This is useful for cool effects, but only works on files that support it. - + Tímto tlačítkem zapnete efekt dozvuk (reverb). Ten lze použít pro výborné efekty, ale funguje pouze se soubory, které jej podporují. + Reverb Roomsize: - + Velikost dozvukového prostoru: + Reverb Damping: - + Útlum dozvuku: + Reverb Width: - + Délka dozvuku: + Reverb Level: - + Úroveň dozvuku: + Apply chorus (if supported) - + Použít chorus (je-li podporován) + This button enables the chorus effect. This is useful for cool echo effects, but only works on files that support it. - + Tímto tlačítkem zapnete efekt chorus. Ten lze použít pro výborné echo efekty, ale funguje pouze se soubory, které jej podporují. + Chorus Lines: - + Počet linií chorusu: + Chorus Level: - + Úroveň chorusu: + Chorus Speed: - + Rychlost chorusu: + Chorus Depth: - + Hloubka chorusu: + Open SoundFont file Otevřít SoundFont soubor + SoundFont2 Files (*.sf2) - + Soubory SoundFont2 (*.sf2) sfxrInstrument + Wave Form - + Vlna sidInstrument + Cutoff - + Oříznutí + Resonance Rezonance + Filter type Typ filtru + Voice 3 off - + Vypnout hlas 3 + Volume Hlasitost + Chip model - + Model čipu sidInstrumentView + Volume: Hlasitost: + Resonance: Rezonance: + + Cutoff frequency: - Frekvence seříznutí: + Frekvence oříznutí: + High-Pass filter - + Filtr typu horní propust + Band-Pass filter - + Filtr typu pásmová propust + Low-Pass filter - + Filtr typu dolní propust + Voice3 Off - + Vypnout hlas 3 + MOS6581 SID - + MOS6581 SID + MOS8580 SID - + MOS8580 SID + + Attack: - + Náběh: + Attack rate determines how rapidly the output of Voice %1 rises from zero to peak amplitude. - + Rychlost náběhu určuje, jak rychle výstup hlasu %1 stoupne z nuly na špičkovou amplitudu. + + Decay: - Doznívání: + Pokles: + Decay rate determines how rapidly the output falls from the peak amplitude to the selected Sustain level. - + Rychlost útlumu (decay) určuje, jak rychle poklesne výstup ze špičky na zvolenou úroveň vydržení (sustain). + Sustain: - Sustain: + Držení: + Output of Voice %1 will remain at the selected Sustain amplitude as long as the note is held. - + Výstup hlasu %1 zůstane na zvolené úrovni Vydržení po celou dobu, kdy bude nota držena. + + Release: - Release: + Doznění: + The output of of Voice %1 will fall from Sustain amplitude to zero amplitude at the selected Release rate. - + Výstup hlasu %1 poklesne z úrovně vydržení (sustain) na nulovou amplitudu zvolenou rychlostí uvolnění (release). + + Pulse Width: Délka pulzu: + 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. - + Rozlišení šířky pulsu umožňuje plynulé vyhlazení šířky, aby nebylo rozeznatelné krokování. Pulzní vlna na oscilátoru %1 musí být zvolena tak, aby měla slyšitelný efekt. + Coarse: - + Ladění: + The Coarse detuning allows to detune Voice %1 one octave up or down. - + Hrubé rozladění umožní rozladit hlas %1 až o jednu oktávu nahoru nebo dolů. + Pulse Wave Pulzní vlna + Triangle Wave Trojúhelníková vlna + SawTooth - + Pilovitá vlna + Noise Šum + Sync Synch + Sync synchronizes the fundamental frequency of Oscillator %1 with the fundamental frequency of Oscillator %2 producing "Hard Sync" effects. - + Synchronizace synchronizuje základní frekvenci oscilátoru %1 se základní frekvencí oscilátoru %2 pomocí efektu pevné (Hard Sync) synchronizace. + Ring-Mod - + Kruhová modulace + Ring-mod replaces the Triangle Waveform output of Oscillator %1 with a "Ring Modulated" combination of Oscillators %1 and %2. - + Kruhová modulace nahradí výstup trojúhelníkové vlny na oscilátoru %1 "kruhově modulovanou" kombinací oscilátorů %1 a %2. + Filtered - + Filtrování + 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. - + Pokud je zapnuto filtrování, hlas %1 bude zpracován filtrem. Pokud je filtrování vypnuto, hlas %1 se objeví přímo na výstupu a filtr na něj nebude mít žádný efekt. + Test - + Test + Test, when set, resets and locks Oscillator %1 at zero until Test is turned off. - + Test, když je nastaven, resetuje a zablokuje oscilátor %1 na nule, dokud se test nevypne. stereoEnhancerControlDialog + WIDE - + ŠÍŘKA + Width: Šířka: @@ -9564,6 +12296,7 @@ This chip was used in the Commodore 64 computer. stereoEnhancerControls + Width Šířka @@ -9571,48 +12304,58 @@ This chip was used in the Commodore 64 computer. stereoMatrixControlDialog + Left to Left Vol: - + Levý do levého – hlasitost: + Left to Right Vol: - + Levý do pravého – hlasitost: + Right to Left Vol: - + Pravý do levého – hlasitost: + Right to Right Vol: - + Pravý do pravého – hlasitost: stereoMatrixControls + Left to Left - + Levý do levého + Left to Right - + Levý do pravého + Right to Left - + Pravý do levého + Right to Right - + Pravý do pravého vestigeInstrument + Loading plugin Načítám plugin + Please wait while loading VST-plugin... Počkejte prosím, než se načte VST plugin... @@ -9620,133 +12363,165 @@ This chip was used in the Commodore 64 computer. vibed + String %1 volume Hlasitost struny %1 + String %1 stiffness Tvrdost struny %1 + Pick %1 position - + Místo drnknutí %1 + Pickup %1 position - + Umístění snímače %1 + Pan %1 Pan %1 + Detune %1 - + Rozladění %1 + Fuzziness %1 Roztřepení %1 + Length %1 - + Délka %1 + Impulse %1 - + Impulz %1 + Octave %1 - + Oktáva %1 vibedView + Volume: Hlasitost: + The 'V' knob sets the volume of the selected string. - Otočný ovladač 'V' nastavuje hlasitost vybrané struny. + Otočný ovladač "V" nastavuje hlasitost vybrané struny. + String stiffness: Tvrdost struny: + 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. - Otočný ovladač 'S' nastavuje tvrdost vybrané struny. Tvrdost struny ovlivňuje délku doznívání struny. Čím nižší hodnota, tím déle bude struna znít. + Otočný ovladač "S" nastavuje tvrdost vybrané struny. Tvrdost struny ovlivňuje délku doznívání struny. Čím nižší hodnota, tím déle bude struna znít. + Pick position: - Pozice: + Místo drnknutí: + 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. - Otočný ovladač 'P' nastavuje pozici, ze které bude se na vybrané struně drnkne. Nižší nastavení znamená drnknutí blíže ke kobylce. + Otočný ovladač "P" nastavuje místo, ve kterém se na vybrané struně drnkne. Nižší nastavení znamená drnknutí blíže ke kobylce. + Pickup position: - Pozice: + Pozice snímače: + 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. - Otočný ovladač 'PU' nastavuje pozici snímače pro vybranou strunu. Nižší nastavení znamená snímač blíže u kobylky. + Otočný ovladač "PU" nastavuje umístění snímače pro vybranou strunu. Nižší nastavení znamená snímač blíže u kobylky. + Pan: - Pan: + Panoráma: + The Pan knob determines the location of the selected string in the stereo field. - Otočný ovladač 'Pan' určuje pozici vybrané struny ve stereo prostoru. + Otočný ovladač "Pan" určuje pozici vybrané struny ve stereo prostoru. + Detune: Rozladění: + 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. - Otočný ovladač 'Detune' mění ladění vybrané struny. Hodnoty nižší než nula způsobí plochý zvuk, hodnoty vyšší než nula způsobí ostřejší zvuk. + Otočný ovladač "Detune" mění ladění vybrané struny. Hodnoty nižší než nula způsobí plochý zvuk, hodnoty vyšší než nula způsobí ostřejší zvuk. + Fuzziness: Roztřepení: + 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'. - Otočný ovladač 'Slap' přidává ke zvuku vybrané struny jemné roztřepení, které je nejvíce patrné při náběhu tónu, ačkoliv lze také použít pro vytvoření více 'kovového' zvuku struny. + Otočný ovladač "Slap" přidává ke zvuku vybrané struny jemné roztřepení, které je nejvíce patrné při náběhu tónu, ačkoliv lze také použít pro vytvoření více "kovového" zvuku struny. + Length: Délka: + 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. - Otočný ovladač 'Lenght' nastavuje délku vybrané struny. Delší struny budou znít déle a jasněji, nicméně však spotřebují více CPU cyklů. + Otočný ovladač "Lenght" nastavuje délku vybrané struny. Delší struny budou znít déle a jasněji, nicméně však spotřebují více CPU cyklů. + Impulse or initial state Impulz nebo výchozí stav + 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. - Přepínač 'IMP' určuje, zda vlna v grafu bude považována za impulz přenášený na strunu drnknutím nebo za počáteční stav struny. + Přepínač "IMP" určuje, zda vlna v grafu bude považována za impulz přenášený na strunu drnknutím nebo za počáteční stav struny. + Octave Oktáva + 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. - Volič 'Octave' se používá k výběru harmonického tónu, na kterém bude struna znít. Například '-2' znamená, že struna bude znít dvě oktávy pod základním tónem, 'F' znamená, že zní základní tón, a '6' znamená, že struna bude znít šest oktáv nad základním tónem. + Volič "Octave" se používá k výběru harmonického tónu, na kterém bude struna znít. Například "-2" znamená, že struna bude znít dvě oktávy pod základním tónem, "F" znamená, že zní základní tón a "6" znamená, že struna bude znít šest oktáv nad základním tónem. + Impulse Editor Editor impulzu + 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. @@ -9760,9 +12535,10 @@ Vlna může být také nakreslena v grafu. Tlačítko "S" vyhladí vlnu. -Tlačítko 'N' normalizuje vlnu. +Tlačítko "N" normalizuje vlnu. + 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. @@ -9774,201 +12550,246 @@ The 'V' knob controls the volume. The 'S' knob controls the string's stiffness. 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. - Vibed simuluje až devět nezávisle vibrujících strun. Volič 'String' vám umožní vybrat, kterou strunu budete upravovat. Pomocí voliče 'Imp' vyberete, jestli graf představuje impulz nebo výchozí stav struny. Voličem 'Octave' vyberete, na kterém harmonickém tónu má struna vibrovat. + Vibed simuluje až devět nezávisle vibrujících strun. Volič "String" vám umožní vybrat, kterou strunu budete upravovat. Pomocí voliče "Imp" vyberete, jestli graf představuje impulz nebo výchozí stav struny. Voličem "Octave" vyberete, na kterém harmonickém tónu má struna vibrovat. Graf vám umožňuje řízení výchozího stavu nebo impulzu použitého pro nastavení pohybu struny. -Otočný ovladač 'V' řídí hlasitost. Ovladač 'S' nastavuje tvrdost struny. Ovladač 'P' určuje pozici drnknutí. Ovladač 'PU' nastavuje pozici snímače. +Otočný ovladač "V" řídí hlasitost. Ovladač "S" nastavuje tvrdost struny. Ovladač "P" určuje pozici drnknutí. Ovladač "PU" nastavuje pozici snímače. -'Pan' a 'Detune' snad není třeba vysvětlovat. Ovladač 'Slap' přidá ke zvuku struny jemné rozostření. +"Pan" a "Detune" snad není třeba vysvětlovat. Ovladač "Slap" přidá ke zvuku struny jemné rozostření. -Ovladač 'Lenght' určuje délku struny. +Ovladač "Lenght" určuje délku struny. LED v pravém dolním rohu editoru vlny určuje, jestli bude struna v aktuálním nástroji aktivní. + Enable waveform Zapnout vlnu + Click here to enable/disable waveform. - Klikněte sem pro zapnutí/vypnutí vlny. + Klepněte sem pro zapnutí/vypnutí vlny. + String Struna + 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. Volič strun se užívá k výběru struny, které bude upravována. Nástroj Vibed může obsahovat maximálně devět nezávisle vibrujících strun. LED v pravém dolním rohu editoru tvaru vlny indikuje, zda je vybraná struna aktivní. + Sine wave Sinusová vlna - Triangle wave - Trojúhelníková vlna - - - Saw wave - Pilovitá vlna - - - Square wave - Pravoúhlá (square) vlna - - - White noise wave - Bílý šum - - - User defined wave - Vlna definovaná uživatelem - - - Smooth - Vyhladit - - - Click here to smooth waveform. - Klikněte sem pro vyhlazení vlny. - - - Normalize - Normalizovat - - - Click here to normalize waveform. - Klikněte sem pro normalizaci vlny. - - + Use a sine-wave for current oscillator. Použít sinusovou vlnu pro aktuální oscilátor. + + Triangle wave + Trojúhelníková vlna + + + Use a triangle-wave for current oscillator. Použít trojúhelníkovou vlnu pro aktuální oscilátor. + + Saw wave + Pilovitá vlna + + + Use a saw-wave for current oscillator. - Klikněte sem pro pilovitou vlnu. + Použít pilovitou vlnu pro aktuální oscilátor. + + Square wave + Pravoúhlá vlna + + + Use a square-wave for current oscillator. - Klikněte sem pro pilovitou vlnu. + Klepněte sem pro pravoúhlou vlnu. + + White noise wave + Bílý šum + + + Use white-noise for current oscillator. Použít bílý šum pro aktuální oscilátor. + + User defined wave + Vlna definovaná uživatelem + + + Use a user-defined waveform for current oscillator. Použít vlastní vlnu pro aktuální oscilátor. + + + Smooth + Vyhladit + + + + Click here to smooth waveform. + Klepněte sem pro vyhlazení vlny. + + + + Normalize + Normalizovat + + + + Click here to normalize waveform. + Klepněte sem pro normalizaci vlny. + voiceObject + Voice %1 pulse width - + Hlas %1 šířka pulzu + Voice %1 attack - + Hlas %1 náběh + Voice %1 decay - + Hlas %1 pokles + Voice %1 sustain - + Hlas %1 držení + Voice %1 release - + Hlas %1 doznění + Voice %1 coarse detuning - + Hlas %1 hrubé ladění + Voice %1 wave shape - + Hlas %1 tvar vlny + Voice %1 sync - + Hlas %1 synchronizace + Voice %1 ring modulate - + Hlas %1 kruhová modulace + Voice %1 filtered - + Hlas %1 filtrování + Voice %1 test - + Hlas %1 test waveShaperControlDialog + INPUT VSTUP + Input gain: - Zisk vstupu: + Zesílení vstupu: + OUTPUT VÝSTUP + Output gain: - Zisk výstupu: + Zesílení výstupu: + Reset waveform - Obnovit vlnu + Obnovení vlny + Click here to reset the wavegraph back to default - + Klepněte sem pro obnovení zobrazení křivky zpět do výchozího stavu + Smooth waveform - Vyhlazená vlna + Vyhlazení vlny + Click here to apply smoothing to wavegraph - Klikněte zde pro použití vyhlazení vlny grafu + Klepněte sem pro vyhlazení křivky + Increase graph amplitude by 1dB Zvýši amplitudu grafu o 1dB + Click here to increase wavegraph amplitude by 1dB - Zde klikněte pro zvýšení amplitudy vlny o 1dB + Klepněte sem pro zvýšení amplitudy křivky o 1 dB + Decrease graph amplitude by 1dB Snížit amplitudu grafu o 1dB + Click here to decrease wavegraph amplitude by 1dB - Zde klikněte pro snížení amplitudy vlny o 1dB + Klepněte sem pro snížení amplitudy křivky o 1 dB + Clip input - Vstup klipu + Ořezat vstup + Clip input signal to 0dB Vstupní úroveň klipu 0dB @@ -9976,12 +12797,14 @@ LED v pravém dolním rohu editoru vlny určuje, jestli bude struna v aktuální waveShaperControls + Input gain - Zisk vstupu + Zesílení vstupu + Output gain - Zisk výstupu + Zesílení výstupu \ No newline at end of file diff --git a/data/locale/en.ts b/data/locale/en.ts index cb596387a..5a75e2e88 100644 --- a/data/locale/en.ts +++ b/data/locale/en.ts @@ -184,7 +184,6 @@ If you're interested in translating LMMS in another language or want to imp - Enable loop @@ -193,6 +192,11 @@ If you're interested in translating LMMS in another language or want to imp This button enables forwards-looping. The sample loops between the end point and the loop point. + + + Enable ping-pong loop + + This button enables ping-pong-looping. The sample loops backwards and forwards between the end point and the loop point. @@ -252,7 +256,7 @@ If you're interested in translating LMMS in another language or want to imp AudioFileProcessorWaveView - + Sample length: @@ -424,17 +428,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 +446,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. @@ -1547,27 +1551,27 @@ If you're interested in translating LMMS in another language or want to imp Editor - + Transport controls - + Play (Space) - + Stop (Space) - + Record - + Record while playing @@ -4098,7 +4102,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri - + Default preset @@ -4592,12 +4596,12 @@ Double click to pick a file. - + 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! @@ -6759,12 +6763,12 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator - + 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. @@ -6971,13 +6975,13 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator - + Please open a pattern by double-clicking on it! - - + + Please enter a new value between %1 and %2: @@ -6985,174 +6989,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) - + 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. - + 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 @@ -7613,32 +7617,32 @@ Reason: "%2" SampleTCOView - + double-click to select sample - + Delete (middle mousebutton) - + Cut - + Copy - + Paste - + Mute/unmute (<%1> + middle click) @@ -7646,18 +7650,18 @@ Reason: "%2" SampleTrack - + Volume - + Panning - - + + Sample track @@ -7665,32 +7669,32 @@ Reason: "%2" SampleTrackView - + Track volume - + Channel volume: - + VOL - + Panning - + Panning: - + PAN @@ -7698,355 +7702,360 @@ 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 - + + Keep plugin windows on top when not embedded + + + + 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. @@ -8545,43 +8554,43 @@ Remember to also save your project manually. You can choose to disable saving wh TimeLineWidget - + Enable/disable auto-scrolling - + Enable/disable loop-points - + After stopping go back to begin - + After stopping go back to position at which playing was started - + After stopping keep position - - + + Hint - + Press <%1> to disable magnetic loop points. - + Hold <Shift> to move the begin loop point; Press <%1> to disable magnetic loop points. @@ -8589,12 +8598,12 @@ Remember to also save your project manually. You can choose to disable saving wh Track - + Mute - + Solo @@ -8672,59 +8681,59 @@ Please make sure you have read-permission to the file and the directory containi TrackContentObjectView - + Current position - - + + Hint - + Press <%1> and drag to make a copy. - + 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) @@ -8732,63 +8741,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 @@ -8994,113 +9003,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 @@ -9191,59 +9200,59 @@ 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 @@ -9658,42 +9667,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 @@ -9701,87 +9710,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. @@ -10930,39 +10939,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. @@ -11838,7 +11847,7 @@ This chip was used in the Commodore 64 computer. - + Embedded ZynAddSubFX @@ -12293,12 +12302,12 @@ This chip was used in the Commodore 64 computer. vestigeInstrument - + Loading plugin - + Please wait while loading VST-plugin... diff --git a/data/locale/ko.ts b/data/locale/ko.ts index c82a2f8bf..4698112ed 100644 --- a/data/locale/ko.ts +++ b/data/locale/ko.ts @@ -2,640 +2,795 @@ AboutDialog + About LMMS - + LMMS에 대하여 + + LMMS + LMMS + + + Version %1 (%2/%3, Qt %4, %5) - + 버전 %1 (%2/%3, Qt %4, %5) + About - + 정보 + LMMS - easy music production for everyone - + LMMS - 누구나 쉽게 할 수 있는 음악 제작 + + Copyright © %1 + Copyright © %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 - + 개발자 + + Involved + 기여자 + + + + Contributors ordered by number of commits: + 기여자 (기여 순으로 정렬): + + + Translation - + 번역 + 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! - + 송현진 (Hyunjin Song) <tteu.ingog@gmail.com> +방성범 (Bang Seongbeom) <bangseongbeom@gmail.com> + +LMMS를 다른 언어로 번역하고 싶다거나 기존 번역을 개선하고 싶다면 저희를 도와주세요! LMMS 관리자와의 연락을 통해 참여하실 수 있습니다. + License - - - - LMMS - - - - Involved - - - - Contributors ordered by number of commits: - - - - Copyright © %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> - + 라이선스 AmplifierControlDialog + VOL - + 음량 + Volume: - 볼륨: + 음량: + PAN - + 패닝 + Panning: - + 패닝: + LEFT - + 왼쪽 + Left gain: - + 왼쪽 이득: + RIGHT - + 오른쪽 + Right gain: - + 오른쪽 이득: AmplifierControls + Volume - 볼륨 + 음량 + Panning - + 패닝 + Left gain - + 왼쪽 이득 + Right gain - + 오른쪽 이득 AudioAlsaSetupWidget + DEVICE - + 장치 + CHANNELS - + 채널 AudioFileProcessorView + Open other sample - + 다른 샘플 열기 + 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. - + 클릭하여 다른 오디오 파일을 선택합니다. 클릭하면 파일을 선택할 수 있는 창이 나타납니다. 루프 모드, 시작점, 끝점, 증폭 등의 설정은 자동으로 초기화되지 않으므로 원본 오디오 파일과 다르게 들릴 수 있습니다. + Reverse sample 샘플 역으로 + If you enable this button, the whole sample is reversed. This is useful for cool effects, e.g. a reversed crash. - - - - Amplify: - - - - 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!) - - - - Startpoint: - - - - Endpoint: - - - - Continue sample playback across notes - - - - 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) - + 이 버튼이 활성화되면 샘플을 역으로 재생합니다. 리버스 크래시와 같은 효과에 사용할 수 있습니다. + Disable loop - + 반복 비활성화 + This button disables looping. The sample plays only once from start to end. - + 이 버튼은 반복을 비활성화합니다. 샘플은 처음부터 끝까지 한 번만 재생됩니다. + + Enable loop - + 반복 활성화 + This button enables forwards-looping. The sample loops between the end point and the loop point. - + 이 버튼은 단방향 반복을 활성화합니다. 샘플은 반복 시작점과 끝점 사이에서 단방향으로 반복 재생됩니다. + This button enables ping-pong-looping. The sample loops backwards and forwards between the end point and the loop point. - + 이 버튼은 양방향 반복을 활성화합니다. 샘플은 반복 시작점과 끝점 사이에서 양방향으로 반복 재생됩니다. + + Continue sample playback across notes + 샘플을 여러 음표에 걸쳐 계속 재생 + + + + 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) + 이 옵션을 활성화하면 샘플이 여러 음표에 걸쳐 계속 재생됩니다 - 음표가 끝나기 전에 샘플이 끝나는 경우나 피치가 바뀌는 경우 다음 음표는 직전 음표의 재생이 끝난 곳부터 재생됩니다. 음표가 다시 처음부터 재생되게 하려면 매우 낮은 음표를 삽입하세요. (< 20Hz) + + + + Amplify: + 증폭: + + + + 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!) + 이 노브를 이용하여 증폭률을 설정할 수 있습니다. 값을 100%로 설정하면 샘플은 그대로 재생됩니다. 그렇지 않은 경우 샘플의 음량이 증가되거나 감소됩니다. (실제 샘플 파일에는 변화가 없습니다) + + + + Startpoint: + 시작점: + + + With this knob you can set the point where AudioFileProcessor should begin playing your sample. - + 이 노브를 이용하여 샘플 재생 시작점을 설정할 수 있습니다. + + Endpoint: + 끝점: + + + With this knob you can set the point where AudioFileProcessor should stop playing your sample. - + 이 노브를 이용하여 샘플 재생 끝점을 설정할 수 있습니다. + Loopback point: - + 루프 시작점: + With this knob you can set the point where the loop starts. - + 이 노브를 이용하여 샘플 반복 시작점을 설정할 수 있습니다. AudioFileProcessorWaveView + Sample length: - + 샘플 길이: AudioJack + JACK client restarted - + JACK 클라이언트 다시 시작됨 + 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와 JACK과의 연결이 끊겼습니다. LMMS의 JACK 드라이버를 다시 시작합니다. 수동으로 연결을 시도할 수도 있습니다. + JACK server down - + JACK 서버 다운됨 + 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. - + JACK 서버가 종료된 것 같습니다. 더 이상 작업을 진행할 수 없습니다. 프로젝트를 저장한 뒤 JACK과 LMMS를 다시 시작하세요. + CLIENT-NAME - + 클라이언트 이름 + CHANNELS - + 채널 AudioOss::setupWidget + DEVICE - + 장치 + CHANNELS - + 채널 AudioPortAudio::setupWidget + BACKEND - + 드라이버 + DEVICE - + 장치 AudioPulseAudio::setupWidget + DEVICE - + 장치 + CHANNELS - + 채널 AudioSdl::setupWidget + DEVICE - + 장치 AudioSndio::setupWidget + DEVICE - + 장치 + CHANNELS - + 채널 AudioSoundIo::setupWidget + BACKEND - + 드라이버 + DEVICE - + 장치 AutomatableModel + &Reset (%1%2) - + 초기화 (%1%2)(&R) + &Copy value (%1%2) - + 값 복사 (%1%2)(&C) + &Paste value (%1%2) - + 값 붙여넣기 (%1%2)(&P) + Edit song-global automation - - - - Connected to %1 - - - - Connected to controller - - - - Edit connection... - - - - Remove connection - - - - Connect to controller... - + 전역 오토메이션 편집 + Remove song-global automation - + 전역 오토메이션 제거 + Remove all linked controls - + 연결 제거 + + + + Connected to %1 + %1에 연결됨 + + + + Connected to controller + 컨트롤러에 연결됨 + + + + Edit connection... + 연결 편집... + + + + Remove connection + 연결 제거 + + + + Connect to controller... + 컨트롤러에 연결... AutomationEditor + Please open an automation pattern with the context menu of a control! - + 컨트롤의 컨텍스트 메뉴에서 오토메이션 패턴을 여시기 바랍니다! + Values copied - + 값 복사됨 + All selected values were copied to the clipboard. - + 선택한 모든 값이 클립보드에 복사되었습니다. AutomationEditorWindow + Play/pause current pattern (Space) - + 현재 패턴 재생/일시정지 (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) - + 현재 패턴 정지 (Space) + Click here if you want to stop playing of the current pattern. - - - - 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. - - - - 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. - - - - 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. - - - - Tension: - - - - Automation Editor - no pattern - - - - Automation Editor - %1 - + 현재 패턴의 재생을 정지하려면 여기를 클릭하세요. + Edit actions - + 편집 동작 + + Draw mode (Shift+D) + 그리기 모드 (Shift+D) + + + + Erase mode (Shift+E) + 지우기 모드 (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. + 여기를 클릭하면 그리기 모드가 활성화됩니다. 그리기 모드에서는 값을 추가하거나 이동할 수 있습니다. 이 모드는 대부분의 경우에 사용되는 기본 모드입니다. 'Shift+D' 키를 눌러 이 모드를 활성화할 수도 있습니다. + + + + 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. + 여기를 클릭하면 지우기 모드가 활성화됩니다. 지우기 모드에서는 값을 삭제할 수 있습니다. 'Shift+E' 키를 눌러 이 모드를 활성화할 수도 있습니다. + + + Interpolation controls - Timeline controls + + Discrete progression + 이산적 진행 + + + + Linear progression + 선형 진행 + + + + Cubic Hermite progression + 3차 에르미트 진행 + + + + 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. + 클릭하여 이 패턴을 3차 에르미트 진행으로 설정합니다. 각 점 사이에서 값은 매끄러운 곡선의 형태로 변화합니다.Save + + + + Tension: + + + + + Cut selected values (%1+X) + 선택된 값 잘라내기 (%1+X) + + + + Copy selected values (%1+C) + 선택된 값 복사 (%1+C) + + + + Paste values from clipboard (%1+V) + 선택된 값 붙여넣기 (%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 - Model is already connected to this pattern. + + 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 + 오토메이션 편집기 - %1 + + + + Model is already connected to this pattern. + 대상이 이미 패턴에 연결되어 있습니다. + AutomationPattern + Drag a control while pressing <%1> - + <%1> 키를 누른 채로 드래그 AutomationPatternView + double-click to open this pattern in automation editor - + 더블클릭하여 오토메이션 편집기에서 이 패턴 열기 + Open in Automation editor - + 오토메이션 편집기에서 열기 + Clear - + 지우기 + Reset name 이름 초기화 + Change name 이름 바꾸기 - %1 Connections - - - - Disconnect "%1" - - - + Set/clear record - + 녹음 설정/해제 + Flip Vertically (Visible) - + 상하 반전 + Flip Horizontally (Visible) - + 좌우 반전 + + %1 Connections + %1개의 연결 + + + + Disconnect "%1" + "%1" 연결 해제 + + + Model is already connected to this pattern. - + 대상이 이미 패턴과 연결되어 있습니다. AutomationTrack + Automation track - + 오토메이션 트랙 BBEditor + Beat+Bassline Editor 비트/베이스 라인 편집기 + Play/pause current beat/bassline (Space) - + 현재 비트/베이스 라인 재생/일시정지 (Space) + Stop playback of current beat/bassline (Space) - + 현재 비트/베이스 라인 정지 (Space) + Click here to play the current beat/bassline. The beat/bassline is automatically looped when its end is reached. - + 클릭하여 비트/베이스 라인을 재생합니다. 자동으로 반복 재생됩니다. + Click here to stop playing of current beat/bassline. - - - - Add beat/bassline - - - - Add automation-track - - - - Remove steps - 단계 제거 - - - Add steps - 단계 더하기 + 클릭하여 비트/베이스 라인 재생을 정지합니다. + Beat selector - + 비트 선택기 + Track and step actions - Clone Steps + + Add beat/bassline + 비트/베이스 라인 추가 + + + + Add sample-track + 샘플 트랙 추가 + + + + Add automation-track + 오토메이션 트랙 추가 + + + + Remove steps - Add sample-track + + Add steps + + + + + Clone Steps BBTCOView + Open in Beat+Bassline-Editor 비트/베이스 라인 편집기에서 열기 + Reset name 이름 초기화 + Change name 이름 바꾸기 + Change color 색상 바꾸기 + Reset color to default 색상을 기본값으로 되돌리기 @@ -643,135 +798,162 @@ If you're interested in translating LMMS in another language or want to imp BBTrack + Beat/Bassline %1 - + 비트/베이스 라인 %1 + Clone of %1 - + %1의 복제 BassBoosterControlDialog + FREQ - + 주파수 + Frequency: - + 주파수: + GAIN - + 이득 + Gain: 이득: + RATIO - + 비율 + Ratio: - + 비율: BassBoosterControls + Frequency - + 주파수 + Gain 이득 + Ratio - + 비율 BitcrushControlDialog + IN - + 입력 + OUT - + 출력 + + GAIN - + 이득 + Input Gain: - + 입력 이득: - NOIS - + + NOISE + 잡음 + Input Noise: + Output Gain: - + 출력 이득: + CLIP - + 클리핑 + Output Clip: - Rate - - - + Rate Enabled + Enable samplerate-crushing - Depth - - - + Depth Enabled + Enable bitdepth-crushing + + FREQ + 주파수 + + + Sample rate: - + 샘플 레이트: - STD - + + STEREO + 스테레오 + Stereo difference: + 좌우 차이: + + + + QUANT - Levels - - - + Levels: @@ -779,200 +961,246 @@ If you're interested in translating LMMS in another language or want to imp CaptionMenu + &Help - + 도움말(&H) + Help (not available) - + 도움말 사용 불가 CarlaInstrumentView + Show GUI - + GUI 표시 + Click here to show or hide the graphical user interface (GUI) of Carla. - + 클릭하여 Carla의 GUI를 표시하거나 숨깁니다. Controller + Controller %1 - + 컨트롤러 %1 ControllerConnectionDialog + Connection Settings - + 연결 설정 + MIDI CONTROLLER - + MIDI 컨트롤러 + Input channel - + 입력 채널 + CHANNEL - + 채널 + Input controller - + 입력 컨트롤러 + CONTROLLER - + 컨트롤러 + + Auto Detect - + 자동 감지 + MIDI-devices to receive MIDI-events from + USER CONTROLLER - + 사용자 지정 컨트롤러 + MAPPING FUNCTION - + 매핑 함수 + OK - + 확인 + Cancel - + 취소 + LMMS - + LMMS + Cycle Detected. - + 순환 연결이 감지되었습니다. ControllerRackView + Controller Rack - + 컨트롤러 랙 + Add - + 추가 + Confirm Delete - + 삭제 확인 + Confirm delete? There are existing connection(s) associated with this controller. There is no way to undo. - + 정말 삭제하시겠습니까? 이 컨트롤러와의 연결이 존재합니다. 이 동작은 취소할 수 없습니다. ControllerView + Controls - + 컨트롤 + Controllers are able to automate the value of a knob, slider, and other controls. - + 컨트롤러를 통하여 노브, 슬라이더 등의 값을 자동으로 제어할 수 있습니다. + Rename controller - + 컨트롤러 이름 바꾸기 + Enter the new name for this controller - - - - &Remove this controller - - - - Re&name this controller - + 컨트롤러의 새 이름을 입력하세요 + LFO - + LFO + + + + &Remove this controller + 컨트롤러 제거(&R) + + + + Re&name this controller + 컨트롤러 이름 바꾸기(&N) CrossoverEQControlDialog + Band 1/2 Crossover: + Band 2/3 Crossover: + Band 3/4 Crossover: + Band 1 Gain: + Band 2 Gain: + Band 3 Gain: + Band 4 Gain: + Band 1 Mute + Mute Band 1 + Band 2 Mute + Mute Band 2 + Band 3 Mute + Mute Band 3 + Band 4 Mute + Mute Band 4 @@ -980,251 +1208,339 @@ If you're interested in translating LMMS in another language or want to imp DelayControls + Delay Samples + Feedback - + 피드백 + Lfo Frequency - + LFO 주파수 + Lfo Amount + Output gain - + 출력 이득 DelayControlsDialog - Lfo Amt - + + DELAY + 지연 + Delay Time + + FDBK + 피드백 + + + Feedback Amount - Lfo - - - - Out Gain - - - - Gain - 이득 - - - DELAY - - - - FDBK - - - + RATE + + Lfo + + + + AMNT + + + Lfo Amt + + + + + Out Gain + 출력 이득 + + + + Gain + 이득 + DualFilterControlDialog - Filter 1 enabled - - - - Filter 2 enabled - - - - Click to enable/disable Filter 1 - - - - Click to enable/disable Filter 2 - - - + + FREQ - + 주파수 + + Cutoff frequency - + 차단 주파수 + + RESO - + 공명 + + Resonance 공명 + + GAIN - + 이득 + + Gain 이득 + MIX + Mix + + + Filter 1 enabled + 필터 1 활성화됨 + + + + Filter 2 enabled + 필터 2 활성화됨 + + + + Click to enable/disable Filter 1 + 클릭하여 필터 1 활성화/비활성화 + + + + Click to enable/disable Filter 2 + 클릭하여 필터 2 활성화/비활성화 + DualFilterControls + Filter 1 enabled - + 필터 1 활성화됨 + Filter 1 type - + 필터 1 종류 + Cutoff 1 frequency + Q/Resonance 1 - + 필터 1 Q/공명 + Gain 1 - + 이득 1 + Mix + Filter 2 enabled - + 필터 2 활성화됨 + Filter 2 type - + 필터 2 종류 + Cutoff 2 frequency + Q/Resonance 2 - + Q/공명 2 + Gain 2 - + 이득 2 + + LowPass + + HiPass + + BandPass csg + + BandPass czpg + + Notch - + 노치 + + Allpass + + Moog - + Moog + + 2x LowPass + + RC LowPass 12dB + + RC BandPass 12dB + + RC HighPass 12dB + + RC LowPass 24dB + + RC BandPass 24dB + + RC HighPass 24dB + + Vocal Formant Filter + + 2x Moog - + 2x Moog + + SV LowPass + + SV BandPass + + SV HighPass + + SV Notch - + SV 노치 + + Fast Formant + + Tripole @@ -1232,41 +1548,50 @@ If you're interested in translating LMMS in another language or want to imp Editor - Play (Space) - - - - Stop (Space) - - - - Record - - - - Record while playing - - - + Transport controls + + + Play (Space) + 재생 (Space) + + + + Stop (Space) + 정지 (Space) + + + + Record + 녹음 + + + + Record while playing + 재생하면서 녹음 + Effect + Effect enabled - + 효과 활성화됨 + Wet/Dry mix + Gate - + 게이트 + Decay @@ -1274,95 +1599,117 @@ If you're interested in translating LMMS in another language or want to imp EffectChain + Effects enabled - + 효과 활성화됨 EffectRackView + EFFECTS CHAIN - + 효과 체인 + Add effect - + 효과 추가 EffectSelectDialog + Add effect - + 효과 추가 + + Name 이름 + Type 형태 + Description 요약 + Author - + 개발자 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. @@ -1379,73 +1726,90 @@ Right clicking will bring up a context menu where you can change the order in wh + Move &up - + 위로 이동(&U) + Move &down - + 아래로 이동(&D) + &Remove this plugin - + 플러그인 제거(&R) EnvelopeAndLfoParameters + Predelay + Attack + Hold + Decay + Sustain + Release + Modulation - + 변조 + LFO Predelay + LFO Attack + LFO speed - + LFO 속도 + LFO Modulation + LFO Wave Shape - + LFO 파형 + Freq x 100 - + 주파수 x 100 + Modulate Env-Amount @@ -1453,741 +1817,952 @@ Right clicking will bring up a context menu where you can change the order in wh EnvelopeAndLfoView + + DEL + Predelay: + Use this knob for setting predelay of the current envelope. The bigger this value the longer the time before start of actual envelope. + + ATT + 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: + 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 - + 감쇠 + 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 + 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 + 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 + + Modulation amount: + 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: + 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: + 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 - + 속도 + LFO speed: - + 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. - + 이 노브를 사용하여 LFO의 속도를 설정합니다. 값이 클수록 LFO 진동이 빨라지게 됩니다. + 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. - + 클릭하여 사인파를 선택합니다. + Click here for a triangle-wave. - 삼각 파형을 위하여 여기를 클릭 + 클릭하여 삼각파를 선택합니다. + Click here for a saw-wave for current. - + 클릭하여 톱니파를 선택합니다. + Click here for a square-wave. - 사각 파형을 위하여 여기를 클릭 + 클릭하여 사각파를 선택합니다. + Click here for a user-defined wave. Afterwards, drag an according sample-file onto the LFO graph. - FREQ x 100 - + + Click here for random wave. + 클릭하여 무작위 파형을 선택합니다. + + FREQ x 100 + 주파수 x 100 + + + Click here if the frequency of this LFO should be multiplied by 100. + multiply LFO-frequency by 100 + MODULATE ENV-AMOUNT + Click here to make the envelope-amount controlled by this LFO. + control envelope-amount by this LFO + ms/LFO: - + ms/LFO: + Hint - + + Drag a sample from somewhere and drop it in this window. - - Click here for random wave. - - EqControls + Input gain - + 입력 이득 + Output gain - + 출력 이득 + Low shelf gain + Peak 1 gain - + 피크 1 이득 + Peak 2 gain - + 피크 2 이득 + Peak 3 gain - + 피크 3 이득 + Peak 4 gain - + 피크 4 이득 + High Shelf gain + HP res - + 고역 필터 공명 + Low Shelf res + Peak 1 BW - + 피크 1 대역폭 + Peak 2 BW - + 피크 2 대역폭 + Peak 3 BW - + 피크 3 대역폭 + Peak 4 BW - + 피크 4 대역폭 + High Shelf res + LP res - + 저역 필터 공명 + HP freq - + 고역 필터 주파수 + Low Shelf freq + Peak 1 freq - + 피크 1 주파수 + Peak 2 freq - + 피크 2 주파수 + Peak 3 freq - + 피크 3 주파수 + Peak 4 freq - + 피크 4 주파수 + High shelf freq + LP freq - + 저역 필터 주파수 + HP active + Low shelf active + Peak 1 active - + 피크 1 활성화 + Peak 2 active - + 피크 2 활성화 + Peak 3 active - + 피크 3 활성화 + Peak 4 active - + 피크 4 활성화 + High shelf active + LP active + 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 + Low Shelf + Peak 1 - + 피크 1 + Peak 2 - + 피크 2 + Peak 3 - + 피크 3 + Peak 4 - + 피크 4 + High Shelf + LP + In Gain + + + Gain 이득 + Out Gain - + 출력 이득 + Bandwidth: - + 대역폭: + + Octave + 옥타브 + + + Resonance : - + 공명 : + Frequency: - + 주파수: + lp grp + hp grp - - Octave - - EqHandle + Reso: - + 공명: + BW: - + 대역폭: + + Freq: - + 주파수: ExportProjectDialog + Export project - + 프로젝트 내보내기 + Output 출력 + File format: - + 파일 형식: + Samplerate: - + 샘플 레이트: + 44100 Hz - + 44100 Hz + 48000 Hz - + 48000 Hz + 88200 Hz - + 88200 Hz + 96000 Hz - + 96000 Hz + 192000 Hz - - - - Bitrate: - - - - 64 KBit/s - - - - 128 KBit/s - - - - 160 KBit/s - - - - 192 KBit/s - - - - 256 KBit/s - - - - 320 KBit/s - + 192000 Hz + Depth: + 16 Bit Integer - + 16비트 정수 + + 24 Bit Integer + 24비트 정수 + + + 32 Bit Float + 32비트 실수 + + + + Stereo mode: + 스테레오 모드: + + + + Stereo + 스테레오 + + + + Joint Stereo - Please note that not all of the parameters above apply for all file formats. - + + Mono + 모노 + + Bitrate: + 비트 레이트: + + + + 64 KBit/s + 64 KBit/s + + + + 128 KBit/s + 128 KBit/s + + + + 160 KBit/s + 160 KBit/s + + + + 192 KBit/s + 192 KBit/s + + + + 256 KBit/s + 256 KBit/s + + + + 320 KBit/s + 320 KBit/s + + + + Use variable bitrate + 가변 비트레이트 사용 + + + Quality settings - + 품질 설정 + Interpolation: - + 보간법: + Zero Order Hold + Sinc Fastest + Sinc Medium (recommended) + Sinc Best (very slow!) + Oversampling (use with care!): + 1x (None) - + 1x (사용하지 않음) + 2x - + 2x + 4x - + 4x + 8x - - - - Start - - - - Cancel - + 8x + Export as loop (remove end silence) - + 루프 곡처럼 내보내기 (후반부 여백 제거) + Export between loop markers - + 반복 마커 사이 구간만 내보내기 + + Start + 시작 + + + + Cancel + 취소 + + + Could not open file 파일을 열 수 없음 - Export project to %1 - - - - Error - - - - Error while determining file-encoder device. Please try to choose a different output format. - - - - Rendering: %1% - - - + 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! - + 파일 %1을(를) 쓰기 위하여 열 수 없습니다. +경로에 파일이 존재하고 파일에 쓸 수 있는 권한이 있는지 확인 후 다시 시도하시기 바랍니다! + + + + Export project to %1 + %1(으)로 프로젝트 내보내기 + + + + Error + 오류 + + + + Error while determining file-encoder device. Please try to choose a different output format. + 파일 인코더를 결정하는 중 오류가 발생하였습니다. 다른 포맷을 선택하여 다시 시도해 보세요. + + + + Rendering: %1% + 렌더링: %1% Fader + + Please enter a new value between %1 and %2: - + %1부터 %2까지의 값을 입력하세요: FileBrowser + Browser - + 탐색기 FileBrowserTreeWidget + Send to active instrument-track - - - - Open in new instrument-track/B+B Editor - - - - Loading sample - - - - Please wait, loading sample for preview... - - - - --- Factory files --- - + 활성화된 악기 트랙에서 열기 + Open in new instrument-track/Song Editor - + 새로운 악기 트랙이나 노래 편집기에서 열기 + + Open in new instrument-track/B+B Editor + 새로운 악기 트랙이나 비트/베이스 라인 편집기에서 열기 + + + + Loading sample + 샘플을 로딩하는 중 + + + + Please wait, loading sample for preview... + 미리보기를 위하여 샘플을 로딩하는 중입니다. 잠시 기다려 주세요... + + + Error - + 오류 + does not appear to be a valid + file + + + --- Factory files --- + + FlangerControls + Delay Samples + Lfo Frequency - + LFO 주파수 + Seconds - + + Regen + Noise 잡음 + Invert - + 파형 반전 FlangerControlsDialog + + DELAY + 지연 + + + Delay Time: - Feedback Amount: - - - - White Noise Amount: - - - - DELAY - - - + RATE - Rate: + + Period: + AMNT + Amount: + FDBK + 피드백 + + + + Feedback Amount: + NOISE + 잡음 + + + + White Noise Amount: + Invert - + 파형 반전 FxLine + Channel send amount + 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. @@ -2195,85 +2770,125 @@ In order to route the channel to another channel, select the FX channel and clic You can remove and move FX channels in the context menu, which is accessed by right-clicking the FX channel. - + FX 채널은 한 개 이상의 악기 트랙으로부터 사운드를 입력받습니다. +한 채널에서 여러 다른 채널로 사운드를 보낼 수 있습니다. LMMS는 FX 채널 간 무한 루프를 생성하는 것을 자동으로 방지합니다. +한 채널의 출력을 다른 채널로 보내려면 출력을 내보낼 FX 채널을 선택한 뒤 대상 채널의 "send" 버튼을 선택하시기 바랍니다. "send" 버튼 아래에 있는 노브를 통하여 보내질 신호의 레벨을 조절할 수 있습니다. + +FX 채널을 오른쪽 클릭하여 나오는 컨텍스트 메뉴에서 채널을 제거하거나 이동할 수 있습니다. + + Move &left - + 왼쪽으로 이동(&L) + Move &right - + 오른쪽으로 이동(&R) + Rename &channel - + 채널 이름 바꾸기(&C) + R&emove channel - + 채널 제거(&R) + Remove &unused channels - + 사용하지 않는 채널 제거(&U) FxMixer + Master - + 마스터 + + + FX %1 - + FX %1 + + + + Volume + 음량 + + + + Mute + 음소거 + + + + Solo + 독주 FxMixerView + FX-Mixer - + FX-믹서 + FX Fader %1 - + FX 페이더 %1 + Mute - + 음소거 + Mute this FX channel - + 이 채널 음소거 + Solo - + 독주 + Solo FX channel - + 이 채널 독주 FxRoute + + Amount to send from channel %1 to channel %2 - + 채널 %1에서 채널 %2(으)로 보낼 양 GigInstrument + Bank 뱅크 + Patch 패치 + Gain 이득 @@ -2281,89 +2896,111 @@ You can remove and move FX channels in the context menu, which is accessed by ri GigInstrumentView + Open other GIG file - + 다른 GIG 파일 열기 + Click here to open another GIG file - + 클릭하여 다른 GIG 파일 열기 + Choose the patch 패치 선택 + Click here to change which patch of the GIG file to use + + Change which instrument of the GIG file is being played + Which GIG file is currently being used + Which patch of the GIG file is currently being used + Gain 이득 + Factor to multiply samples by + Open GIG file - + GIG 파일 열기 + GIG Files (*.gig) - + GIG 파일 (*.gig) GuiApplication + Working directory - + 작업 경로 + The LMMS working directory %1 does not exist. Create it now? You can change the directory later via Edit -> Settings. - + LMMS 작업 경로 %1이(가) 존재하지 않습니다. 지금 만드시겠습니까? 나중에 편집 -> 설정에서 변경할 수 있습니다. + Preparing UI UI 준비 + Preparing song editor 노래 편집기 준비 + Preparing mixer 믹서 준비 + Preparing controller rack - 제어기 랙 준비 + 컨트롤러 랙 준비 + Preparing project notes 프로젝트 노트 준비 + Preparing beat/bassline editor 비트/베이스 라인 편집기 준비 + Preparing piano roll 피아노 롤 준비 + Preparing automation editor 오토메이션 편집기 준비 @@ -2371,788 +3008,986 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentFunctionArpeggio + Arpeggio - + 아르페지오 + Arpeggio type - + 아르페지오 형태 + Arpeggio range + 아르페지오 범위 + + + + Cycle steps - Arpeggio time - - - - Arpeggio gate - - - - Arpeggio direction - - - - Arpeggio mode - - - - Up - - - - Down - - - - Up and down - - - - Random - - - - Free - - - - Sort - - - - Sync - 동기 - - - Down and up - - - + Skip rate + Miss rate - Cycle steps - + + Arpeggio time + 아르페지오 시간 + + + + Arpeggio gate + 아르페지오 게이트 + + + + Arpeggio direction + 아르페지오 방향 + + + + Arpeggio mode + 아르페지오 모드 + + + + Up + 위로 + + + + Down + 아래로 + + + + Up and down + 위 다음 아래 + + + + Down and up + 아래 다음 위 + + + + Random + 무작위 + + + + Free + 자유 + + + + Sort + 정렬 + + + + Sync + 동기화 InstrumentFunctionArpeggioView + 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 - + 범위 + Arpeggio range: - + 아르페지오 범위: + octave(s) - + 옥타브 + Use this knob for setting the arpeggio range in octaves. The selected arpeggio will be played within specified number of octaves. - - - - TIME - - - - Arpeggio time: - - - - ms - - - - Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. - - - - GATE - - - - 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: - - - - Direction: - - - - Mode: - - - - SKIP - - - - Skip rate: - - - - 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. - + 이 노브를 사용하여 아르페지오 범위를 옥타브 단위로 설정합니다. 아르페지오는 설정된 옥타브 범위 내에서 재생됩니다. + CYCLE + Cycle notes: + note(s) + 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 + + + + + Skip rate: + + + + + + + % + % + + + + 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 + 시간 + + + + Arpeggio time: + 아르페지오 시간: + + + + ms + ms + + + + Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. + 이 노브를 사용하여 아르페지오 시간을 밀리초 단위로 지정합니다. 아르페지오 시간은 각각의 아르페지오 음이 재생되는 길이를 결정합니다. + + + + GATE + 게이트 + + + + 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: + 코드: + + + + Direction: + 방향: + + + + Mode: + 모드: + InstrumentFunctionNoteStacking + octave - + 옥타브 + + Major + Majb5 + minor + minb5 + sus2 + sus4 + aug + augsus4 + tri + 6 - + 6 + 6sus4 - + 6sus4 + 6add9 - + 6add9 + m6 + 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 + Maj7b5 + Maj7#5 + Maj7#11 + Maj7add13 + m7 + m7b5 + m7b9 + m7add11 + m7add13 + m-Maj7 + m-Maj7add11 + m-Maj7add13 + 9 - + 9 + 9sus4 - + 9sus4 + add9 - + add9 + 9#5 - + 9#5 + 9b5 - + 9b5 + 9#11 - + 9#11 + 9b13 - + 9b13 + Maj9 + Maj9sus4 + Maj9#5 + Maj9#11 + m9 + madd9 + m9b5 + m9-Maj7 + 11 - + 11 + 11b9 - + 11b9 + Maj11 + m11 + m-Maj11 + 13 - + 13 + 13#9 - + 13#9 + 13b9 - + 13b9 + 13b5b9 - + 13b5b9 + Maj13 + m13 + m-Maj13 + Harmonic minor - + 화성 단음계 + Melodic minor - + 가락 단음계 + Whole tone + Diminished + Major pentatonic + Minor pentatonic + Jap in sen + Major bebop + Dominant bebop + Blues + Arabic + Enigmatic + Neopolitan + Neopolitan minor + Hungarian minor + Dorian - Phrygolydian + + Phrygian + Lydian + Mixolydian + Aeolian + Locrian - Chords - - - - Chord type - - - - Chord range - - - + Minor + Chromatic + Half-Whole Diminished + 5 - + 5 + Phrygian dominant + Persian + + + Chords + 코드 + + + + Chord type + 코드 종류 + + + + Chord range + 코드 범위 + InstrumentFunctionNoteStackingView - RANGE - - - - Chord range: - - - - octave(s) - - - - Use this knob for setting the chord range in octaves. The selected chord will be played within specified number of octaves. - - - + STACKING - + 코드 쌓기 + Chord: - + 코드: + + + + RANGE + 범위 + + + + Chord range: + 코드 범위: + + + + octave(s) + 옥타브 + + + + 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 - + MIDI 입력 활성화 + + CHANNEL - + 채널 + + VELOCITY - + 벨로시티 + ENABLE MIDI OUTPUT - + MIDI 출력 활성화 + PROGRAM - - - - MIDI devices to receive MIDI events from - - - - MIDI devices to send MIDI events to - + 프로그램 + NOTE - CUSTOM BASE VELOCITY + + MIDI devices to receive MIDI events from + + MIDI devices to send MIDI events to + + + + + CUSTOM BASE VELOCITY + 사용자 지정 기준 벨로시티 + + + Specify the velocity normalization base for MIDI-based instruments at 100% note velocity + BASE VELOCITY - + 기준 벨로시티 InstrumentMiscView + MASTER PITCH - + 마스터 피치 + Enables the use of Master Pitch - + 마스터 피치 사용 InstrumentSoundShaping + VOLUME - + 음량 + Volume - 볼륨 + 음량 + CUTOFF - + 컷오프 + + Cutoff frequency - + 차단 주파수 + RESO - + 공명 + Resonance 공명 + Envelopes/LFOs - + 엔벨로프/LFO + Filter type - 필터 형태 + 필터 종류 + Q/Resonance - + Q/공명 + LowPass + HiPass + BandPass csg + BandPass czpg + Notch - + 노치 + Allpass + Moog - + Moog + 2x LowPass + RC LowPass 12dB + RC BandPass 12dB + RC HighPass 12dB + RC LowPass 24dB + RC BandPass 24dB + RC HighPass 24dB + Vocal Formant Filter + 2x Moog - + 2x Moog + SV LowPass + SV BandPass + SV HighPass + SV Notch - + SV 노치 + Fast Formant + Tripole @@ -3160,359 +3995,451 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentSoundShapingView + TARGET - + 대상 + 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 - + 필터 + 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. - Hz - + + FREQ + 주파수 + + cutoff frequency: + 차단 주파수: + + + + 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 - + 공명 + Resonance: 공명: + 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. - FREQ - - - - cutoff frequency: - - - + Envelopes, LFOs and filters are not supported by the current instrument. - + 이 악기는 엔벨로프, LFO, 필터를 지원하지 않습니다. InstrumentTrack - unnamed_track - - - - Volume - 볼륨 - - - Panning - - - - Pitch - - - - FX channel - - - - Default preset - - - + With this knob you can set the volume of the opened channel. - + 이 노브를 이용하여 트랙의 음량을 조절할 수 있습니다. + + + unnamed_track + 이름 없는 트랙 + + + Base note - + 기준 음 + + Volume + 음량 + + + + Panning + 패닝 + + + + Pitch + 피치 + + + Pitch range - + 피치 범위 + + FX channel + FX 채널 + + + Master Pitch - + 마스터 피치 + + + + + Default preset + 기본 프리셋 InstrumentTrackView + Volume - 볼륨 + 음량 + Volume: - 볼륨: + 음량: + VOL - + 음량 + Panning - + 패닝 + Panning: - + 패닝: + PAN - + 패닝 + MIDI - + MIDI + Input 입력 + Output 출력 + FX %1: %2 - + FX %1: %2 InstrumentTrackWindow + GENERAL SETTINGS - - - - Instrument volume - - - - Volume: - 볼륨: - - - VOL - - - - Panning - - - - Panning: - - - - PAN - - - - Pitch - - - - Pitch: - - - - cents - - - - PITCH - - - - FX channel - - - - ENV/LFO - - - - FUNC - - - - FX - - - - MIDI - - - - Save preset - - - - XML preset file (*.xpf) - - - - PLUGIN - - - - Pitch range (semitones) - - - - RANGE - - - - 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. - - - - MISC - + 일반 설정 + 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 채널 + + + + FX + 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 + 엔벨로프, 필터 & LFO + + + + Chord stacking & arpeggio + 코드 쌓기 & 아르페지오 + + + + Effects + 효과 + + + + MIDI settings + MIDI 설정 + + + + Miscellaneous + 기타 + + + + Save preset + 프리셋 저장 + + + + XML preset file (*.xpf) + XML 프리셋 파일 (*.xpf) + + + + Plugin + 플러그인 Knob + Set linear - + 선형으로 설정 + Set logarithmic - + 로그스케일로 설정 + Please enter a new value between -96.0 dBFS and 6.0 dBFS: - + -96.0 dBFS부터 6.0 dBFS까지의 값을 입력하세요: + Please enter a new value between %1 and %2: - + %1부터 %2까지의 값을 입력하세요: LadspaControl + Link channels - + 채널 링크 LadspaControlDialog + Link Channels - + 채널 링크 + Channel - + 채널 LadspaControlView + Link channels - + 채널 링크 + Value: - + 값: + Sorry, no help available. - + 죄송합니다. 도움말을 사용할 수 없습니다. LadspaEffect + Unknown LADSPA plugin %1 requested. - + 알 수 없는 LADSPA 플러그인 %1이(가) 요청되었습니다. LcdSpinBox + Please enter a new value between %1 and %2: - + %1부터 %2까지의 값을 입력하세요: LeftRightNav + + + Previous - + 이전 + + + Next - + 다음 + Previous (%1) - + 이전 (%1) + Next (%1) - + 다음 (%1) LfoController + LFO Controller - + LFO 컨트롤러 + Base value - + 기준 값 + Oscillator speed + Oscillator amount + Oscillator phase - + 오실레이터 위상 + Oscillator waveform - + 오실레이터 파형 + Frequency Multiplier @@ -3520,1101 +4447,1369 @@ You can remove and move FX channels in the context menu, which is accessed by ri LfoControllerDialog + LFO - + LFO + LFO Controller - + LFO 컨트롤러 + BASE - + 기준 + Base amount: + todo + SPD - + 속도 + LFO-speed: + Use this knob for setting speed of the LFO. The bigger this value the faster the LFO oscillates and the faster the effect. + 이 노브를 사용하여 LFO의 속도를 설정합니다. 값이 클수록 LFO 진동이 빨라지게 됩니다. + + + + AMNT + Modulation amount: + 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 - + 위상 + Phase offset: - + 위상: + degrees - + + 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. - + 클릭하여 사인파를 선택합니다. + Click here for a triangle-wave. - 삼각 파형을 위하여 여기를 클릭 + 클릭하여 삼각파를 선택합니다. + Click here for a saw-wave. - 톱니 파형을 위해 여기를 클릭 + 클릭하여 톱니파를 선택합니다. + Click here for a square-wave. - 사각 파형을 위하여 여기를 클릭 - - - Click here for an exponential wave. - - - - Click here for white-noise. - 화이트 노이즈를 위해 여기를 클릭 - - - Click here for a user-defined shape. -Double click to pick a file. - + 클릭하여 사각파를 선택합니다. + Click here for a moog saw-wave. - AMNT - + + Click here for an exponential wave. + 클릭하여 지수형 파형을 선택합니다. + + + + Click here for white-noise. + 클릭하여 화이트 노이즈를 선택합니다. + + + + Click here for a user-defined shape. +Double click to pick a file. + 클릭하여 사용자 지정 파형을 선택합니다. +더블클릭하여 파일을 선택하세요. LmmsCore + Generating wavetables + Initializing data structures - + 자료 구조 초기화 중 + Opening audio and midi devices - + 오디오 장치와 MIDI 장치를 여는 중 + Launching mixer threads - + 믹서 스레드를 시작하는 중 MainWindow - Could not save config-file - + + Configuration file + 설정 파일 - Could not save configuration file %1. You're probably not permitted to write to this file. -Please make sure you have write-access to the file and try again. - + + Error while parsing configuration file at line %1:%2: %3 + 설정 파일 분석 중 오류 발생 (행 %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! + 파일 %1을(를) 쓰기 위하여 열 수 없습니다. +경로에 파일이 존재하고 파일에 쓸 수 있는 권한이 있는지 확인 후 다시 시도하시기 바랍니다! + + + + 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? + 복구 파일이 존재합니다. 이전에 LMMS가 비정상 종료되었거나 여러 개의 LMMS 인스턴스가 동시에 실행 중인 것 같습니다. 복구 파일로부터 프로젝트를 복구하시겠습니까? + + + + + + Recover + 복구 + + + + Recover the file. Please don't run multiple instances of LMMS when you do this. + 파일을 복구합니다. 다른 LMMS 인스턴스가 실행 중이지 않은 상태에서 선택하시기 바랍니다. + + + + + + Discard + 저장하지 않음 + + + + Launch a default session and delete the restored files. This is not reversible. + 복구 파일을 삭제하고 기본 프로젝트를 불러옵니다. 이 동작은 되돌릴 수 없습니다. + + + + Version %1 + 버전 %1 + + + + Preparing plugin browser + 플러그인 탐색기 준비 + + + + Preparing file browsers + 파일 탐색기 준비 + + + + My Projects + 내 프로젝트 + + + + My Samples + 내 샘플 + + + + My Presets + 내 사전 설정 + + + + My Home + 내 홈 디렉터리 + + + + Root directory + 최상위 디렉토리 + + + + Volumes + 음량 + + + + My Computer + 내 컴퓨터 + + + + Loading background artwork + 배경 아트워크를 불러오는 중 + + + + &File + 파일(&F) + + + &New - + 새로 만들기(&N) + + New from template + 템플릿에서 새 프로젝트 생성 + + + &Open... - + 열기(&O)... + + &Recently Opened Projects + 최근에 사용한 프로젝트(&R) + + + &Save - + 저장(&S) + Save &As... - + 다른 이름으로 저장(&A)... + + Save as New &Version + 새로운 버전으로 저장(&V) + + + + Save as default template + 기본 템플릿으로 저장 + + + Import... - + 가져오기... + E&xport... - + 내보내기(&X)... + + E&xport Tracks... + 트랙 내보내기(&X)... + + + + Export &MIDI... + MIDI 내보내기(&M)... + + + &Quit - + 끝내기(&Q) + &Edit - + 편집(&E) + + Undo + 실행 취소 + + + + Redo + 다시 실행 + + + Settings - + 설정 + + &View + 보기(&V) + + + &Tools - + 도구(&T) + &Help - + 도움말(&H) + + Online Help + 온라인 도움말 + + + Help + 도움말 + + + + What's This? + + About + 정보 + + + + Create new project + 새 프로젝트 생성 + + + + Create new project from template + 템플릿에서 새 프로젝트 생성 + + + + Open existing project + 기존 프로젝트 열기 + + + + Recently opened projects + 최근에 사용한 프로젝트 + + + + Save current project + 현재 프로젝트 저장 + + + + Export current project + 현재 프로젝트 내보내기 + + + What's this? - About - + + Toggle metronome + 메트로놈 토글 - Create new project - - - - Create new project from template - - - - Open existing project - - - - Recently opened projects - - - - Save current project - - - - Export current project - - - - Song Editor - + + Show/hide Song-Editor + 노래 편집기 보이기/숨기기 + 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. - Beat+Bassline Editor - 비트/베이스 라인 편집기 + + Show/hide Beat+Bassline Editor + 비트/베이스 라인 편집기 보이기/숨기기 + 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. - Piano Roll - + + Show/hide Piano-Roll + 피아노-롤 보이기/숨기기 + Click here to show or hide the Piano-Roll. With the help of the Piano-Roll you can edit melodies in an easy way. - Automation Editor - + + Show/hide Automation Editor + 오토메이션 편집기 보이기/숨기기 + 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. - FX Mixer - + + Show/hide FX Mixer + FX 믹서 보이기/숨기기 + 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. - Project Notes - 프로젝트 노트 + + Show/hide project notes + 프로젝트 노트 보이기/숨기기 + Click here to show or hide the project notes window. In this window you can put down your project notes. - Controller Rack - + + Show/hide controller rack + 컨트롤러 랙 보이기/숨기기 + Untitled - + 제목 없음 + + Recover session. Please save your work! + 복구 세션입니다. 프로젝트 파일을 저장해 주세요! + + + LMMS %1 - + 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) + LMMS (*.mmp *.mmpz) + + + + Save Project + 프로젝트 저장 + + + + LMMS Project + LMMS 프로젝트 + + + + LMMS Project Template + LMMS 프로젝트 템플릿 + + + + 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. - LMMS (*.mmp *.mmpz) - + + Song Editor + 노래 편집기 - Version %1 - + + Beat+Bassline Editor + 비트/베이스 라인 편집기 - Configuration file - + + Piano Roll + 피아노 롤 - Error while parsing configuration file at line %1:%2: %3 - + + Automation Editor + 오토메이션 편집기 - Volumes - + + FX Mixer + FX 믹서 - Undo - + + Project Notes + 프로젝트 노트 - Redo - - - - My Projects - 내 프로젝트 - - - My Samples - 내 샘플 - - - My Presets - 내 사전 설정 - - - My Home - 내 홈 디렉터리 - - - My Computer - 내 컴퓨터 - - - &File - - - - &Recently Opened Projects - - - - Save as New &Version - - - - E&xport Tracks... - - - - Online Help - - - - What's This? - - - - Open Project - - - - Save Project - - - - 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. - - - - Ignore - - - - Launch LMMS as usual but with automatic backup disabled to prevent the present recover file from being overwritten. - - - - Discard - - - - Launch a default session and delete the restored files. This is not reversible. - - - - Preparing plugin browser - 플러그인 탐색기 준비 - - - Preparing file browsers - 파일 탐색기 준비 - - - Root directory - - - - Loading background artwork - - - - New from template - - - - Save as default template - - - - &View - - - - Toggle metronome - - - - Show/hide Song-Editor - - - - Show/hide Beat+Bassline Editor - 비트/베이스 라인 편집기 보이기/숨기기 - - - Show/hide Piano-Roll - - - - Show/hide Automation Editor - - - - Show/hide FX Mixer - - - - Show/hide project notes - 프로젝트 노트 보이기/숨기기 - - - Show/hide controller rack - - - - Recover session. Please save your work! - - - - Automatic backup disabled. Remember to save your work! - - - - 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? - - - - LMMS Project - - - - LMMS Project Template - - - - Overwrite default template? - - - - This will overwrite your current default template. - + + Controller Rack + 컨트롤러 랙 + Volume as dBFS - + 음량을 dBFS 단위로 표시 + Smooth scroll - + 부드러운 스크롤 + Enable note labels in piano roll - - - - Save project template - + 피아노 롤에 음표 라벨 표시 MeterDialog + + Meter Numerator - + 박자표 분자 + + Meter Denominator - + 박자표 분모 + TIME SIG - + 박자 MeterModel + Numerator - + 분자 + Denominator - + 분모 MidiController + MIDI Controller - + MIDI 컨트롤러 + unnamed_midi_controller - + 이름 없는 MIDI 컨트롤러 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. - + 기본 사운드폰트 파일이 설정되지 않았습니다(편집->설정). 따라서 MIDI 파일을 가져온 뒤 재생하면 아무 소리도 재생되지 않을 것입니다. GM 사운드폰트를 다운로드한 뒤 설정 창에서 경로를 지정하고 다시 시도해 보시기 바랍니다. + 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. - + LMMS가 SoundFont2 플레이어 지원 없이 컴파일되었습니다. MIDI 파일에서 가져온 트랙은 기본적으로 SoundFont2 플레이어로 재생되므로 MIDI 파일을 가져온 뒤 재생하면 아무 소리도 재생되지 않을 것입니다. + Track - + 트랙 MidiJack + JACK server down When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (title) - + JAK 서버 종료 + The JACK server seems to be shuted down. When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (dialog message) - + JACK 서버가 종료된 것 같습니다. MidiPort + Input channel - + 입력 채널 + Output channel - + 출력 채널 + Input controller - + 입력 컨트롤러 + Output controller - + 출력 컨트롤러 + Fixed input velocity - + 입력 벨로시티 고정값 + Fixed output velocity - - - - Output MIDI program - - - - Receive MIDI-events - - - - Send MIDI-events - + 출력 벨로시티 고정값 + Fixed output note - + 출력 음높이 고정값 + + Output MIDI program + 출력 MIDI 프로그램 + + + Base velocity - + 기준 벨로시티 + + + + Receive MIDI-events + MIDI 이벤트 받기 + + + + Send MIDI-events + MIDI 이벤트 보내기 MidiSetupWidget + DEVICE - + 장치 MonstroInstrument + Osc 1 Volume - + 오실레이터 1 볼륨 + Osc 1 Panning - + 오실레이터 1 패닝 + Osc 1 Coarse detune + Osc 1 Fine detune left + Osc 1 Fine detune right + Osc 1 Stereo phase offset + Osc 1 Pulse width - + 오실레이터 1 펄스 폭 + Osc 1 Sync send on rise + Osc 1 Sync send on fall + Osc 2 Volume - + 오실레이터 2 볼륨 + Osc 2 Panning - + 오실레이터 2 패닝 + Osc 2 Coarse detune + Osc 2 Fine detune left + Osc 2 Fine detune right + Osc 2 Stereo phase offset + Osc 2 Waveform - + 오실레이터 2 파형 + Osc 2 Sync Hard + Osc 2 Sync Reverse + Osc 3 Volume - + 오실레이터 3 볼륨 + Osc 3 Panning - + 오실레이터 3 패닝 + Osc 3 Coarse detune + Osc 3 Stereo phase offset + Osc 3 Sub-oscillator mix + Osc 3 Waveform 1 - + 오실레이터 3 파형 1 + Osc 3 Waveform 2 - + 오실레이터 3 파형 2 + Osc 3 Sync Hard + Osc 3 Sync Reverse + LFO 1 Waveform - + LFO 1 파형 + LFO 1 Attack + LFO 1 Rate + LFO 1 Phase + LFO 2 Waveform - + LFO 2 파형 + LFO 2 Attack + LFO 2 Rate + LFO 2 Phase + Env 1 Pre-delay + Env 1 Attack + 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 + Vol1-Env1 + Vol1-Env2 + Vol1-LFO1 + Vol1-LFO2 + Vol2-Env1 + Vol2-Env2 + Vol2-LFO1 + Vol2-LFO2 + Vol3-Env1 + Vol3-Env2 + Vol3-LFO1 + Vol3-LFO2 + Phs1-Env1 + Phs1-Env2 + Phs1-LFO1 + Phs1-LFO2 + Phs2-Env1 + Phs2-Env2 + Phs2-LFO1 + Phs2-LFO2 + Phs3-Env1 + Phs3-Env2 + Phs3-LFO1 + Phs3-LFO2 + Pit1-Env1 + Pit1-Env2 + Pit1-LFO1 + Pit1-LFO2 + Pit2-Env1 + Pit2-Env2 + Pit2-LFO1 + Pit2-LFO2 + Pit3-Env1 + Pit3-Env2 + Pit3-LFO1 + Pit3-LFO2 + PW1-Env1 + PW1-Env2 + PW1-LFO1 + PW1-LFO2 + Sub3-Env1 + Sub3-Env2 + Sub3-LFO1 + Sub3-LFO2 + + Sine wave - 사인 파형 + 사인파 + Bandlimited Triangle wave - + 대역 제한 삼각파 + Bandlimited Saw wave - + 대역 제한 톱니파 + Bandlimited Ramp wave - + 대역 제한 역톱니파 + Bandlimited Square wave - + 대역 제한 사각파 + Bandlimited Moog saw wave - + 대역 제한 Moog 톱니파 + + Soft square wave + Absolute sine wave + + Exponential wave - + 지수형 파형 + White noise - + 화이트 노이즈 + Digital Triangle wave - + 삼각파 + Digital Saw wave - + 톱니파 + Digital Ramp wave - + 역톱니파 + Digital Square wave - + 사각파 + Digital Moog saw wave - + Moog 톱니파 + Triangle wave - 삼각 파형 + 삼각파 + Saw wave - 톱니 파형 + 톱니파 + Ramp wave - + 역톱니파 + Square wave - 사각 파형 + 사각파 + Moog saw wave - + Moog 톱니파 + Abs. sine wave + Random - + 무작위 + Random smooth @@ -4622,20 +5817,24 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MonstroView + Operators view + 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 + 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. @@ -4644,256 +5843,407 @@ Each modulation target has 4 knobs, one for each modulator. By default the knobs + + + + Volume + 음량 + + + + + + Panning + 패닝 + + + + + + Coarse detune + + + + + + + semitones + 반음 + + + + + Finetune left + + + + + + + + cents + 센트 + + + + + 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 + + + + + + Rate + + + + + + Phase + 위상 + + + + + Pre-delay + + + + + + Hold + + + + + + Decay + + + + + + Sustain + + + + + + Release + + + + + + Slope + + + + Mix Osc2 with Osc3 + Modulate amplitude of Osc3 with Osc2 - + 오실레이터 2로 오실레이터 3의 진폭 변조 + Modulate frequency of Osc3 with Osc2 - + 오실레이터 2로 오실레이터 3의 주파수 변조 + Modulate phase of Osc3 with Osc2 - + 오실레이터 2로 오실레이터 3의 위상 변조 + 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. - + 오실레이터 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. - Volume - 볼륨 - - - Panning - - - - Coarse detune - - - - semitones - - - - Finetune left - - - - cents - - - - 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 - - - - Rate - - - - Phase - - - - Pre-delay - - - - Hold - - - - Decay - - - - Sustain - - - - Release - - - - Slope - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Modulation amount @@ -4901,34 +6251,42 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator MultitapEchoControlDialog + Length - + 길이 + Step length: + Dry + Dry Gain: + Stages + Lowpass stages: + Swap inputs - + 좌우 입력 바꾸기 + Swap left and right input channel for reflections @@ -4936,365 +6294,468 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator NesInstrument + Channel 1 Coarse detune + Channel 1 Volume + Channel 1 Envelope length + Channel 1 Duty cycle + Channel 1 Sweep amount + Channel 1 Sweep rate + Channel 2 Coarse detune + Channel 2 Volume + Channel 2 Envelope length + Channel 2 Duty cycle + Channel 2 Sweep amount + Channel 2 Sweep rate + Channel 3 Coarse detune + Channel 3 Volume + Channel 4 Volume + Channel 4 Envelope length + Channel 4 Noise frequency + Channel 4 Noise frequency sweep + Master volume - + 마스터 음량 + Vibrato - + 비브라토 NesInstrumentView + + + + Volume - 볼륨 + 음량 + + + Coarse detune + + + Envelope length + Enable channel 1 - + 채널 1 활성화 + Enable envelope 1 - + 엔벨로프 1 활성화 + Enable envelope 1 loop + Enable sweep 1 + + Sweep amount + + Sweep rate + + 12.5% Duty cycle + + 25% Duty cycle + + 50% Duty cycle + + 75% Duty cycle + Enable channel 2 - + 채널 2 활성화 + Enable envelope 2 - + 엔벨로프 2 활성화 + Enable envelope 2 loop + Enable sweep 2 + Enable channel 3 - + 채널 3 활성화 + Noise Frequency + Frequency sweep + Enable channel 4 - + 채널 4 활성화 + Enable envelope 4 - + 엔벨로프 4 활성화 + Enable envelope 4 loop + Quantize noise frequency when using note frequency + Use note frequency for noise + Noise mode + Master Volume - + 마스터 볼륨 + Vibrato - + 비브라토 OscillatorObject + + Osc %1 waveform + 오실레이터 %1 파형 + + + + Osc %1 harmonic + + + + + Osc %1 volume - + 오실레이터 %1 음량 + + Osc %1 panning - - - - Osc %1 coarse detuning - + 오실레이터 %1 패닝 + + Osc %1 fine detuning left + + Osc %1 coarse detuning + + + + Osc %1 fine detuning right + Osc %1 phase-offset - + 오실레이터 %1 위상 + Osc %1 stereo phase-detuning - + 오실레이터 %1 좌우 위상차 + Osc %1 wave shape - + 오실레이터 %1 파형 + Modulation type %1 - - - - Osc %1 waveform - - - - Osc %1 harmonic - + 변조 유형 %1 PatchesDialog + Qsynth: Channel Preset + Bank selector + Bank 뱅크 + Program selector + Patch 패치 + Name 이름 + OK - + 확인 + Cancel - + 취소 PatmanView + Open other patch - + 다른 패치 열기 + Click here to open another patch-file. Loop and Tune settings are not reset. + Loop - + 루프 + Loop mode - + 루프 모드 + Here you can toggle the Loop mode. If enabled, PatMan will use the loop information available in the file. + Tune + Tune mode + Here you can toggle the Tune mode. If enabled, PatMan will tune the sample to match the note's frequency. + No file selected - + 파일이 선택되지 않음 + Open patch file - + 패치 파일 열기 + Patch-Files (*.pat) - + 패치 파일 (*.pat) PatternView - Open in piano-roll - 피아노-롤에서 열기 - - - Clear all notes - 전체 박자 지우기 - - - Reset name - 이름 초기화 - - - Change name - 이름 바꾸기 - - - Add steps - 단계 더하기 - - - Remove steps - 단계 제거 - - + use mouse wheel to set velocity of a step + double-click to open in Piano Roll + + Open in piano-roll + 피아노-롤에서 열기 + + + + Clear all notes + 전체 음표 지우기 + + + + Reset name + 이름 초기화 + + + + Change name + 이름 바꾸기 + + + + Add steps + + + + + Remove steps + + + + Clone Steps @@ -5302,1177 +6763,1603 @@ 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. - + 이전 버전 LMMS의 버그로 인해 피크 컨트롤러가 제대로 연결되지 않았을 수 있습니다. 피크 컨트롤러가 제대로 연결되었는지 확인 후 파일을 다시 저장해 주시기 바랍니다. 불편을 드려 죄송합니다. PeakControllerDialog + PEAK + LFO Controller - + LFO 컨트롤러 PeakControllerEffectControlDialog + BASE - + 기준 + Base amount: - Modulation amount: - - - - Attack: - - - - Release: - - - + AMNT + + Modulation amount: + + + + MULT + Amount Multiplicator: + ATCK + + Attack: + + + + DCAY - Treshold: + + Release: + TRSH + + + Treshold: + + PeakControllerEffectControls + Base value - + 기준 값 + Modulation amount - Mute output - - - + Attack + Release - Abs Value - - - - Amount Multiplicator - - - + Treshold + + + Mute output + 출력 음소거 + + + + Abs Value + 절댓값 + + + + Amount Multiplicator + + PianoRoll - Please open a pattern by double-clicking on it! - 이것을 이중 클릭을 함으로서 패턴을 열어주세요. - - - Last note - 마지막 박자 - - - Note lock - 박자 잠금 - - + Note Velocity - + 음표 벨로시티 + Note Panning - + 음표 패닝 + Mark/unmark current semitone - - - - Mark current scale - - - - Mark current chord - - - - Unmark all - - - - No scale - - - - No chord - - - - Velocity: %1% - - - - Panning: %1% left - - - - Panning: %1% right - - - - Panning: center - - - - Please enter a new value between %1 and %2: - + 현재 반음 표시 + Mark/unmark all corresponding octave semitones - Select all notes on this key + + Mark current scale + + + Mark current chord + + + + + Unmark all + 모두 표시 해제 + + + + Select all notes on this key + 이 음의 음표 모두 선택 + + + + Note lock + 박자 잠금 + + + + Last note + 마지막 박자 + + + + No scale + 음계 없음 + + + + No chord + 코드 없음 + + + + Velocity: %1% + 벨로시티: %1% + + + + Panning: %1% left + 패닝: %1% 왼쪽 + + + + Panning: %1% right + 패닝: %1% 오른쪽 + + + + Panning: center + 패닝: 가운데 + + + + Please open a pattern by double-clicking on it! + 더블클릭하여 패턴을 열어주세요! + + + + + Please enter a new value between %1 and %2: + %1부터 %2까지의 값을 입력하세요: + PianoRollWindow + Play/pause current pattern (Space) - + 현재 패턴 재생/일시정지 (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) - + 현재 패턴 정지 (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) - + 그리기 모드 (Shift+D) + Erase mode (Shift+E) - + 지우기 모드 (Shift+E) + Select mode (Shift+S) - - - - Detune mode (Shift+T) - + 선택 모드 (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. - + 여기를 클릭하면 그리기 모드가 활성화됩니다. 그리기 모드에서는 음표를 추가, 이동할 수 있으며 길이를 조절할 수도 있습니다. 이 모드는 대부분의 경우에 사용되는 기본 모드입니다. 'Shift+D' 키를 눌러 이 모드를 활성화할 수도 있습니다. 이 모드에서 %1키를 누르면 일시적으로 선택 모드로 전환됩니다. + 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. + 여기를 클릭하면 선택 모드가 활성화됩니다. 선택 모드에서는 음표를 선택할 수 있습니다. 그리기 모드에서 %1키를 누르면 일시적으로 선택 모드로 전환됩니다. + + + + Pitch Bend mode (Shift+T) - 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. + + 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) - + 선택된 음표 잘라내기 (%1+X) + Copy selected notes (%1+C) - + 선택된 음표 복사 (%1+C) + Paste notes from clipboard (%1+V) - + 선택된 음표 붙여넣기 (%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. - 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. - - - - Edit actions - - - - Copy paste controls - - - + 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 피아노-롤 - %1 + + Piano-Roll - no pattern 피아노-롤 - 패턴 없음 - - Quantize - - PianoView + Base note - + 기준 음 Plugin + Plugin not found - + 플러그인을 찾을 수 없음 + The plugin "%1" wasn't found or could not be loaded! Reason: "%2" - + 플러그인 "%1"을(를) 찾을 수 없거나 읽어올 수 없습니다. +이유: %2 + Error while loading plugin - + 플러그인 로딩 오류 + Failed to load plugin "%1"! - + 플러그인 "%1"을(를) 로딩할 수 없습니다! PluginBrowser + + Instrument Plugins + 악기 플러그인 + + + Instrument browser 악기 탐색기 + Drag an instrument into either the Song-Editor, the Beat+Bassline Editor or into an existing instrument track. - - - - Instrument Plugins - + 플러그인을 노래 편집기, 비트/베이스 라인 편집기, 이미 존재하는 악기 트랙 중 하나로 드래그하세요. PluginFactory + Plugin not found. - + 플러그인을 찾을 수 없습니다. + LMMS plugin %1 does not have a plugin descriptor named %2! - + LMMS 플러그인 %1은(는) 이름이 %2인 플러그인 디스크립터를 가지고 있지 않습니다! ProjectNotes - Project notes + + Project Notes 프로젝트 노트 - Put down your project notes here. - 여기에 프로젝트 노트를 작성하세요. + + Enter project notes here + 여기에 프로젝트 노트를 입력하세요 + Edit Actions - + 편집 동작 + &Undo - + 실행 취소(&U) + %1+Z - + %1+Z + &Redo - + 다시 실행(&R) + %1+Y - + %1+Y + &Copy - + 복사(&C) + %1+C - + %1+C + Cu&t - + 잘라내기(&T) + %1+X - + %1+X + &Paste - + 붙여넣기(&P) + %1+V - + %1+V + Format Actions - + 서식 동작 + &Bold - + 굵게(&B) + %1+B - + %1+B + &Italic - + 기울임꼴(&I) + %1+I - + %1+I + &Underline - + 밑줄(&U) + %1+U - + %1+U + &Left - + 왼쪽 정렬(&L) + %1+L - + %1+L + C&enter - + 가운데 정렬(&E) + %1+E - + %1+E + &Right - + 오른쪽 정렬(&R) + %1+R - + %1+R + &Justify - + 양쪽 정렬(&J) + %1+J - + %1+J + &Color... - + 색(&C)... ProjectRenderer + WAV-File (*.wav) - + Wave 파일(*.wav) + Compressed OGG-File (*.ogg) - + 압축 OGG 파일(*.ogg) + + + + Compressed MP3-File (*.mp3) + 압축 MP3 파일(*.mp3) QWidget + + + Name: 이름: + + Maker: 제작자: + + Copyright: 저작권: + + Requires Real Time: - 실제 시간 필요: + + + + + + + Yes + + + + + + No 아니오 + + Real Time Capable: 실제 시간 가능: + + In Place Broken: 깨진 곳에 위치: + + Channels In: - 채널 인: + 입력 채널: + + Channels Out: - 채널 아웃: + 출력 채널: + + File: %1 + 파일: %1 + + + File: 파일: - - File: %1 - - RenameDialog + Rename... + 이름 바꾸기... + + + + ReverbSCControlDialog + + + Input + 입력 + + + + Input Gain: + 입력 이득: + + + + Size + 크기 + + + + Size: + + + Color + 음색 + + + + Color: + + + + + Output + 출력 + + + + Output Gain: + 출력 이득: + + + + ReverbSCControls + + + Input Gain + 입력 이득 + + + + Size + 크기 + + + + Color + 음색 + + + + Output Gain + 출력 이득 + SampleBuffer + + Fail to open file + 파일을 열 수 없음 + + + + Audio files are limited to %1 MB in size and %2 minutes of playing time + 오디오 파일은 %1MB보다 작고 %2분보다 짧아야 합니다 + + + Open audio file - - - - 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) - + 오디오 파일 열기 + All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) - + 모든 오디오 파일 (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + + + + Wave-Files (*.wav) + Wave 파일(*.wav) + + + + OGG-Files (*.ogg) + OGG 파일(*.ogg) + + + + DrumSynth-Files (*.ds) + DrumSynth 파일(*.ds) + + + + FLAC-Files (*.flac) + FLAC 파일(*.flac) + + + + SPEEX-Files (*.spx) + SPEEX 파일(*.spx) + + + + VOC-Files (*.voc) + VOC 파일(*.voc) + + + + AIFF-Files (*.aif *.aiff) + AIFF 파일 (*.aif *.aiff) + + + + AU-Files (*.au) + AU 파일 (*.au) + + + + RAW-Files (*.raw) + RAW 파일 (*.raw) SampleTCOView + double-click to select sample - + 더블클릭하여 샘플 선택 + Delete (middle mousebutton) - + 삭제(마우스 가운데 버튼) + Cut - + 잘라내기 + Copy - + 복사 + Paste - + 붙여넣기 + Mute/unmute (<%1> + middle click) - + 음소거/해제 (<%1> + 마우스 가운데 버튼) SampleTrack - Sample track - - - + Volume - 볼륨 + 음량 + Panning - + 패닝 + + + + + Sample track + 샘플 트랙 SampleTrackView + Track volume - + 트랙 음량 + Channel volume: - + 채널 음량: + VOL - + 음량 + Panning - + 패닝 + Panning: - + 패닝: + PAN - + 패닝 SetupDialog + Setup LMMS - + LMMS 설정 + + General settings - + 일반 설정 + BUFFER SIZE - + 버퍼 크기 + + Reset to default-value - + 기본값으로 초기화 + MISC - + 기타 + Enable tooltips - + 툴팁 활성화 + Show restart warning after changing settings - + 설정을 변경했을 때 다시 시작 경고 표시 + Display volume as dBFS - + 음량을 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 - + VST 플러그인을 LMMS 재생과 동기화 + 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 - + LMMS 작업 경로 - VST-plugin directory - + + Themes directory + 테마 경로 + Background artwork - + 배경 아트워크 + + VST-plugin directory + VST 플러그인 경로 + + + + GIG directory + GIG 경로 + + + + SF2 directory + SF2 경로 + + + + LADSPA plugin directories + LADSPA 플러그인 경로 + + + STK rawwave directory + Default Soundfont File - + 기본 사운드폰트 파일 + + Performance settings - + 성능 설정 + + Auto save + 자동 저장 + + + + Enable auto-save + 자동 저장 활성화 + + + + Allow auto-save while playing + 재생 중 자동 저장 허용 + + + UI effects vs. performance - + UI 효과 vs. 성능 + Smooth scroll in Song Editor - + 노래 편집기에서 부드러운 스크롤 사용 + Show playback cursor in AudioFileProcessor + + Audio settings - + 오디오 설정 + AUDIO INTERFACE - + 오디오 인터페이스 + + MIDI settings - + MIDI 설정 + MIDI INTERFACE - + MIDI 인터페이스 + OK - + 확인 + Cancel - + 취소 + Restart LMMS - + LMMS 다시 시작 + Please note that most changes won't take effect until you restart LMMS! + Frames: %1 Latency: %2 ms - + 프레임: %1 +시간 지연: %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. - + 여기에서 LMMS 내부 버퍼 크기를 설정할 수 있습니다. 작은 값을 설정하면 시간 지연이 감소하지만 음질 저하나 성능 저하가 일어날 수 있습니다. 이러한 현상은 실시간 커널을 가지지 않는 오래된 시스템에서 자주 발생합니다. + Choose LMMS working directory - + LMMS 작업 경로 선택 + + Choose your GIG directory + GIG 경로 선택 + + + + Choose your SF2 directory + SF2 경로 선택 + + + Choose your VST-plugin directory - + VST 플러그인 경로 선택 + Choose artwork-theme directory - + 아트워크 경로 선택 + Choose LADSPA plugin directory - + LADSPA 플러그인 경로 선택 + Choose STK rawwave directory + Choose default SoundFont - + 기본 사운드폰트 설정 + Choose background artwork - + 배경 아트워크 선택 + + minutes + + + + + minute + + + + + Disabled + 비활성화됨 + + + + Auto-save interval: %1 + 자동 저장 간격: %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. + 자동 백업의 시간 간격을 %1(으)로 설정합니다. +여전히 프로젝트를 수동으로 저장하는 것을 추천합니다. 재생 중 자동 저장을 비활성화할 수 있으며 일부 오래된 시스템에서는 잘 작동하지 않을 수 있습니다. + + + 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. - - Reopen last project on start - - - - Directories - - - - Themes directory - - - - GIG directory - - - - SF2 directory - - - - LADSPA plugin directories - - - - Auto save - - - - Choose your GIG directory - - - - Choose your SF2 directory - - - - minutes - - - - minute - - - - Enable auto-save - - - - Allow auto-save while playing - - - - 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. - - Song + Tempo - + 템포 + Master volume - + 마스터 음량 + Master pitch - - - - 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... - - - - The following errors occured while loading: - - - - MIDI File (*.mid) - + 마스터 피치 + LMMS Error report - + LMMS 오류 보고 + + Project saved + 프로젝트 저장됨 + + + + The project %1 is now saved. + 프로젝트 %1이 저장되었습니다. + + + + Project NOT saved. + 프로젝트가 저장되지 않았습니다. + + + + The project %1 was not saved! + 프로젝트 %1이 저장되지 않았습니다! + + + + Import file + 파일 가져오기 + + + + MIDI sequences + MIDI 시퀀스 + + + + Hydrogen projects + Hydrogen 프로젝트 + + + + 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) + MIDI 파일(*.mid) + + + + The following errors occured while loading: + 로딩 중 다음과 같은 오류가 발생하였습니다: 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. + 파일 %1을(를) 열 수 없습니다. 파일을 읽을 수 있는 권한이 없기 때문일 수 있습니다. 파일을 읽을 수 있는 권한이 있는지 확인 후 다시 시도하시기 바랍니다. + + + Could not write 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. - - - - Error in file - - - - The file %1 seems to contain errors and therefore can't be loaded. - - - - Tempo - - - - TEMPO/BPM - - - - tempo of song - - - - 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 - - - - Master volume - - - - master volume - - - - Master pitch - - - - master pitch - - - - Value: %1% - - - - Value: %1 semitones - - - + 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. - + 파일 %1을(를) 쓰기 위하여 열 수 없습니다. 파일을 쓸 수 있는 권한이 없기 때문일 수 있습니다. 파일에 쓸 수 있는 권한이 있는지 확인 후 다시 시도하시기 바랍니다. - template - + + Error in file + 파일 오류 - project - + + The file %1 seems to contain errors and therefore can't be loaded. + 파일 %1에 오류가 있어 로딩에 실패하였습니다. + Version difference - + 버전 차이 + This %1 was created with LMMS %2. - + 이 %1은(는) LMMS %2에서 만들어졌습니다. + + + + template + 템플릿 + + + + project + 프로젝트 + + + + Tempo + 템포 + + + + TEMPO/BPM + 템포/BPM + + + + tempo of song + 템포 + + + + 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). + 곡의 템포는 분당 박자 수(BPM) 단위로 설정할 수 있습니다. 이 값을 바꾸면 곡의 템포를 바꿀 수 있습니다. 한 마디가 4박자인 일반적인 경우 BPM 단위의 템포는 분당 재생되는 1 / 4 마디의 수(4분당 재생되는 마디의 수)와 같습니다. + + + + High quality mode + 고음질 모드 + + + + + Master volume + 마스터 음량 + + + + master volume + 마스터 볼륨 + + + + + Master pitch + 마스터 피치 + + + + master pitch + 마스터 피치 + + + + Value: %1% + 값: %1% + + + + Value: %1 semitones + 값: %1반음 SongEditorWindow + Song-Editor - + 노래 편집기 + Play song (Space) - + 노래 재생 (Space) + Record samples from Audio-device - + 오디오 장치로부터 샘플 녹음 + Record samples from Audio-device while playing song or BB track - + 노래 또는 비트/베이스 라인 트랙을 재생하는 동안 오디오 장치로부터 샘플 녹음 + Stop song (Space) - - - - Add beat/bassline - - - - Add sample-track - - - - Add automation-track - - - - Draw mode - - - - Edit mode (select and move) - + 노래 정지 (Space) + 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. + 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 - Edit actions - + + Add beat/bassline + 비트/베이스 라인 추가 + + Add sample-track + 샘플 트랙 추가 + + + + Add automation-track + 오토메이션 트랙 추가 + + + + Edit actions + 편집 동작 + + + + Draw mode + 그리기 모드 + + + + Edit mode (select and move) + 편집 모드 (선택 및 이동) + + + Timeline controls + Zoom controls @@ -6480,590 +8367,753 @@ Remember to also save your project manually. You can choose to disable saving wh SpectrumAnalyzerControlDialog + Linear spectrum - + 선형 스펙트럼 + Linear Y axis - + 선형 Y축 SpectrumAnalyzerControls + Linear spectrum - + 선형 스펙트럼 + Linear Y axis - + 선형 Y축 + Channel mode - + 채널 모드 SubWindow + Close - + 닫기 + Maximize - + 최대화 + Restore - + 복원 TabWidget + + Settings for %1 - + %1에 대한 설정 TempoSyncKnob + + Tempo Sync - + 템포 동기화 + No Sync - + 동기화 없음 + Eight beats - + 여덟 박자 + Whole note - + 온음표 + Half note - + 2분음표 + Quarter note - + 4분음표 + 8th note - + 8분음표 + 16th note - + 16분음표 + 32nd note - + 32분음표 + Custom... - + 사용자 지정... + Custom - + 사용자 지정 + Synced to Eight Beats - + 여덟 박자에 동기화됨 + Synced to Whole Note - + 온음표에 동기화됨 + Synced to Half Note - + 2분음표에 동기화됨 + Synced to Quarter Note - + 4분음표에 동기화됨 + Synced to 8th Note - + 8분음표에 동기화됨 + Synced to 16th Note - + 16분음표에 동기화됨 + Synced to 32nd Note - + 32분음표에 동기화됨 TimeDisplayWidget + click to change time units - + 클릭하여 시간 단위 바꾸기 + MIN - + + SEC - + + MSEC - + 밀리초 + BAR - + 마디 + BEAT - + + TICK - + TimeLineWidget + Enable/disable auto-scrolling - + 자동 스크롤 활성화/비활성화 + Enable/disable loop-points - + 루프 활성화/비활성화 + After stopping go back to begin - + 정지한 뒤 시작점으로 이동 + After stopping go back to position at which playing was started - + 정지한 뒤 재생을 시작한 점으로 이동 + After stopping keep position - + 정지한 후 위치 유지 + + Hint - + + Press <%1> to disable magnetic loop points. - + <%1> 키를 눌러 반복 지점을 자유롭게 이동할 수 있습니다. + Hold <Shift> to move the begin loop point; Press <%1> to disable magnetic loop points. - + <Shift> 키를 누르면 반복 시작점을 움직일 수 있습니다; <%1> 키를 눌러 반복 지점을 자유롭게 움직일 수 있습니다. Track + Mute - + 음소거 + Solo - + 독주 TrackContainer + Couldn't import file - + 파일을 가져올 수 없음 + Couldn't find a filter for importing file %1. You should convert this file into a format supported by LMMS using another software. - + 파일 %1을(를) 가져오기 위한 필터를 찾을 수 없습니다. +이 파일을 가져오려면 다른 프로그램을 사용하여 LMMS가 지원하는 포맷으로 변환하시기 바랍니다. + Couldn't open file - + 파일을 열 수 없음 + 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! - + 파일 %1을(를) 읽기 열 수 없습니다. 파일을 읽을 수 있는 권한이 있는지 확인 후 다시 시도하시기 바랍니다! + Loading project... - + 프로젝트 로딩 중... + + Cancel - + 취소 + + Please wait... - + 잠시만 기다려 주세요... + + Loading cancelled + 로딩 취소됨 + + + + Project loading was cancelled. + 프로젝트 로딩이 취소되었습니다. + + + + Loading Track %1 (%2/Total %3) + 트랙 %1 로딩 중 (%2/총 %3) + + + Importing MIDI-file... - + MIDI 파일을 가져오는중... TrackContentObject + Mute - + 음소거 TrackContentObjectView + Current position - + 현재 위치 + + Hint - + + Press <%1> and drag to make a copy. - + <%1> 키를 누른 채 드래그하여 복사합니다. + Current length - + 현재 길이 + Press <%1> for free resizing. - + <%1> 키를 눌러 크기를 자유롭게 조절할 수 있습니다. + + %1:%2 (%3:%4 to %5:%6) - + %1:%2 (%3:%4부터 %5:%6까지) + Delete (middle mousebutton) - + 삭제(마우스 가운데 버튼) + Cut - + 잘라내기 + Copy - + 복사 + Paste - + 붙여넣기 + Mute/unmute (<%1> + middle click) - + 음소거/해제 (<%1> + 마우스 가운데 버튼) 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 - + FX %1: %2 + + Assign to new FX Channel + 새 FX 채널 할당 + + + Turn all recording on + Turn all recording off - - Assign to new FX Channel - - 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 + 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 + Synchronize oscillator 2 with oscillator 3 + Use frequency modulation for modulating oscillator 2 with oscillator 3 + Osc %1 volume: - + 오실레이터 %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: - + 오실레이터 %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 - + 반음 + 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. - + 이 노브를 사용하여 오실레이터 %1의 피치를 조절할 수 있습니다. 24반음(두 옥타브) 범위 내에서 조절이 가능합니다. 이 기능은 화음을 가지는 소리를 합성할 때 유용하게 사용될 수 있습니다. + Osc %1 fine detuning left: + + cents - + 센트 + 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. - + 이 노브를 사용하여 오실레이터 %1의 왼쪽 채널 음정을 미세 조절할 수 있습니다. -100센트부터 +100센트까지의 범위 내에서 조절이 가능합니다. 이 기능은 풍성한 소리를 합성할 때 유용하게 사용될 수 있습니다. + 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. - + 이 노브를 사용하여 오실레이터 %1의 오른쪽 채널 음정을 미세 조절할 수 있습니다. -100센트부터 +100센트까지의 범위 내에서 조절이 가능합니다. 이 기능은 풍성한 소리를 합성할 때 유용하게 사용될 수 있습니다. + Osc %1 phase-offset: + + degrees - + + 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. - + 이 오실레이터에 사인파 사용 + Use a triangle-wave for current oscillator. - + 이 오실레이터에 삼각파 사용 + Use a saw-wave for current oscillator. - + 이 오실레이터에 톱니파 사용 + Use a square-wave for current oscillator. - + 이 오실레이터에 사각파 사용 + Use a moog-like saw-wave for current oscillator. + Use an exponential wave for current oscillator. + Use white-noise for current oscillator. + Use a user-defined waveform for current oscillator. - + 이 오실레이터에 사용자 지정 파형 사용 VersionedSaveDialog + Increment version number - + 버전 증가 + Decrement version number - + 버전 감소 + already exists. Do you want to replace it? - + 이(가) 이미 존재합니다. 덮어쓰시겠습니까? VestigeInstrumentView + Open other VST-plugin - + 다른 VST 플러그인 열기 + 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. - - - - 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 - + 다른 VST 플러그인을 열려면 여기를 클릭하세요. 이 버튼을 클릭하면 플러그인 파일을 선택할 수 있는 창이 열립니다. + Control VST-plugin from LMMS host - + LMMS에서 VST 플러그인 제어 + Click here, if you want to control VST-plugin from host. - + LMMS에서 VST 플러그인을 제어하려면 여기를 클릭하세요. + Open VST-plugin preset - + VST-플러그인 프리셋 열기 + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. - + 다른 *.fxp, *.fxb VST 플러그인 프리셋을 열려면 여기를 클릭하세요. + Previous (-) - + 이전 (-) + + Click here, if you want to switch to another VST-plugin preset program. - + 다른 VST 플러그인 프리셋으로 전환하려면 여기를 클릭하세요. + Save preset - + 프리셋 저장 + Click here, if you want to save current VST-plugin preset program. - + 현재 VST 플러그인 프리셋을 저장하려면 여기를 클릭하세요. + Next (+) - + 다음 (+) + Click here to select presets that are currently loaded in VST. - Preset - + + Show/hide GUI + GUI 보이기/숨기기 + + Click here to show or hide the graphical user interface (GUI) of your VST-plugin. + 클릭하여 VST 플러그인의 GUI를 표시하거나 숨깁니다. + + + + Turn off all notes + 모든 음 끄기 + + + + Open VST-plugin + VST 플러그인 열기 + + + + DLL-files (*.dll) + DLL 파일 (*.dll) + + + + EXE-files (*.exe) + EXE 파일 (*.exe) + + + + No VST-plugin loaded + VST 플러그인이 로딩되지 않음 + + + + Preset + 프리셋 + + + by + - VST plugin control @@ -7071,582 +9121,751 @@ 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 - + 클릭하여 활성화 VstEffectControlDialog + Show/hide - + 보이기/숨기기 + Control VST-plugin from LMMS host - + LMMS에서 VST 플러그인 제어 + Click here, if you want to control VST-plugin from host. - + LMMS에서 VST 플러그인을 제어하려면 여기를 클릭하세요. + Open VST-plugin preset - + VST-플러그인 프리셋 열기 + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. - + 다른 *.fxp, *.fxb VST 플러그인 프리셋을 열려면 여기를 클릭하세요. + Previous (-) - + 이전 (-) + + Click here, if you want to switch to another VST-plugin preset program. - + 다른 VST 플러그인 프리셋으로 전환하려면 여기를 클릭하세요. + 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. - + 현재 VST 플러그인 프리셋을 저장하려면 여기를 클릭하세요. + + Effect by: + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> - + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> VstPlugin - Loading plugin - 플러그인 읽는 중 + + + The VST plugin %1 could not be loaded. + VST 플러그인 %1을 불러올 수 없습니다. + Open Preset - + 프리셋 열기 + + Vst Plugin Preset (*.fxp *.fxb) - + VST 플러그인 프리셋 (*.fxp *.fxb) + : default + " + ' + Save Preset - + 프리셋 저장 + .fxp - + .fxp + .FXP - + .FXP + .FXB - + .FXB + .fxb - + .fxb + + Loading plugin + 플러그인 읽는 중 + + + Please wait while loading VST plugin... - - - - The VST plugin %1 could not be loaded. - + VST 플러그인을 읽을 동안 잠시 기다려 주세요... WatsynInstrument + Volume A1 - + A1 음량 + Volume A2 - + A2 음량 + Volume B1 - + B1 음량 + Volume B2 - + B2 음량 + Panning A1 - + A1 패닝 + Panning A2 - + A2 패닝 + Panning B1 - + B1 패닝 + Panning B2 - + 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 + Right detune B1 + Right detune B2 + 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 + B2-B1 modulation + Selected graph - + 선택된 그래프 WatsynView - Select oscillator A1 - - - - Select oscillator A2 - - - - Select oscillator B1 - - - - Select oscillator B2 - - - - Mix output of A2 to A1 - - - - Modulate amplitude of A1 with output of A2 - - - - Ring-modulate A1 and A2 - - - - Modulate phase of A1 with output of A2 - - - - Mix output of B2 to B1 - - - - Modulate amplitude of B1 with output of B2 - - - - Ring-modulate B1 and B2 - - - - Modulate phase of B1 with output of B2 - - - - Draw your own waveform here by dragging your mouse on this graph. - - - - Load waveform - - - - Click to load a waveform from a sample file - - - - Phase left - - - - Click to shift phase by -15 degrees - - - - Phase right - - - - Click to shift phase by +15 degrees - - - - Normalize - 일반화 - - - Click to normalize - - - - Invert - - - - Click to invert - - - - Smooth - 부드럽게 - - - Click to smooth - - - - Sine wave - 사인 파형 - - - Click for sine wave - - - - Triangle wave - 삼각 파형 - - - Click for triangle wave - - - - Click for saw wave - - - - Square wave - 사각 파형 - - - Click for square wave - - - + + + + Volume - 볼륨 + 음량 + + + + Panning - + 패닝 + + + + Freq. multiplier + + + + Left detune + + + + + + + + cents - + 센트 + + + + Right detune + A-B Mix + Mix envelope amount + Mix envelope attack + Mix envelope hold + Mix envelope decay + Crosstalk + + + Select oscillator A1 + + + + + Select oscillator A2 + + + + + Select oscillator B1 + + + + + Select oscillator B2 + + + + + Mix output of A2 to A1 + + + + + Modulate amplitude of A1 with output of A2 + + + + + Ring-modulate A1 and A2 + + + + + Modulate phase of A1 with output of A2 + + + + + Mix output of B2 to B1 + + + + + Modulate amplitude of B1 with output of B2 + + + + + Ring-modulate B1 and B2 + + + + + Modulate phase of B1 with output of B2 + + + + + + + + Draw your own waveform here by dragging your mouse on this graph. + 드래그하여 원하는 파형을 그리세요. + + + + Load waveform + 파형 불러오기 + + + + Click to load a waveform from a sample file + 샘플 파일에서 파형 가져오기 + + + + Phase left + 왼쪽 위상 + + + + Click to shift phase by -15 degrees + 위상을 -15도만큼 바꾸기 + + + + Phase right + 오른쪽 위상 + + + + Click to shift phase by +15 degrees + 위상을 +15도만큼 바꾸기 + + + + Normalize + 일반화 + + + + Click to normalize + 클릭하여 규격화 + + + + Invert + 파형 반전 + + + + Click to invert + 클릭하여 파형 반전 + + + + Smooth + 부드럽게 + + + + Click to smooth + 클릭하여 파형을 부드럽게 + + + + Sine wave + 사인파 + + + + Click for sine wave + 클릭하여 사인파 선택 + + + + + Triangle wave + 삼각파 + + + + Click for triangle wave + 클릭하여 삼각파 선택 + + + + Click for saw wave + 클릭하여 톱니파 선택 + + + + Square wave + 사각파 + + + + Click for square wave + 클릭하여 사각파 선택 + ZynAddSubFxInstrument + Portamento - + 포르타멘토 + Filter Frequency - + 필터 주파수 + Filter Resonance - + 필터 공명 + Bandwidth - + 대역폭 + FM Gain + Resonance Center Frequency + Resonance Bandwidth + Forward MIDI Control Change Events - + MIDI 컨트롤 변화(CC) 이벤트 전달 ZynAddSubFxView - Show GUI - - - - Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. - - - + Portamento: - + 포르타멘토: + PORT - + 포르타멘토 + Filter Frequency: - + 필터 주파수: + FREQ - + 주파수 + Filter Resonance: - + 필터 공명: + RES - + 공명 + Bandwidth: - + 대역폭: + BW - + 대역폭 + FM Gain: - + FM 이득: + FM GAIN - + FM 이득 + Resonance center frequency: - + 공명 중심 주파수: + RES CF + Resonance bandwidth: - + 공명 대역폭: + RES BW + Forward MIDI Control Changes - + MIDI 컨트롤 변화(CC) 전달 + + + + Show GUI + GUI 표시 + + + + Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. + 클릭하여 ZynAddSubFX의 GUI를 표시하거나 숨깁니다. audioFileProcessor + Amplify 증폭 + Start of sample 샘플 시작 + End of sample 샘플 끝 + + Loopback point + 루프 시작점 + + + Reverse sample 샘플 역으로 + + Loop mode + 루프 모드 + + + Stutter - Loopback point - - - - Loop mode - - - + Interpolation mode - + 보간법 + None - + 없음 + Linear - + 선형 + Sinc - + Sinc + Sample not found: %1 - + 샘플 %1을 찾을 수 없음 bitInvader + Samplelength 샘플 길이 @@ -7654,327 +9873,408 @@ Please make sure you have read-permission to the file and the directory containi bitInvaderView + Sample Length 샘플 길이 + + Draw your own waveform here by dragging your mouse on this graph. + 드래그하여 원하는 파형을 그리세요. + + + Sine wave - 사인 파형 + 사인파 + + Click for a sine-wave. + 클릭하여 사인파를 선택합니다. + + + Triangle wave - 삼각 파형 + 삼각파 + + Click here for a triangle-wave. + 클릭하여 삼각파를 선택합니다. + + + Saw wave - 톱니 파형 + 톱니파 + + Click here for a saw-wave. + 클릭하여 톱니파를 선택합니다. + + + Square wave - 사각 파형 + 사각파 + + Click here for a square-wave. + 클릭하여 사각파를 선택합니다. + + + White noise wave - 화이트 노이즈 파형 + 화이트 노이즈 + + Click here for white-noise. + 클릭하여 화이트 노이즈를 선택합니다. + + + User defined wave 사용자 정의 파형 + + Click here for a user-defined shape. + 클릭하여 사용자 지정 파형을 선택합니다. + + + Smooth 부드럽게 + Click here to smooth waveform. - 파형을 부드럽게 하기 위하여 여기를 클릭 + 클릭하여 파형을 부드럽게 합니다. + Interpolation - 내삽 + 보간 + Normalize - 일반화 - - - Draw your own waveform here by dragging your mouse on this graph. - - - - Click for a sine-wave. - 사인 파형을 위해 클릭. - - - Click here for a triangle-wave. - 삼각 파형을 위해 여기를 클릭 - - - Click here for a saw-wave. - 톱니 파형을 위해 여기를 클릭 - - - Click here for a square-wave. - 사각 파형을 위해 여기를 클릭 - - - Click here for white-noise. - 화이트 노이즈를 위해 여기를 클릭 - - - Click here for a user-defined shape. - 사용자 정의를 위해 여기를 클릭 + 규격화 dynProcControlDialog + INPUT - + 입력 + Input gain: - + 입력 이득: + OUTPUT - + 출력 + Output gain: - + 출력 이득: + ATTACK + Peak attack time: + RELEASE + Peak release time: + Reset waveform - + 파형 초기화 + Click here to reset the wavegraph back to default - + 클릭하여 기본 그래프로 초기화 + Smooth waveform - + 파형을 부드럽게 + Click here to apply smoothing to wavegraph + Increase wavegraph amplitude by 1dB + Click here to increase wavegraph amplitude by 1dB + Decrease wavegraph amplitude by 1dB + Click here to decrease wavegraph amplitude by 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 - + 입력 이득 + Output gain - + 출력 이득 + Attack time + Release time + Stereo mode - + 스테레오 모드 fxLineLcdSpinBox + Assign to: - + 채널 할당: + New FX Channel - + 새 FX 채널 graphModel + Graph - + 그래프 kickerInstrument + Start frequency 시작 주파수 + End frequency 끝 주파수 + + Length + 길이 + + + + Distortion Start + 디스토션 시작 값 + + + + Distortion End + 디스토션 끝 값 + + + Gain 이득 - Length - - - - Distortion Start - - - - Distortion End - - - + Envelope Slope + Noise 잡음 + Click + Frequency Slope + Start from note - + 음표 주파수에서 시작 + End to note - + 음표 주파수에서 마침 kickerInstrumentView + Start frequency: 시작 주파수: + End frequency: 끝 주파수: - Gain: - 이득: - - + Frequency Slope: - Envelope Length: - + + Gain: + 이득: + + Envelope Length: + 엔벨로프 길이: + + + Envelope Slope: + Click: + Noise: - + 잡음: + Distortion Start: - + 디스토션 시작 값: + Distortion End: - + 디스토션 끝 값: ladspaBrowserView + + Available Effects - 사용 가능 효과 + 사용 가능한 효과 + + Unavailable Effects 사용 불가능한 효과 + + Instruments 악기 + + Analysis Tools 분석 도구 + + Don't know 알 수 없음 + 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. @@ -7991,6 +10291,7 @@ Double clicking any of the plugins will bring up information on the ports. + Type: 형태: @@ -7998,10 +10299,12 @@ Double clicking any of the plugins will bring up information on the ports. ladspaDescription + Plugins 플러그인 + Description 요약 @@ -8009,66 +10312,83 @@ Double clicking any of the plugins will bring up information on the ports. ladspaPortDialog + Ports 포트 + Name 이름 + Rate - + 종류 + Direction 방향 + Type 형태 + Min < Default < Max 최소 < 기본 < 최대 + Logarithmic - + 로그 + SR Dependent SR 의존 + Audio 오디오 + Control - 제어 + 컨트롤 + Input 입력 + Output 출력 + Toggled 토글 + Integer 정수 + Float - 유동 + 실수 + + Yes @@ -8076,46 +10396,57 @@ Double clicking any of the plugins will bring up information on the ports. lb302Synth + VCF Cutoff Frequency - VCF Cutoff 주파수 + VCF 차단 주파수 + VCF Resonance VCF 공명 + VCF Envelope Mod - VCF 감싸기 모드 + VCF 엔벨로프 모드 + VCF Envelope Decay - VCF 감싸기 감쇄 + VCF 엔벨로프 감쇠 + Distortion - 왜곡 + 디스토션 + Waveform 파형 + Slide Decay 슬라이드 감소 + Slide 슬라이드 + Accent + Dead + 24dB/oct Filter 24dB/oct 필터 @@ -8123,241 +10454,301 @@ Double clicking any of the plugins will bring up information on the ports. lb302SynthView + Cutoff Freq: - Cutoff 주파수: + 차단 주파수: + Resonance: 공명: + Env Mod: - 환경 모드: + 엔벨로프 변조: + Decay: - 감쇄: + 감쇠: + 303-es-que, 24dB/octave, 3 pole filter + Slide Decay: - 슬라이드 감쇄: + 슬라이드 감쇠: + DIST: - + 디스토션: + Saw wave - 톱니 파형 + 톱니파 + Click here for a saw-wave. - 톱니 파형을 위해 여기를 클릭 + 클릭하여 톱니파를 선택합니다. + Triangle wave - 삼각 파형 + 삼각파 + Click here for a triangle-wave. - 삼각 파형을 위하여 여기를 클릭 + 클릭하여 삼각파를 선택합니다. + Square wave - 사각 파형 + 사각파 + Click here for a square-wave. - 사각 파형을 위하여 여기를 클릭 + 클릭하여 사각파를 선택합니다. + Rounded square wave - 둥근 사각 파형 + 둥근 사각파 + Click here for a square-wave with a rounded end. - 둥근 끝의 사가 파형을 위하여 여기를 클릭. + 클릭하여 둥근 사각파를 선택합니다. + Moog wave - + Moog 톱니파 + Click here for a moog-like wave. - + 클릭하여 Moog 톱니파를 선택합니다. + Sine wave - 사인 파형 + 사인파 + Click for a sine-wave. - 사인 파형을 위해 클릭 + 클릭하여 사인파를 선택합니다. + + White noise wave - 화이트 노이즈 파형 + 화이트 노이즈 + Click here for an exponential wave. - + 클릭하여 지수형 파형을 선택합니다. + Click here for white-noise. - 화이트 노이즈를 위해 여기를 클릭 + 클릭하여 화이트 노이즈를 선택합니다. + 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 - + 대역 제한 Moog 톱니파 + Click here for bandlimited moog saw wave. - + 클릭하여 대역 제한 Moog 톱니파를 선택합니다. malletsInstrument + Hardness + Position 위치 + Vibrato Gain 떨림 이득 + Vibrato Freq - 떨림 주파수 + 비브라토 주파수 + Stick Mix 스틱 믹스 + Modulator - 모듈레이트 + 모듈레이터 + Crossfade 크로스페이드 + LFO Speed LFO 속도 + LFO Depth - + LFO 깊이 + ADSR - + ADSR + Pressure 압력 + Motion 모션 + Speed 속도 + Bowed + Spread + Marimba 마림바 + Vibraphone - + 비브라폰 + Agogo - + 아고고 + Wood1 + Reso + Wood2 + Beats + Two Fixed + Clump + Tubular Bells + Uniform Bar + Tuned Bar + Glass - + 유리 + Tibetan Bowl @@ -8365,149 +10756,186 @@ Double clicking any of the plugins will bring up information on the ports. malletsInstrumentView + Instrument 악기 + Spread + Spread: - Hardness - - - - Hardness: - - - - Position - 위치 - - - Position: - 위치: - - - Vib Gain - - - - Vib Gain: - - - - Vib Freq - - - - Vib Freq: - - - - Stick Mix - 스틱 믹스 - - - Stick Mix: - - - - Modulator - 모듈레이트 - - - Modulator: - - - - Crossfade - 크로스페이드 - - - Crossfade: - - - - LFO Speed - LFO 속도 - - - LFO Speed: - - - - LFO Depth - - - - LFO Depth: - - - - ADSR - - - - ADSR: - - - - Pressure - 압력 - - - Pressure: - - - - Speed - 속도 - - - Speed: - - - + Missing files 없는 파일 + Your Stk-installation seems to be incomplete. Please make sure the full Stk-package is installed! + Stk 설치가 불완전한 것 같습니다. 완전한 Stk 패키지가 설치되었는지 확인하시기 바랍니다! + + + + Hardness + + + Hardness: + + + + + Position + 위치 + + + + Position: + 위치: + + + + Vib Gain + + + + + Vib Gain: + + + + + Vib Freq + + + + + Vib Freq: + + + + + Stick Mix + 스틱 믹스 + + + + Stick Mix: + + + + + Modulator + 모듈레이터 + + + + Modulator: + 모듈레이터: + + + + Crossfade + 크로스페이드 + + + + Crossfade: + 크로스페이드: + + + + LFO Speed + LFO 속도 + + + + LFO Speed: + LFO 속도: + + + + LFO Depth + LFO 깊이 + + + + LFO Depth: + LFO 깊이: + + + + ADSR + ADSR + + + + ADSR: + ADSR: + + + + Pressure + 압력 + + + + Pressure: + 압력: + + + + Speed + 속도 + + + + Speed: + 속도: + manageVSTEffectView + - VST parameter control + VST Sync - + VST와 동기화 + 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. @@ -8515,30 +10943,39 @@ Double clicking any of the plugins will bring up information on the ports. manageVestigeInstrumentView + + - VST plugin control + VST Sync - + VST와 동기화 + 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. @@ -8546,118 +10983,147 @@ Double clicking any of the plugins will bring up information on the ports. opl2instrument + Patch 패치 + Op 1 Attack + Op 1 Decay + Op 1 Sustain + Op 1 Release + Op 1 Level + Op 1 Level Scaling + Op 1 Frequency Multiple + Op 1 Feedback + 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 @@ -8665,18 +11131,26 @@ Double clicking any of the plugins will bring up information on the ports. opl2instrumentView + + Attack + + Decay + + Release + + Frequency multiplier @@ -8684,327 +11158,428 @@ Double clicking any of the plugins will bring up information on the ports. organicInstrument + Distortion - 왜곡 + 디스토션 + Volume - 볼륨 + 음량 organicInstrumentView + Distortion: - - - - Volume: - 볼륨: - - - Randomise - - - - Osc %1 waveform: - - - - Osc %1 volume: - - - - Osc %1 panning: - - - - cents - + 디스토션: + The distortion knob adds distortion to the output of the instrument. + + 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: + 오실레이터 %1 파형: + + + + Osc %1 volume: + 오실레이터 %1 음량: + + + + Osc %1 panning: + 오실레이터 %1 패닝: + + + Osc %1 stereo detuning + + cents + 센트 + + + Osc %1 harmonic: - + 오실레이터 %1 배음: papuInstrument + Sweep time + Sweep direction + Sweep RtShift amount + + Wave Pattern Duty + Channel 1 volume + + + Volume sweep direction + + + Length of each step in sweep + Channel 2 volume + Channel 3 volume + Channel 4 volume + + Shift Register width + + + + Right Output level + Left Output level + Channel 1 to SO2 (Left) + Channel 2 to SO2 (Left) + Channel 3 to SO2 (Left) + Channel 4 to SO2 (Left) + Channel 1 to SO1 (Right) + Channel 2 to SO1 (Right) + Channel 3 to SO1 (Right) + Channel 4 to SO1 (Right) + Treble + Bass - - Shift Register width - - papuInstrumentView + Sweep Time: + Sweep Time - Sweep RtShift amount: - - - - Sweep RtShift amount - - - - Wave pattern duty: - - - - Wave Pattern Duty - - - - Square Channel 1 Volume: - - - - Length of each step in sweep: - - - - Length of each step in sweep - - - - 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 - - - + 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 + + + + + + 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 @@ -9012,348 +11587,437 @@ Double clicking any of the plugins will bring up information on the ports. patchesDialog + Qsynth: Channel Preset + Bank selector + Bank 뱅크 + Program selector + Patch 패치 + Name 이름 + OK - + 확인 + Cancel - + 취소 pluginBrowser + no description - 요약 없음 + 설명 없음 - Incomplete monophonic imitation tb303 + + A native amplifier plugin + 내장 증폭기 플러그인 + + + + Simple sampler with various settings for using samples (e.g. drums) in an instrument-track - Plugin for freely manipulating stereo output + + Boost your bass the fast and simple way - Plugin for controlling knobs with sound peaks + + Customizable wavetable synthesizer - Plugin for enhancing stereo separation of a stereo input file + + An oversampling bitcrusher + + Carla Patchbay Instrument + + + + + Carla Rack Instrument + + + + + A 4-band Crossover Equalizer + + + + + A native delay plugin + 내장 딜레이 플러그인 + + + + A Dual filter plugin + + + + + plugin for processing dynamics in a flexible way + + + + + A native eq plugin + 내장 EQ 플러그인 + + + + A native flanger plugin + 내장 플랜저 플러그인 + + + + Player for GIG files + GIG 파일 플레이어 + + + + Filter for importing Hydrogen files into LMMS + Hydrogen 파일을 LMMS로 읽어오기 위한 필터 + + + + Versatile drum synthesizer + + + + List installed LADSPA plugins 설치된 LADSPA 플러그인 목록 - GUS-compatible patch instrument + + plugin for using arbitrary LADSPA-effects inside LMMS. + LMMS에서 LADSPA 이펙트를 이용하기 위한 플러그인. + + + + Incomplete monophonic imitation tb303 + + Filter for exporting MIDI-files from LMMS + MIDI 파일을 LMMS에서 내보내기 위한 필터 + + + + Filter for importing MIDI-files into LMMS + MIDI 파일을 LMMS로 읽어오기 위한 필터 + + + + Monstrous 3-oscillator synth with modulation matrix + + + + + A multitap echo delay plugin + + + + + A NES-like synthesizer + + + + + 2-operator FM Synth + + + + Additive Synthesizer for organ-like sounds - Tuneful things to bang on + + Emulation of GameBoy (TM) APU + GameBoy (TM) APU 에뮬레이션 + + + + GUS-compatible patch instrument - VST-host for using VST(i)-plugins within LMMS + + Plugin for controlling knobs with sound peaks - Vibrating string modeler + + Reverb algorithm by Sean Costello + Sean Costello의 리버브 알고리즘 + + + + Player for SoundFont files + 사운드폰트 파일 플레이어 + + + + LMMS port of sfxr - plugin for using arbitrary LADSPA-effects inside LMMS. - LMMS안에서 임의 LADSPA 효과를 이용하기 위한 플러그인 - - - Filter for importing MIDI-files into LMMS - 미디 파일을 LMMS로 읽어오기 위한 필터 - - + Emulation of the MOS6581 and MOS8580 SID. This chip was used in the Commodore 64 computer. - Player for SoundFont files - 소리 글꼴 파일을 위한 재생기 + + Graphical spectrum analyzer plugin + 그래픽 스펙트럼 분석 플러그인 - Emulation of GameBoy (TM) APU + + Plugin for enhancing stereo separation of a stereo input file - Customizable wavetable synthesizer + + Plugin for freely manipulating stereo output - Embedded ZynAddSubFX - - - - 2-operator FM Synth - - - - Filter for importing Hydrogen files into LMMS - - - - LMMS port of sfxr - - - - Monstrous 3-oscillator synth with modulation matrix + + Tuneful things to bang on + Three powerful oscillators you can modulate in several ways - A native amplifier plugin + + VST-host for using VST(i)-plugins within LMMS + LMMS의 VST(i) 플러그인 호스트 + + + + Vibrating string modeler - Carla Rack Instrument - + + plugin for using arbitrary VST effects inside LMMS. + LMMS에서 VST 이펙트를 이용하기 위한 플러그인. + 4-oscillator modulatable wavetable synth + plugin for waveshaping - Boost your bass the fast and simple way - - - - Versatile drum synthesizer - - - - Simple sampler with various settings for using samples (e.g. drums) in an instrument-track - - - - plugin for processing dynamics in a flexible way - - - - Carla Patchbay Instrument - - - - plugin for using arbitrary VST effects inside LMMS. - - - - Graphical spectrum analyzer plugin - - - - A NES-like synthesizer - - - - A native delay plugin - - - - Player for GIG files - - - - A multitap echo delay plugin - - - - A native flanger plugin - - - - An oversampling bitcrusher - - - - A native eq plugin - - - - A 4-band Crossover Equalizer - - - - A Dual filter plugin - - - - Filter for exporting MIDI-files from LMMS - + + Embedded ZynAddSubFX + 내장 ZynAddSubFX 플러그인 sf2Instrument + Bank 뱅크 + Patch 패치 + 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. - + 사운드폰트 %1을 불러올 수 없습니다. sf2InstrumentView + Open other SoundFont file - 다른 사운드끌꼴 파일 열기 + 다른 사운드폰트 파일 열기 + Click here to open another SF2 file - 다른 SF2 파일을 열기 위하여 여기를 클릭 + 클릭하여 다른 SF2 파일 열기 + 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) 음성글꼴2 파일 (*.sf2) @@ -9361,33 +12025,40 @@ This chip was used in the Commodore 64 computer. sfxrInstrument + Wave Form - + 파형 sidInstrument + Cutoff - + 컷오프 + Resonance 공명 + Filter type - 필터 형태 + 필터 종류 + Voice 3 off + Volume - 볼륨 + 음량 + Chip model 칩 모델 @@ -9395,134 +12066,172 @@ This chip was used in the Commodore 64 computer. sidInstrumentView + Volume: - 볼륨: + 음량: + Resonance: 공명: + + Cutoff frequency: - + 차단 주파수: + High-Pass filter 하이패스 필터 + Band-Pass filter 밴드패스 필터 + Low-Pass filter 로우패스 필터 + Voice3 Off + MOS6581 SID - + MOS6581 SID + MOS8580 SID - + MOS8580 SID + + Attack: + Attack rate determines how rapidly the output of Voice %1 rises from zero to peak amplitude. + + Decay: - 감쇄: + 감쇠: + Decay rate determines how rapidly the output falls from the peak amplitude to the selected Sustain level. + Sustain: + Output of Voice %1 will remain at the selected Sustain amplitude as long as the note is held. + + 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 잡음 + Sync - 동기 + 동기화 + 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 테스트 + Test, when set, resets and locks Oscillator %1 at zero until Test is turned off. @@ -9530,10 +12239,12 @@ This chip was used in the Commodore 64 computer. stereoEnhancerControlDialog + WIDE 넓게 + Width: 너비: @@ -9541,6 +12252,7 @@ This chip was used in the Commodore 64 computer. stereoEnhancerControls + Width 너비 @@ -9548,37 +12260,45 @@ This chip was used in the Commodore 64 computer. stereoMatrixControlDialog + Left to Left Vol: - 왼쪽에서 왼쪽 볼륨: + 왼쪽에서 왼쪽 음량: + Left to Right Vol: - 왼쪽에서 오른쪽 볼륨: + 왼쪽에서 오른쪽 음량: + Right to Left Vol: - 오른쪽에서 왼쪽 볼륨: + 오른쪽에서 왼쪽 음량: + Right to Right Vol: - 오른쪽에서 오른쪽 볼륨: + 오른쪽에서 오른쪽 음량: stereoMatrixControls + Left to Left 왼쪽에서 왼쪽 + Left to Right 왼쪽에서 오른쪽 + Right to Left 오른쪽에서 왼쪽 + Right to Right 오른쪽에서 오른쪽 @@ -9586,144 +12306,178 @@ This chip was used in the Commodore 64 computer. vestigeInstrument + Loading plugin 플러그인 읽는 중 + Please wait while loading VST-plugin... - VST 플러그인 읽은 동안 잠시 대기... + VST 플러그인을 읽을 동안 잠시 기다려 주세요... vibed + String %1 volume - + %1번 현 음량 + String %1 stiffness + Pick %1 position + Pickup %1 position - + 픽업 %1 위치 + Pan %1 - + %1번 패닝 + Detune %1 + Fuzziness %1 + Length %1 - 길이 %1 + %1번 길이 + Impulse %1 + Octave %1 - + 옥타브 %1 vibedView + Volume: - 볼륨: + 음량: + The 'V' knob sets the volume of the selected string. + 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: - 위치 지정: + + 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: - + 픽업 위치: + 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: - + 패닝: + The Pan knob determines the location of the selected string in the stereo field. + 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: + 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: 길이: + 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 - + 옥타브 + 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 Impulse 편집기 + 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. @@ -9734,6 +12488,7 @@ 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. @@ -9748,129 +12503,160 @@ The LED in the lower right corner of the waveform editor determines whether the + Enable waveform - + 파형 활성화 + Click here to enable/disable waveform. - + 클릭하여 파형 활성화/비활성화. + String + 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 - 사인 파형 - - - Triangle wave - 삼각 파형 - - - Saw wave - 톱니 파형 - - - Square wave - 사각 파형 - - - White noise wave - 화이트 노이즈 파형 - - - User defined wave - 사용자 정의 파형 - - - Smooth - 부드럽게 - - - Click here to smooth waveform. - 파형을 부드럽게 하기 위하여 여기를 클릭 - - - Normalize - 일반화 - - - Click here to normalize waveform. - + 사인파 + Use a sine-wave for current oscillator. - + 이 오실레이터에 사인파 사용 + + Triangle wave + 삼각파 + + + Use a triangle-wave for current oscillator. - + 이 오실레이터에 삼각파 사용 + + Saw wave + 톱니파 + + + Use a saw-wave for current oscillator. - + 이 오실레이터에 톱니파 사용 + + Square wave + 사각파 + + + Use a square-wave for current oscillator. - + 이 오실레이터에 사각파 사용 + + White noise wave + 화이트 노이즈 + + + Use white-noise for current oscillator. + + User defined wave + 사용자 정의 파형 + + + Use a user-defined waveform for current oscillator. - + 이 오실레이터에 사용자 지정 파형 사용 + + + + Smooth + 부드럽게 + + + + Click here to smooth waveform. + 클릭하여 파형을 부드럽게 합니다. + + + + Normalize + 규격화 + + + + Click here to normalize waveform. + 클릭하여 파형을 규격화합니다. voiceObject + Voice %1 pulse width - + 소리 %1 펄스 폭 + Voice %1 attack + Voice %1 decay + Voice %1 sustain + Voice %1 release + Voice %1 coarse detuning + Voice %1 wave shape 소리 %1 파형 + Voice %1 sync 소리 %1 동기화 + Voice %1 ring modulate - 소리 %1 링 조정 + 소리 %1 링 모듈레이션 + Voice %1 filtered 소리 %1 필터됨 + Voice %1 test 소리 %1 테스트 @@ -9878,58 +12664,72 @@ The LED in the lower right corner of the waveform editor determines whether the waveShaperControlDialog + INPUT - + 입력 + Input gain: - + 입력 이득: + OUTPUT - + 출력 + Output gain: - + 출력 이득: + Reset waveform - + 파형 초기화 + Click here to reset the wavegraph back to default - + 클릭하여 기본 그래프로 초기화 + Smooth waveform - + 파형을 부드럽게 + Click here to apply smoothing to wavegraph + Increase graph amplitude by 1dB + Click here to increase wavegraph amplitude by 1dB + Decrease graph amplitude by 1dB + Click here to decrease wavegraph amplitude by 1dB + Clip input - + 입력 신호 클리핑 + Clip input signal to 0dB @@ -9937,12 +12737,14 @@ The LED in the lower right corner of the waveform editor determines whether the waveShaperControls + Input gain - + 입력 이득 + Output gain - + 출력 이득 \ No newline at end of file diff --git a/data/locale/ru.ts b/data/locale/ru.ts index 37a19db0d..9946e5cfd 100644 --- a/data/locale/ru.ts +++ b/data/locale/ru.ts @@ -2,30 +2,62 @@ AboutDialog + About LMMS О программе LMMS + + LMMS + ЛММС + + + Version %1 (%2/%3, Qt %4, %5) Версия %1 (%2/%3, Qt %4, %5) + About Подробнее + LMMS - easy music production for everyone LMMS - лёгкое создание музыки для всех + + Copyright © %1 + Все права защищены © %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 Авторы + + Involved + Участники + + + + Contributors ordered by number of commits: + Разработчики сортированные по числу коммитов: + + + Translation Перевод + 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! @@ -36,61 +68,50 @@ Alexey Kouznetsov <alexey/dot/kouznetsov/at/gmail/dot/com> Oe Ai <oeai/at/symbiants/dot/com> + License Лицензия - - LMMS - ЛММС - - - Involved - Участники - - - Contributors ordered by number of commits: - Разработчики сортированные по числу коммитов: - - - Copyright © %1 - Все права защищены © %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> - - AmplifierControlDialog + VOL ГРОМ + Volume: Громкость: + PAN БАЛ + Panning: Баланс: + LEFT Лево + Left gain: Лево мощность: + RIGHT Право + Right gain: Право мощность: @@ -98,18 +119,22 @@ Oe Ai <oeai/at/symbiants/dot/com> AmplifierControls + Volume Громкость + Panning Баланс + Left gain Лево мощн + Right gain Право мощн @@ -117,10 +142,12 @@ Oe Ai <oeai/at/symbiants/dot/com> AudioAlsaSetupWidget + DEVICE УСТРОЙСТВО + CHANNELS КАНАЛЫ @@ -128,78 +155,98 @@ Oe Ai <oeai/at/symbiants/dot/com> AudioFileProcessorView + Open other sample Открыть другую запись + 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. Нажмите здесь, чтобы открыть другой звуковой файл. В новом окне диалога вы сможете выбрать нужный файл. Такие настройки, как режим повтора, точки начала/конца, усиление и прочие не сбросятся, поэтому звучание может отличаться от оригинала. + Reverse sample Отзеркалить запись + If you enable this button, the whole sample is reversed. This is useful for cool effects, e.g. a reversed crash. Если включить эту кнопку, вся запись пойдёт в обратную сторону, это удобно для крутых эффектов, типа обратного грохота. - Amplify: - Усиление: - - - 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!) - Эта ручка задаёт коэффициент усиления. При значении 100% исходный звук не меняется, в противном случае ― он будет ослаблен или усилен. (Обратите внимание, что исходная запись при этом останется нетронутой.) - - - Startpoint: - Начало: - - - Endpoint: - Конец: - - - Continue sample playback across notes - Продолжить воспроизведение записи по нотам - - - 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) - Включение этой опции продолжит воспроизведение записи по разным нотам - если изменить ускорение или длительность ноты остановится до конца записи, то со следующей ноты запись продолжится там, где остановилась, чтобы сбросить воспроизвдение на начало записи, вставьте ноту внизу у клавиш (<20 Гц) - - + Disable loop Отключить петлю + This button disables looping. The sample plays only once from start to end. - Эта кнопка отключает петлю (loop-цикл). Запись проигрывается только один раз от начала до конца. + Эта кнопка отключает зацикливание (loop-цикл). Запись проигрывается только один раз от начала до конца. + + Enable loop Включить петлю + This button enables forwards-looping. The sample loops between the end point and the loop point. Эта кнопка включает переднюю петлю. Сэмпл кольцуется между конечной точкой и точкой петли. + This button enables ping-pong-looping. The sample loops backwards and forwards between the end point and the loop point. Эта кнопка включает пинг-понг петлю. Сэмпл кольцуется обратно и вперёд между конечной точкой и точкой петли. + + Continue sample playback across notes + Продолжить воспроизведение записи по нотам + + + + 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) + Включение этой опции продолжит воспроизведение записи по разным нотам - если изменить ускорение или длительность ноты остановится до конца записи, то со следующей ноты запись продолжится там, где остановилась, чтобы сбросить воспроизвдение на начало записи, вставьте ноту внизу у клавиш (<20 Гц) + + + + Amplify: + Усиление: + + + + 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!) + Эта ручка задаёт коэффициент усиления. При значении 100% исходный звук не меняется, в противном случае ― он будет ослаблен или усилен. (Обратите внимание, что исходная запись при этом останется нетронутой.) + + + + Startpoint: + Начало: + + + With this knob you can set the point where AudioFileProcessor should begin playing your sample. Этим регулятором можно установить точку где АудиоФайлПроцессор должен начать воспроизведение сэмпла. + + Endpoint: + Конец: + + + With this knob you can set the point where AudioFileProcessor should stop playing your sample. Этот регулятор устанавливает точку в которой АудиоФайлПроцессор должен перестать воспроизвдение сэмпла. + Loopback point: Точка возврата петли: + With this knob you can set the point where the loop starts. Этот регулятор ставит точку начала петли. @@ -207,6 +254,7 @@ Oe Ai <oeai/at/symbiants/dot/com> AudioFileProcessorWaveView + Sample length: Длина записи: @@ -214,26 +262,32 @@ Oe Ai <oeai/at/symbiants/dot/com> AudioJack + JACK client restarted JACK-клиент перезапущен + 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 не был подключен к JACK по какой-то причине, поэтому LMMS подключение к JACK было перезапущено. Вам придётся заново вручную создать соединения. + JACK server down JACK-сервер не доступен + 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. Возможно JACK-сервер был выключен и запуск нового процесса не удался, поэтому ЛММС не может продолжить работу. Вам следует сохранить проект и перезапустить JACK и LMMS. + CLIENT-NAME ИМЯ КЛИЕНТА + CHANNELS КАНАЛЫ @@ -241,10 +295,12 @@ Oe Ai <oeai/at/symbiants/dot/com> AudioOss::setupWidget + DEVICE УСТРОЙСТВО + CHANNELS КАНАЛЫ @@ -252,10 +308,12 @@ Oe Ai <oeai/at/symbiants/dot/com> AudioPortAudio::setupWidget + BACKEND УПРАВЛЕНИЕ + DEVICE УСТРОЙСТВО @@ -263,10 +321,12 @@ Oe Ai <oeai/at/symbiants/dot/com> AudioPulseAudio::setupWidget + DEVICE УСТРОЙСТВО + CHANNELS КАНАЛЫ @@ -274,6 +334,7 @@ Oe Ai <oeai/at/symbiants/dot/com> AudioSdl::setupWidget + DEVICE УСТРОЙСТВО @@ -281,10 +342,12 @@ Oe Ai <oeai/at/symbiants/dot/com> AudioSndio::setupWidget + DEVICE УСТРОЙСТВО + CHANNELS КАНАЛЫ @@ -292,10 +355,12 @@ Oe Ai <oeai/at/symbiants/dot/com> AudioSoundIo::setupWidget + BACKEND БЭКЕНД + DEVICE УСТРОЙСТВО @@ -303,61 +368,75 @@ Oe Ai <oeai/at/symbiants/dot/com> AutomatableModel + &Reset (%1%2) &R Сбросить (%1%2) + &Copy value (%1%2) &C Копировать значение (%1%2) + &Paste value (%1%2) &P Вставить значение (%1%2) + Edit song-global automation Изменить глоабльную автоматизацию композиции - Connected to %1 - Подсоединено к %1 - - - Connected to controller - Подсоединено к контроллеру - - - Edit connection... - Настроить соединение... - - - Remove connection - Удалить соединение - - - Connect to controller... - Соединить с контроллером... - - + Remove song-global automation Убрать глобальную автоматизацию композиции + Remove all linked controls Убрать всё присоединенное управление + + + Connected to %1 + Подсоединено к %1 + + + + Connected to controller + Подсоединено к контроллеру + + + + Edit connection... + Настроить соединение... + + + + Remove connection + Удалить соединение + + + + Connect to controller... + Соединить с контроллером... + AutomationEditor + Please open an automation pattern with the context menu of a control! Откройте редатор автоматизации через контекстное меню регулятора! + Values copied Значения скопированы + All selected values were copied to the clipboard. Все выбранные значения скопированы в буфер обмена. @@ -365,144 +444,186 @@ Oe Ai <oeai/at/symbiants/dot/com> 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) Режим рисования (Shift+D) + Erase mode (Shift+E) Режим стирания (Shift-E) + Flip vertically Перевернуть вертикально + Flip horizontally Перевернуть горизонтально + Click here and the pattern will be inverted.The points are flipped in the y direction. Нажмите здесь и мелодия перевернётся. Точки переворачиваются в Y направлении. + Click here and the pattern will be reversed. The points are flipped in the x direction. Нажмите здесь и мелодия перевернётся в направлении 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. При нажатии на эту кнопку активируется режим рисования нот, в нём вы можете добавлять/перемещать и изменять длительность одиночных нот. Это основной режим и используется большую часть времени. Для включения этого режима можно использовать комбинацию клавиш Shift+D. + 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. При нажатии на эту кнопку активируется режим стирания. В этом режиме вы можете стирать ноты по одной. Для включения этого режима можно использовать комбинацию клавиш Shift+E. - 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. - Кубическая Эрмитова прогрессия для этого шаблона автоматизации. Кол-во подсоединенных объектов изменится по сглаженной кривой и смягчится на пиках и спадах. - - - Cut selected values (%1+X) - Вырезать выбранные ноты (%1+X) - - - Copy selected values (%1+C) - Копировать выбранные ноты в буфер (%1+C) - - - Paste values from clipboard (%1+V) - Вставить запомненные значения (%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. - При нажатии на эту кнопку ноты из буфера будут вставлены в первый видимый такт. - - - Tension: - Напряжение: - - - Automation Editor - no pattern - Редактор автоматизаци — нет шаблона - - - Automation Editor - %1 - Редактор автоматизации — %1 - - - Edit actions - Правка: - - + Interpolation controls Управление интерполяцией - Timeline 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) + Вырезать выбранные ноты (%1+X) + + + + Copy selected values (%1+C) + Копировать выбранные ноты в буфер (%1+C) + + + + Paste values from clipboard (%1+V) + Вставить запомненные значения (%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 + Редактор автоматизации — %1 + + + Model is already connected to this pattern. Модель уже подключена к этому шаблону. @@ -510,6 +631,7 @@ Oe Ai <oeai/at/symbiants/dot/com> AutomationPattern + Drag a control while pressing <%1> Тяните контроль удерживая <%1> @@ -517,46 +639,57 @@ Oe Ai <oeai/at/symbiants/dot/com> AutomationPatternView + double-click to open this pattern in automation editor Дважды щёлкните мышью чтобы настроить автоматизацию этого шаблона + Open in Automation editor Открыть в редакторе автоматизации + Clear Очистить + Reset name Сбросить название + Change name Переименовать - %1 Connections - Соединения %1 - - - Disconnect "%1" - Отсоединить «%1» - - + Set/clear record Установить/очистить запись + Flip Vertically (Visible) Перевернуть вертикально (Видимое) + Flip Horizontally (Visible) Перевернуть горизонтально (Видимое) + + %1 Connections + Соединения %1 + + + + Disconnect "%1" + Отсоединить «%1» + + + Model is already connected to this pattern. Модель уже подключена к этому шаблону. @@ -564,6 +697,7 @@ Oe Ai <oeai/at/symbiants/dot/com> AutomationTrack + Automation track Дорожка автоматизации @@ -571,77 +705,95 @@ Oe Ai <oeai/at/symbiants/dot/com> BBEditor + Beat+Bassline Editor Ритм+Бас Редактор + Play/pause current beat/bassline (Space) Игра/пауза текущей линии ритма/баса (<Space>) + Stop playback of current beat/bassline (Space) Остановить воспроизведение текущей линии ритм-баса (ПРОБЕЛ) + Click here to play the current beat/bassline. The beat/bassline is automatically looped when its end is reached. Нажмите чтобы проиграть текущую линию ритм-баса. Она будет закольцована по достижении окончания. + Click here to stop playing of current beat/bassline. Остановить воспроизведение (Пробел). - Add beat/bassline - Добавить ритм/бас - - - Add automation-track - Добавить дорожку автоматизации - - - Remove steps - Убрать такты - - - Add steps - Добавить такты - - + Beat selector Выбор бита + Track and step actions - + Действия для дорожки или ее части - Clone Steps - Клонировать такты + + Add beat/bassline + Добавить ритм/бас + Add sample-track Добавить дорожку записи + + + Add automation-track + Добавить дорожку автоматизации + + + + Remove steps + Убрать такты + + + + Add steps + Добавить такты + + + + Clone Steps + Клонировать такты + BBTCOView + Open in Beat+Bassline-Editor Открыть в редакторе ритм + баса + Reset name Сбросить название + Change name Переименовать + Change color Изменить цвет + Reset color to default Установить цвет по умолчанию @@ -649,10 +801,12 @@ Oe Ai <oeai/at/symbiants/dot/com> BBTrack + Beat/Bassline %1 Ритм-Бас Линия %1 + Clone of %1 Копия %1 @@ -660,26 +814,32 @@ Oe Ai <oeai/at/symbiants/dot/com> BassBoosterControlDialog + FREQ ЧАСТ + Frequency: Частота: + GAIN МОЩ + Gain: Мощность: + RATIO ОТН + Ratio: Отношение: @@ -687,14 +847,17 @@ Oe Ai <oeai/at/symbiants/dot/com> BassBoosterControls + Frequency Частота + Gain Мощность + Ratio Отношение @@ -702,82 +865,98 @@ Oe Ai <oeai/at/symbiants/dot/com> BitcrushControlDialog + IN - IN + ВХОД + OUT - OUT + ВЫХОД + + GAIN МОЩ + Input Gain: Входная мощность: - NOIS - ШУМ + + NOISE + Шум + Input Noise: Входной шум: + Output Gain: Выходная мощность: + CLIP - + СРЕЗ + Output Clip: - - - - Rate - Частота выборки + Выходная обрезка: + Rate Enabled - + Частота выборки включена + Enable samplerate-crushing - - - - Depth - Ёмкость + Включить дробление частоты дискретизации + Depth Enabled - + Глубина включена + Enable bitdepth-crushing - + Включить дробление битовой глубины + + FREQ + FREQ + + + Sample rate: Частота сэмплирования: - STD - + + STEREO + СТЕРЕО + Stereo difference: Стерео разница: - Levels - Уровни + + QUANT + КВАНТ + Levels: Уровни: @@ -785,10 +964,12 @@ Oe Ai <oeai/at/symbiants/dot/com> CaptionMenu + &Help &H Справка + Help (not available) Справка (не доступна) @@ -796,10 +977,12 @@ Oe Ai <oeai/at/symbiants/dot/com> CarlaInstrumentView + Show GUI Показать интерфейс + Click here to show or hide the graphical user interface (GUI) of Carla. Нажмите сюда, чтобы показать или скрыть графический интерфейс Карла. @@ -807,6 +990,7 @@ Oe Ai <oeai/at/symbiants/dot/com> Controller + Controller %1 Контроллер %1 @@ -814,58 +998,73 @@ Oe Ai <oeai/at/symbiants/dot/com> ControllerConnectionDialog + Connection Settings Параметры соединения + MIDI CONTROLLER MIDI-КОНТРОЛЛЕР + Input channel Канал ввода + CHANNEL КАНАЛ + Input controller Контроллер ввода + CONTROLLER КОНТРОЛЛЕР + + Auto Detect Автоопределение + MIDI-devices to receive MIDI-events from Устройства MiDi для приёма событий + USER CONTROLLER ПОЛЬЗ. КОНТРОЛЛЕР + MAPPING FUNCTION ПЕРЕОПРЕДЕЛЕНИЕ + OK ОК + Cancel Отменить + LMMS - ЛММС + LMMS + Cycle Detected. Обнаружен цикл. @@ -873,18 +1072,22 @@ Oe Ai <oeai/at/symbiants/dot/com> ControllerRackView + Controller Rack Рэка контроллеров + Add Добавить + Confirm Delete Подтвердить удаление + Confirm delete? There are existing connection(s) associated with this controller. There is no way to undo. Подтверждаете удаление? Есть возможные соединения с этим контроллером, возврата не будет. @@ -892,116 +1095,143 @@ Oe Ai <oeai/at/symbiants/dot/com> ControllerView + Controls Управление + Controllers are able to automate the value of a knob, slider, and other controls. Контроллеры могут автоматизировать изменения значений регуляторов, ползунков и прочего управления. + Rename controller Переименовать контроллер + Enter the new name for this controller Введите новое название для контроллера - &Remove this controller - - - - Re&name this controller - - - + LFO LFO + + + &Remove this controller + Убрать этот контроллер + + + + Re&name this controller + Переименовать этот контроллер + CrossoverEQControlDialog + Band 1/2 Crossover: - + Полоса 1/2 кроссовер: + Band 2/3 Crossover: - + Полоса 2/3 кроссовер: + Band 3/4 Crossover: - + Полоса 3/4 кроссовер: + Band 1 Gain: - + Полоса 1 усиление: + Band 2 Gain: - + Полоса 2 усиление: + Band 3 Gain: - + Полоса 3 усиление: + Band 4 Gain: - + Полоса 4 усиление: + Band 1 Mute - + Полоса 1 выключена + Mute Band 1 - + Заглушить полосу 1 + Band 2 Mute - + Полоса 2 выключена + Mute Band 2 - + Заглушить полосу 2 + Band 3 Mute - + Полоса 3 заглушена + Mute Band 3 - + Заглушить полосу 3 + Band 4 Mute - + Полоса 4 заглушена + Mute Band 4 - + Заглушить полосу 4 DelayControls + Delay Samples Задержка сэмплов + Feedback Возврат + Lfo Frequency - + Частота LFO + Lfo Amount - + Объём LFO + Output gain Выходная мощность @@ -1009,270 +1239,362 @@ Oe Ai <oeai/at/symbiants/dot/com> DelayControlsDialog - Lfo Amt - - - - Delay Time - - - - Feedback Amount - Объём возврата: - - - Lfo - - - - Out Gain - - - - Gain - Усиление - - + DELAY - + ЗАДЕРЖ + + Delay Time + Время задержки + + + FDBK - RATE - + + Feedback Amount + Объём возврата: + + RATE + ЧАСТ + + + + Lfo + Lfo + + + AMNT ГЛУБ + + + Lfo Amt + Вел LFO + + + + Out Gain + Выходная мощность + + + + Gain + Усиление + DualFilterControlDialog - Filter 1 enabled - Фильтр 1 включен - - - Filter 2 enabled - Фильтр 2 включен - - - Click to enable/disable Filter 1 - Кликнуть для включения/выключения Фильтра 1 - - - Click to enable/disable Filter 2 - Кликнуть для включения/выключения Фильтра 2 - - + + FREQ FREQ + + Cutoff frequency Срез частот + + RESO RESO + + Resonance Резонанс + + GAIN МОЩ + + Gain - Усиление + УСИЛ + MIX - + МИКС + Mix - + Микс + + + + Filter 1 enabled + Фильтр 1 включен + + + + Filter 2 enabled + Фильтр 2 включен + + + + Click to enable/disable Filter 1 + Кликнуть для включения/выключения Фильтра 1 + + + + Click to enable/disable Filter 2 + Кликнуть для включения/выключения Фильтра 2 DualFilterControls + Filter 1 enabled Фильтр 1 включен + Filter 1 type - + Фильтр 1 тип + Cutoff 1 frequency - + Срез 1 частоты + Q/Resonance 1 + Gain 1 - + Усиление 1 + Mix - + Микс + Filter 2 enabled Фильтр 2 включен + Filter 2 type - + Фильтр 2 тип + Cutoff 2 frequency - + Срез 2 частоты + Q/Resonance 2 + Gain 2 - + Усиление 2 + + LowPass Низ.ЧФ + + HiPass Выс.ЧФ + + BandPass csg Сред.ЧФ csg + + BandPass czpg Сред.ЧФ czpg + + Notch Полосно-заграждающий + + Allpass Все проходят + + Moog Муг + + 2x LowPass 2х Низ.ЧФ + + RC LowPass 12dB RC Низ.ЧФ 12дБ + + RC BandPass 12dB RC Сред.ЧФ 12 дБ + + RC HighPass 12dB RC Выс.ЧФ 12дБ + + RC LowPass 24dB RC Низ.ЧФ 24дБ + + RC BandPass 24dB RC Сред.ЧФ 24дБ + + RC HighPass 24dB RC Выс.ЧФ 24дБ + + Vocal Formant Filter Фильтр Вокальной форманты + + 2x Moog - + 2x Муг + + SV LowPass - + SV Низ.ЧФ + + SV BandPass - + SV Сред.ЧФ + + SV HighPass - + SV Выс.ЧФ + + SV Notch + + Fast Formant + + Tripole - + Триполи Editor + + Transport controls + Управление транспортом + + + Play (Space) Игра (Пробел) + Stop (Space) Стоп (Пробел) + Record Запись + Record while playing Запись при игре - - Transport controls - Управление транспортом - Effect + Effect enabled Эффект включён + Wet/Dry mix Насыщенность + Gate Шлюз + Decay Затихание @@ -1280,6 +1602,7 @@ Oe Ai <oeai/at/symbiants/dot/com> EffectChain + Effects enabled Эффекты включёны @@ -1287,10 +1610,12 @@ Oe Ai <oeai/at/symbiants/dot/com> EffectRackView + EFFECTS CHAIN ЦЕПЬ ЭФФЕКТОВ + Add effect Добавить эффект @@ -1298,22 +1623,28 @@ Oe Ai <oeai/at/symbiants/dot/com> EffectSelectDialog + Add effect Добавить эффект + + Name Имя + Type Тип + Description Описание + Author Автор @@ -1321,54 +1652,67 @@ Oe Ai <oeai/at/symbiants/dot/com> 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. Decay (затихание) управляет количеством буферов тишины, которые должны пройти до конца работы плагина. Меньшие величины снижают перегрузку процессора, но вознкает риск появления потрескивания или подрезания в хвосте на передержке (delay) или эхо (reverb) эффектах. + GATE ШЛЮЗ + Gate: Шлюз: + The Gate knob controls the signal level that is considered to be 'silence' while deciding when to stop processing signals. GATE (Шлюз) определяет уровень сигнала, который будет считаться "тишиной" при определении остановки обрабатывания сигналов. + 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. @@ -1398,14 +1742,17 @@ Right clicking will bring up a context menu where you can change the order in wh Контекстное меню, вызываемое щелчком правой кнопкой мыши, позволяет менять порядок следования фильтров или удалять их вместе с другими. + Move &up &u Переместить выше + Move &down &d Переместить ниже + &Remove this plugin &R Убрать фильтр @@ -1413,58 +1760,72 @@ Right clicking will bring up a context menu where you can change the order in wh EnvelopeAndLfoParameters + Predelay Задержка + Attack Вступление + Hold Удерживание + Decay Затихание + Sustain Выдержка + Release Убывание + Modulation Модуляция + LFO Predelay Задержка LFO + LFO Attack Вступление LFO + LFO speed Скорость LFO + LFO Modulation Модуляция LFO + LFO Wave Shape Форма сигнала LFO + Freq x 100 ЧАСТ x 100 + Modulate Env-Amount Модулировать огибающую @@ -1472,610 +1833,791 @@ Right clicking will bring up a context menu where you can change the order in wh EnvelopeAndLfoView + + DEL DEL + Predelay: Задержка: + 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: Вступление: + 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: Удержание: + 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: - Затихание: + Затухание: + 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: Выдержка: + 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: Убывание: + 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 AMT + + Modulation amount: Глубина модуляции: + 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: Пред. задержка 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 (LFO - НизкоЧастотный осциллятор (генератор)). Чем больше величина, тем больше времени до того как LFO начнёт работать. + LFO- 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. Используйте эту ручку для установления времени вступления этого LFO. Чем больше значение, тем дольше LFO нуждается в увеличении своей амплитуды до максимума. + SPD SPD + LFO speed: Скорость 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. Эта ручка устанавлявает скорость текущего LFO. Чем больше значение, тем быстрее LFO осциллирует и быстрее производится эффект. + 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. Эта ручка устанавливает глубину модуляции для текущего LFO. Чем больше значение, тем в большей степени выбранная характеристика (н-р, громкость или частота среза) будет зависеть от этого LFO. + Click here for a sine-wave. - Генерировать гармонический (синусоидальный) сигнал. + Синусоида. + Click here for a triangle-wave. Сгенерировать треугольный сигнал. + Click here for a saw-wave for current. Сгенерировать зигзагообразный сигнал. + Click here for a square-wave. - Сгенерировать квдратный сигнал (меандр) . + Сгенерировать квадрат. + Click here for a user-defined wave. Afterwards, drag an according sample-file onto the LFO graph. Задать свою форму сигнала. Впоследствии, перетащить соответствующий файл с записью в граф LFO. + + Click here for random wave. + Нажмите сюда для случайной волны. + + + FREQ x 100 ЧАСТОТА x 100 + Click here if the frequency of this LFO should be multiplied by 100. Нажмите, чтобы умножить частоту этого LFO на 100. + multiply LFO-frequency by 100 Умножить частоту LFO на 100 + MODULATE ENV-AMOUNT МОДУЛИР ОГИБАЮЩУЮ + Click here to make the envelope-amount controlled by this LFO. Нажмите сюда, чтобы глубина модуляции огибающей задавалась этим LFO. + control envelope-amount by this LFO Разрешить этому LFO задавать значение огибающей + ms/LFO: мс/LFO: + Hint Подсказка + Drag a sample from somewhere and drop it in this window. Перетащите в это окно какую-нибудь запись. - - Click here for random wave. - Нажмите сюда для случайной волны. - EqControls + Input gain Входная мощность + Output gain Выходная мощность + Low shelf gain - + Низкая ступень усиления + Peak 1 gain - + Пик 1 усиление + Peak 2 gain - + Пик 2 усиление + Peak 3 gain - + Пик 3 усиление + Peak 4 gain - + Пик 4 усиление + High Shelf gain - + Высокая степень усиления + HP res - + ВЧ резон + Low Shelf res - + Низкая ступень резон + Peak 1 BW - + Пик 1 BW + Peak 2 BW - + Пик 2 BW + Peak 3 BW - + Пик 3 BW + Peak 4 BW - + Пик 4 BW + High Shelf res - + Высокая ступень резон + LP res - + НЧ резон + HP freq - + НЧ част + Low Shelf freq - + Низкая степень част + Peak 1 freq - + Пик 1 част + Peak 2 freq - + Пик 2 част + Peak 3 freq - + Пик 3 част + Peak 4 freq - + Пик 4 част + High shelf freq - + Высокая ступень част + LP freq - + НЧ част + HP active - + ВЧ активна + Low shelf active - + Низкая ступень активна + Peak 1 active - + Пик 1 активен + Peak 2 active - + Пик 2 активен + Peak 3 active - + Пик 3 активен + Peak 4 active - + Пик 3 активен + High shelf active - + Высокая степень активна + LP active - + НЧ активна + LP 12 - + НЧ 12 + LP 24 - + НЧ 24 + LP 48 - + НЧ 48 + HP 12 - + ВЧ 12 + HP 24 - + ВЧ 24 + HP 48 - + ВЧ 48 + low pass type - + Тип нижних частот + high pass type - + Тип верхних частот + Analyse IN - + Анализировать ВХОД + Analyse OUT - + Анализировать ВЫХОД EqControlsDialog + HP - + ВЧ + Low Shelf - + Низкая ступень + Peak 1 - + Пик 1 + Peak 2 - + Пик 2 + Peak 3 - + Пик 3 + Peak 4 - + Пик 3 + High Shelf - + Высокая ступень + LP - + НЧ + In Gain - + Входная мощность + + + Gain Мощность + Out Gain - + Выходная мощность + Bandwidth: - + Полоса пропускания: + + Octave + Октава + + + Resonance : Резонанс: + Frequency: Частота: + lp grp - + нч grp + hp grp - - - - Octave - + вч grp EqHandle + Reso: - + Резон: + BW: - + BW + + Freq: - + Част: ExportProjectDialog + Export project Экспорт проекта + Output Вывод + File format: Формат файла: + Samplerate: Частота дискретизации: + 44100 Hz 44.1 КГц + 48000 Hz 48 КГц + 88200 Hz 88.2 КГц + 96000 Hz 96 КГц + 192000 Hz 192 КГц - Bitrate: - Частота бит: - - - 64 KBit/s - 64 КБит/с - - - 128 KBit/s - 128 КБит/с - - - 160 KBit/s - 160 КБит/с - - - 192 KBit/s - 192 КБит/с - - - 256 KBit/s - 256 КБит/с - - - 320 KBit/s - 320 КБит/с - - + Depth: Емкость: + 16 Bit Integer 16 Бит целое + + 24 Bit Integer + 24 бита целое + + + 32 Bit Float 32 Бит плавающая - Please note that not all of the parameters above apply for all file formats. - Заметьте, что не все параметры ниже будут применены для всех форматов файлов. + + Stereo mode: + Режим стерео: + + Stereo + Стерео + + + + Joint Stereo + Объединённое стерео + + + + Mono + Моно + + + + Bitrate: + Частота бит: + + + + 64 KBit/s + 64 КБит/с + + + + 128 KBit/s + 128 КБит/с + + + + 160 KBit/s + 160 КБит/с + + + + 192 KBit/s + 192 КБит/с + + + + 256 KBit/s + 256 КБит/с + + + + 320 KBit/s + 320 КБит/с + + + + Use variable bitrate + Использовать плавающую глубину битности + + + Quality settings Настройки качества + Interpolation: Интерполяция: + Zero Order Hold Нулевая задержка + Sinc Fastest Синхр. Быстрая + Sinc Medium (recommended) Синхр. Средняя (рекомендовано) + Sinc Best (very slow!) Синхр. лучшая (очень медленно!) + Oversampling (use with care!): Передискретизация (использовать осторожно!): + 1x (None) 1х (Нет) + 2x + 4x + 8x - Start - Начать - - - Cancel - Отменить - - + Export as loop (remove end silence) Экспортировать как петлю (убрать тишину в конце) + Export between loop markers Экспорт между метками петли + + Start + Начать + + + + Cancel + Отменить + + + 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! + Невозможно открыть файл %1 для записи. Пожалуйста, убедитесь, что у вас есть разрешение на запись в файл и содержащую его директорию, и попробуйте снова. + + + Export project to %1 Экспорт проекта в %1 + Error Ошибка + Error while determining file-encoder device. Please try to choose a different output format. Ошибка при определении кодека файла. Попробуйте выбрать другой формат вывода. + Rendering: %1% Обработка: %1% - - 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! - - Fader + + Please enter a new value between %1 and %2: Введите новое значение от %1 до %2: @@ -2083,6 +2625,7 @@ Please make sure you have write permission to the file and the directory contain FileBrowser + Browser Обозреватель файлов @@ -2090,123 +2633,151 @@ Please make sure you have write permission to the file and the directory contain FileBrowserTreeWidget + Send to active instrument-track Послать на активную инструментальную-дорожку - Open in new instrument-track/B+B Editor - Открыть в новой инструментальной дорожке/Б+Б редакторе - - - Loading sample - Загрузка записи - - - Please wait, loading sample for preview... - Пж. ждите, запись загружается для просмотра... - - - --- Factory files --- - --- Заводские файлы --- - - + Open in new instrument-track/Song Editor Отркрыть в новой инструментальной дорожке/редакторе песни + + Open in new instrument-track/B+B Editor + Открыть в новой инструментальной дорожке/Б+Б редакторе + + + + Loading sample + Загрузка записи + + + + Please wait, loading sample for preview... + Пж. ждите, запись загружается для просмотра... + + + Error Ошибка + does not appear to be a valid Не похоже на правильное + file - + файл + + + + --- Factory files --- + --- Заводские файлы --- FlangerControls + Delay Samples Задержка сэмплов + Lfo Frequency - + Частота LFO + Seconds Секунды + Regen + Noise Шум + Invert - + Инвертировать FlangerControlsDialog - Delay Time: - - - - Feedback Amount: - Объём возврата: - - - White Noise Amount: - Объём белого шума: - - + DELAY - + Задержка + + Delay Time: + Время задержки: + + + RATE - + ЧАСТ - Rate: - + + Period: + Период: + AMNT ГЛУБ + Amount: - + Величина: + FDBK - NOISE - + + Feedback Amount: + Объём возврата: + + NOISE + Шум + + + + White Noise Amount: + Объём белого шума: + + + Invert - + Инвертировать FxLine + Channel send amount Величина отправки канала + 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. @@ -2221,22 +2792,27 @@ You can remove and move FX channels in the context menu, which is accessed by ri + Move &left Двигать влево &L + Move &right Двигать вправо &r + Rename &channel Переименовать канал &c + R&emove channel Удалить канал &e + Remove &unused channels Удалить неиспользуемые каналы &u @@ -2244,37 +2820,62 @@ You can remove and move FX channels in the context menu, which is accessed by ri FxMixer + Master Главный + + + FX %1 Эффект %1 + + + Volume + Громкость + + + + Mute + Тихо + + + + Solo + Соло + FxMixerView + FX-Mixer Микшер Эффектов + FX Fader %1 + Mute Тихо + Mute this FX channel Заглушить этот канал ЭФ + Solo Соло + Solo FX channel Соло канал ЭФ @@ -2282,6 +2883,8 @@ You can remove and move FX channels in the context menu, which is accessed by ri FxRoute + + Amount to send from channel %1 to channel %2 Величина отправки с канала %1 на канал %2 @@ -2289,14 +2892,17 @@ You can remove and move FX channels in the context menu, which is accessed by ri GigInstrument + Bank Банк + Patch Патч + Gain Мощность @@ -2304,46 +2910,58 @@ You can remove and move FX channels in the context menu, which is accessed by ri GigInstrumentView + Open other GIG file Открыть другой GIG файл + Click here to open another GIG file Кликните сюда, чтобы открыть другой GIG файл + Choose the patch Выбрать патч + Click here to change which patch of the GIG file to use Нажмите здесь для смены используемого патча GIG файла + + Change which instrument of the GIG file is being played Изменить инструмент, который воспроизводит GIG файл + Which GIG file is currently being used Какой GIG файл сейчас используется + Which patch of the GIG file is currently being used Какой патч GIG файла сейчас используется + Gain - Мощность + УСИЛ + Factor to multiply samples by Фактор умножения сэмплов + Open GIG file Открыть GIG файл + GIG Files (*.gig) GIG Файлы (*.gig) @@ -2351,42 +2969,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. Рабочий каталог LMMS (%1) не существует. Создать его? Позже вы сможете сменить его через Правка -> Параметры. + Preparing UI Подготовка UI + Preparing song editor Подготовка редактора песни + Preparing mixer Подготовка микшера + Preparing controller rack Подготовка стойки управления + Preparing project notes Подготовка заметок проекта + Preparing beat/bassline editor Подготовка Ритм+Бас редактора + Preparing piano roll Подготовка редактора нот + Preparing automation editor Подготовка редактора автоматизации @@ -2394,650 +3022,814 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentFunctionArpeggio + Arpeggio Арпеджио + Arpeggio type Тип арпеджио + Arpeggio range Диапазон арпеджио - Arpeggio time - Период арпеджио - - - Arpeggio gate - Шлюз арпеджио - - - Arpeggio direction - Направление арпеджио - - - Arpeggio mode - Режим арпеджио - - - Up - Вверх - - - Down - Вниз - - - Up and down - Вверх и вниз - - - Random - Случайно - - - Free - Свободно - - - Sort - Упорядочить - - - Sync - Синхронизировать - - - Down and up - Вниз и вверх - - - Skip rate + + Cycle steps + + Skip rate + Частота пропуска + + + Miss rate - Cycle steps - + + Arpeggio time + Период арпеджио + + + + Arpeggio gate + Шлюз арпеджио + + + + Arpeggio direction + Направление арпеджио + + + + Arpeggio mode + Режим арпеджио + + + + Up + Вверх + + + + Down + Вниз + + + + Up and down + Вверх и вниз + + + + Down and up + Вниз и вверх + + + + Random + Случайно + + + + Free + Свободно + + + + Sort + Упорядочить + + + + Sync + Синхронизировать 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 RANGE + Arpeggio range: Диапазон арпеджио: + octave(s) Октав[а/ы] + Use this knob for setting the arpeggio range in octaves. The selected arpeggio will be played within specified number of octaves. Используйте эту ручку, чтобы установить диапазон арпеджио (в октавах). Выбранный тип арпеджио будет охватывать указанное количество октав. - TIME - TIME - - - Arpeggio time: - Период арпеджио: - - - ms - мс - - - Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. - Регулировка периода арпеджио - время (в миллисекундах), которое должен звучать каждый тон арпеджио. - - - GATE - GATE - - - 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: - Аккорд: - - - Direction: - Направление: - - - Mode: - Режим: - - - SKIP - - - - Skip rate: - - - - 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. - - - + CYCLE - + ЦИКЛ + Cycle notes: + note(s) + нота(ы) + + + + 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. - 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 + ПРОПУСК + + + + Skip rate: + Частота пропуска: + + + + + + % + % + + + + 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 + TIME + + + + Arpeggio time: + Период арпеджио: + + + + ms + мс + + + + Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. + Регулировка периода арпеджио - время (в миллисекундах), которое должен звучать каждый тон арпеджио. + + + + GATE + GATE + + + + 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: + Аккорд: + + + + Direction: + Направление: + + + + Mode: + Режим: + InstrumentFunctionNoteStacking + octave Октава + + Major Мажорный + Majb5 - + Majb5 + 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 - + Maj7 + Maj7b5 - + Maj7b5 + Maj7#5 - + Maj7#5 + Maj7#11 - + Maj7#11 + Maj7add13 - + Maj7add13 + m7 - + m7 + m7b5 - + m7b5 + m7b9 - + m7b9 + m7add11 - + m7add11 + m7add13 - + m7add13 + m-Maj7 - + m-Maj7 + m-Maj7add11 - + m-Maj7add11 + m-Maj7add13 - + m-Maj7add13 + 9 - + 9 + 9sus4 - + 9sus4 + add9 - + add9 + 9#5 - + 9#5 + 9b5 - + 9b5 + 9#11 - + 9#11 + 9b13 - + 9b13 + Maj9 - + Maj9 + Maj9sus4 - + Maj9sus4 + Maj9#5 - + Maj9#5 + Maj9#11 - + Maj9#11 + m9 - + m9 + madd9 - + madd9 + m9b5 - + m9b5 + m9-Maj7 - + m9-Maj7 + 11 - + 11 + 11b9 - + 11b9 + Maj11 - + Maj11 + m11 - + m11 + m-Maj11 - + m-Maj11 + 13 - + 13 + 13#9 - + 13#9 + 13b9 - + 13b9 + 13b5b9 - + 13b5b9 + Maj13 - + Maj13 + m13 - + m13 + m-Maj13 - + m-Maj13 + Harmonic minor - + Гармонический минор + Melodic minor - + Мелодический минор + Whole tone - + Целый тон + Diminished - + Пониженный + Major pentatonic - + Мажорная пентатоника + Minor pentatonic - + Минорная пентатоника + Jap in sen + Major bebop + Dominant bebop + Blues - + Blues + Arabic - + Арабский + Enigmatic + Neopolitan - + Неополитанский + Neopolitan minor - + Неополитанский минор + Hungarian minor + Dorian - + Дорийский - Phrygolydian - + + Phrygian + Фригийский + Lydian - + Лидийский + Mixolydian - + Миксолидийский + Aeolian - + Эолийский + Locrian - Chords - Аккорды - - - Chord type - Тип аккорда - - - Chord range - Диапазон аккорда - - + Minor + Chromatic - + Хроматический + Half-Whole Diminished + 5 - + 5 + Phrygian dominant + Persian + + + Chords + Аккорды + + + + Chord type + Тип аккорда + + + + Chord range + Диапазон аккорда + InstrumentFunctionNoteStackingView - RANGE - ДИАП - - - Chord range: - Диапазон аккорда: - - - octave(s) - Октав[а/ы] - - - Use this knob for setting the chord range in octaves. The selected chord will be played within specified number of octaves. - Эта ручка изменяет диапазон аккорда, который будет содержать указанное число октав. - - + STACKING СТЫКОВКА + Chord: Аккорд: + + + RANGE + ДИАП + + + + Chord range: + Диапазон аккорда: + + + + octave(s) + Октав[а/ы] + + + + 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 ВКЛ MIDI ВВОД + + CHANNEL CHANNEL + + VELOCITY VELOCITY + ENABLE MIDI OUTPUT ВКЛ MIDI ВЫВОД + PROGRAM PROGRAM - MIDI devices to receive MIDI events from - MiDi устройства-источники событий - - - MIDI devices to send MIDI events to - MiDi устройства для отправки событий на них - - + NOTE NOTE + + MIDI devices to receive MIDI events from + MiDi устройства-источники событий + + + + MIDI devices to send MIDI events to + MiDi устройства для отправки событий на них + + + CUSTOM BASE VELOCITY ПРОИЗВОЛЬНАЯ БАЗОВАЯ СКОРОСТЬ + Specify the velocity normalization base for MIDI-based instruments at 100% note velocity Определяет базовую скорость нормализации для MiDi инструментов при громкости ноты 100% + BASE VELOCITY БАЗОВАЯ СКОРОСТЬ @@ -3045,10 +3837,12 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentMiscView + MASTER PITCH - + Мастер-высота + Enables the use of Master Pitch Включает использование основной тональности @@ -3056,178 +3850,222 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentSoundShaping + VOLUME VOLUME + Volume Громкость + CUTOFF CUTOFF + + Cutoff frequency Срез частоты + RESO RESO + Resonance Резонанс + Envelopes/LFOs Огибание/LFO + Filter type Тип фильтра + Q/Resonance + LowPass Низ.ЧФ + HiPass Выс.ЧФ + BandPass csg Сред.ЧФ csg + BandPass czpg Сред.ЧФ czpg + Notch Полосно-заграждающий + Allpass Все проходят + Moog Муг + 2x LowPass 2х Низ.ЧФ + RC LowPass 12dB RC Низ.ЧФ 12дБ + RC BandPass 12dB RC Сред.ЧФ 12 дБ + RC HighPass 12dB RC Выс.ЧФ 12дБ + RC LowPass 24dB RC Низ.ЧФ 24дБ + RC BandPass 24dB RC Сред.ЧФ 24дБ + RC HighPass 24dB RC Выс.ЧФ 24дБ + Vocal Formant Filter Фильтр Вокальной форманты + 2x Moog - + 2x Муг + SV LowPass - + SV Низ.ЧФ + SV BandPass - + SV Сред.ЧФ + SV HighPass - + SV Выс.ЧФ + SV Notch + Fast Formant + Tripole - + Триполи InstrumentSoundShapingView + TARGET ЦЕЛЬ + 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...! Эта вкладка позволяет вам настроить огибающие. Они очень важны для настройки звучания. Например, с помощью огибающей громкости вы можете задать зависимость громкости звучания от времени. Если вам понадобится эмулировать мягкие струнные, просто задайте больше времени нарастания и исчезновения звука. С помощью обгибающих и низкочастотного осцилятора (LFO) вы в несколько щелчков мыши сможете создать просто невероятные звуки! + 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. Здесь вы можете выбрать фильтр для дорожки этого инструмента. Фильтры могут довольно сильно менять звучание. - 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: - Резонанс: - - - 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. - Эта ручка задаёт количество резонанса для фильтра, этим определяется насколько нужно усилить ближайшие к отрезанным частоты. - - + FREQ ЧАСТ + cutoff frequency: Срез частот: + + 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: + Усиление: + + + + 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. Огибающие, LFO и фильтры не поддерживаются этим инструментом. @@ -3235,85 +4073,107 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentTrack - unnamed_track - безымянная_дорожка - - - Volume - Громкость - - - Panning - Стерео - - - Pitch - Тональность - - - FX channel - Канал ЭФ - - - Default preset - Основная предустановка - - + With this knob you can set the volume of the opened channel. Регулировка громкости текущего канала. + + + unnamed_track + безымянная_дорожка + + + Base note Опорная нота + + Volume + Громкость + + + + Panning + Стерео + + + + Pitch + Тональность + + + Pitch range Диапазон тональности + + FX channel + Канал ЭФ + + + Master Pitch - + Основная тональность + + + + + Default preset + Основная предустановка InstrumentTrackView + Volume Громкость + Volume: Громкость: + VOL ГРОМ + Panning Баланс + Panning: Баланс: + PAN БАЛ + MIDI MIDI + Input Вход + Output Выход + FX %1: %2 ЭФ %1: %2 @@ -3321,125 +4181,160 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentTrackWindow + GENERAL SETTINGS ОСНОВНЫЕ НАСТРОЙКИ - Instrument volume - Громкость инструмента - - - Volume: - Громкость: - - - VOL - ГРОМ - - - Panning - Баланс - - - Panning: - Стереобаланс: - - - PAN - БАЛ - - - Pitch - Тональность - - - Pitch: - Тональность: - - - cents - процентов - - - PITCH - ТОН - - - FX channel - Канал ЭФ - - - ENV/LFO - ОГИБ/LFO - - - FUNC - ФУНКЦ - - - FX - ЭФ - - - MIDI - MIDI - - - Save preset - Сохранить предустановку - - - XML preset file (*.xpf) - XML файл настроек (*.xpf) - - - PLUGIN - ПЛАГИН - - - Pitch range (semitones) - Диапазон тональности (полутона) - - - RANGE - ДИАП - - - 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. - Нажать здесь, чтобы сохранить настройки текущей инстр. дорожки в файл предустановок. Позже можно загрузить эту предустановку двойным кликом в браузере предустановок. - - - MISC - РАЗН - - + 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 + Параметры MIDI + + + + Miscellaneous + Разное + + + + Save preset + Сохранить предустановку + + + + XML preset file (*.xpf) + XML файл настроек (*.xpf) + + + + Plugin + Модуль + Knob + Set linear Установить линейно + Set logarithmic Установить логарифмически + Please enter a new value between -96.0 dBFS and 6.0 dBFS: - + Введите новое значение от –96,0 дБВ до 6,0 дБВ: + Please enter a new value between %1 and %2: Введите новое значение от %1 до %2: @@ -3447,6 +4342,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaControl + Link channels Связать каналы @@ -3454,10 +4350,12 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaControlDialog + Link Channels Связать каналы + Channel Канал @@ -3465,14 +4363,17 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaControlView + Link channels Связать каналы + Value: Значение: + Sorry, no help available. Извините, справки нет. @@ -3480,6 +4381,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaEffect + Unknown LADSPA plugin %1 requested. Запрошен неизвестный модуль LADSPA «%1». @@ -3487,6 +4389,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri LcdSpinBox + Please enter a new value between %1 and %2: Введите новое значение от %1 до %2: @@ -3494,18 +4397,26 @@ You can remove and move FX channels in the context menu, which is accessed by ri LeftRightNav + + + Previous Предыдущий + + + Next Следующий + Previous (%1) Предыдущий (%1) + Next (%1) Следующий (%1) @@ -3513,30 +4424,37 @@ You can remove and move FX channels in the context menu, which is accessed by ri LfoController + LFO Controller Контроллер LFO + Base value Основное значение + Oscillator speed Скорость волны + Oscillator amount Размер волны + Oscillator phase Фаза волны + Oscillator waveform Форма волны + Frequency Multiplier Множитель частоты @@ -3544,115 +4462,142 @@ You can remove and move FX channels in the context menu, which is accessed by ri LfoControllerDialog + LFO LFO + LFO Controller Контроллер LFO + BASE БАЗА + Base amount: - Кол-во базы: + Базовое значение: + todo доделать + SPD СКОР + LFO-speed: Скорость LFO: + Use this knob for setting speed of the LFO. The bigger this value the faster the LFO oscillates and the faster the effect. Эта ручка устанавлявает скорость LFO. Чем больше значение, тем больше частота осциллятора. + + AMNT + ГЛУБ + + + Modulation amount: Количество модуляции: + 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. Эта ручка устанавливает глубину модуляции для LFO. Чем больше значение, тем в большей степени выбранная характеристика (н-р, громкость или частота среза) будет зависеть от ГНЧ(LFO). + PHS ФАЗА + Phase offset: Сдвиг фазы: + degrees градусы + 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. Эта ручка устанавливает начальную фазу НизкоЧастотного Осциллятора (LFO), т. е. точку, с которой осциллятор начинает вырабатывать сигнал. Например, если вы задали синусоидальную форму сигнала и начальную фазу 180º, волна сначала пойдёт вниз, а не вверх, так же как и для квадратной волны. + Click here for a sine-wave. Синусоида. + Click here for a triangle-wave. - Треугольник. + Сгенерировать треугольный сигнал. + Click here for a saw-wave. - Зигзаг. + Сгенерировать зигзаг. + Click here for a square-wave. - Квадрат. + Сгенерировать квадрат. + + Click here for a moog saw-wave. + Нажать здесь для зигзагообразной муг волны. + + + Click here for an exponential wave. - Экспонента. + Генерировать экспоненциальный сигнал. + Click here for white-noise. - Белый шум. + Сгенерировать белый шум. + Click here for a user-defined shape. Double click to pick a file. Нажмите здесь для определения своей формы. Двойное нажатие для выбора файла. - - Click here for a moog saw-wave. - Нажать здесь для зигзагообразной муг волны. - - - AMNT - ГЛУБ - LmmsCore + Generating wavetables Генерация волн + Initializing data structures Инициализация структуры данных + Opening audio and midi devices Открываем аудио и миди устройства + Launching mixer threads Запускаем потоки микшера @@ -3660,408 +4605,502 @@ Double click to pick a file. MainWindow - Could not save config-file - Не могу сохранить настройки + + Configuration file + Файл настроек - Could not save configuration file %1. You're probably not permitted to write to this file. -Please make sure you have write-access to the file and try again. - Не могу записать настройки в файл %1. Возможно, вы не обладаете правами на запись в него. -Пожалуйста, проверьте свои права и попробуйте снова. + + Error while parsing configuration file at line %1:%2: %3 + Ошибка во время обработки файла настроек в строке %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! + Невозможно открыть файл %1 для записи. Пожалуйста, убедитесь, что у вас есть разрешение на запись в файл и содержащую его директорию, и попробуйте снова. + + + + 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? + Остался файл для восстановления. Похоже последняя сессия не была нормально завершена или запущен ещё один процесс LMMS. +Хотите восстановить проект из этой сессии? + + + + + + 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 + Версия %1 + + + + Preparing plugin browser + Подготовка обзора плагинов + + + + Preparing file browsers + Подготовка обзора файлов + + + + My Projects + Мои проекты + + + + My Samples + Мои сэмплы + + + + My Presets + Мои предустановки + + + + My Home + Моя домашняя папка + + + + Root directory + Корневая директория + + + + Volumes + Громкость 1 оциллятора + + + + My Computer + Мой компьютер + + + + Loading background artwork + Загружаем фоновый рисунок + + + + &File + &F Файл + + + &New &N Новый + + New from template + Новый на основе шаблона + + + &Open... &Открыть... + + &Recently Opened Projects + &R Недавние проекты + + + &Save &S Сохранить + Save &As... &A Сохранить как... + + Save as New &Version + &V Сохранить как новую версию + + + + Save as default template + Сохранить как обычный шаблон + + + Import... Импорт... + E&xport... &X Экспорт... + + E&xport Tracks... + &x Экспорт дорожек... + + + + Export &MIDI... + Экспорт &MIDI... + + + &Quit &Q Выйти + &Edit &E Правка + + Undo + Откатить действие + + + + Redo + Возврат действия + + + Settings Параметры + + &View + &Просмотр + + + &Tools &T Сервис + &Help &H Справка + + Online Help + Помощь онлайн + + + Help Справка - What's this? + + What's This? Что это? + About О программе + Create new project Создать новый проект + Create new project from template Создать новый проект по шаблону + Open existing project Открыть существующий проект + Recently opened projects Недавние проекты + Save current project Сохранить текущий проект + Export current project Экспорт проекта - Song Editor + + What's this? + Что это? + + + + Toggle metronome + Включить метроном + + + + Show/hide Song-Editor Показать/скрыть музыкальный редактор + 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. Сим запускается или скрывается музыкальный редактор. С его помощью вы можете редактировать композицию и задавать время воспроизведения каждой дорожки. Также вы можете вставлять и передвигать записи прямо в списке воспроизведения. - Beat+Bassline Editor - Показать/скрыть ритм-бас редактор + + Show/hide Beat+Bassline Editor + Показать/скрыть Ритм+Бас редактор + 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. Сим запускается ритм-бас редактор. Он необходим для установки ритма, открытия, добавления и удаления каналов, а также вырезания, копирования и вставки ритм-бас шаблонов, мелодий и т. п. - Piano Roll - Показать/скрыть нотный редактор + + Show/hide Piano-Roll + Показать/Скрыть Редактор Нот + Click here to show or hide the Piano-Roll. With the help of the Piano-Roll you can edit melodies in an easy way. Запуск редатора нот. С его помощью вы можете легко редактировать мелодии. - Automation Editor + + Show/hide Automation Editor Показать/скрыть редактор автоматизации + 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. Показать/скрыть окно редактора автоматизации. С его помощью вы можете легко редактироватьдинамику выбранных величин. - FX Mixer + + Show/hide 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. Скрыть/показать микшер ЭФфектов. Он является мощным инструментом для управления эффектами. Вы можете вставлять эффекты в различные каналы. - Project Notes - Показать/скрыть заметки к проекту + + Show/hide project notes + Показать/скрыть заметки проекта + Click here to show or hide the project notes window. In this window you can put down your project notes. Эта кнопка показывает/прячет окно с заметками. В этом окне вы можете помещать любые комментарии к своей композиции. - Controller Rack + + Show/hide controller rack Показать/скрыть управление контроллерами + Untitled Неназванный + + Recover session. Please save your work! + Восстановление сессии. Пожалуйста, сохраните свою работу! + + + LMMS %1 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) + 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. Пока что справка для LMMS не написана. Вероятно, Вы сможете найти нужные материалы на http://lmms.sf.net/wiki . - LMMS (*.mmp *.mmpz) - LMMS (*.mmp *.mmpz) - - - Version %1 - Версия %1 - - - Configuration file - Файл настроек - - - Error while parsing configuration file at line %1:%2: %3 - Ошибка во время обработки файла настроек в строке %1:%2: %3 - - - Volumes - - - - Undo - Откатить действие - - - Redo - Возврат действия - - - My Projects - Мои проекты - - - My Samples - Мои сэмплы - - - My Presets - Мои предустановки - - - My Home - Моя домашняя папка - - - My Computer - Мой компьютер - - - &File - &F Файл - - - &Recently Opened Projects - &R Недавние проекты - - - Save as New &Version - &V Сохранить как новую версию - - - E&xport Tracks... - &x Экспорт дорожек... - - - Online Help - Помощь онлайн - - - What's This? - Что это? - - - Open Project - Открыть проект - - - Save Project - Сохранить проект - - - 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? - Остался файл для восстановления. Похоже последняя сессия не была нормально завершена или запущен ещё один процесс LMMS. -Хотите восстановить проект из этой сессии? - - - Recover - Восстановить - - - Recover the file. Please don't run multiple instances of LMMS when you do this. - Восстановить файл. Пожалуйства, не запускайте несколько процессов ЛММС во время этого. - - - Ignore - Игнорировать - - - Launch LMMS as usual but with automatic backup disabled to prevent the present recover file from being overwritten. - Запуск ЛММС как обычно, но с отключенным автоматическим восстановлением, чтобы предотвратить перезапись текущего файла восстановления. - - - Discard - Отказать - - - Launch a default session and delete the restored files. This is not reversible. - Запустить обычную сессию и удалить восстановленные файлы. Это безвозвратно. - - - Preparing plugin browser - Подготовка обзора плагинов - - - Preparing file browsers - Подготовка обзора файлов - - - Root directory - Корневая директория - - - Loading background artwork - Загружаем фоновый рисунок - - - New from template - - - - Save as default template - Сохранить как обычный шаблон - - - &View - - - - Toggle metronome - Включить метроном - - - Show/hide Song-Editor + + Song Editor Показать/скрыть музыкальный редактор - Show/hide Beat+Bassline Editor - Показать/скрыть Ритм+Бас редактор + + Beat+Bassline Editor + Показать/скрыть ритм-бас редактор - Show/hide Piano-Roll - Показать/Скрыть Редактор Нот + + Piano Roll + Показать/скрыть нотный редактор - Show/hide Automation Editor + + Automation Editor Показать/скрыть редактор автоматизации - Show/hide FX Mixer + + FX Mixer Показать/скрыть микшер ЭФ - Show/hide project notes - Показать/скрыть заметки проекта + + Project Notes + Показать/скрыть заметки к проекту - Show/hide controller rack + + Controller Rack Показать/скрыть управление контроллерами - Recover session. Please save your work! - Восстановление сессии. Пожалуйста, сохраните свою работу! - - - Automatic backup disabled. Remember to save your work! - Автоматическое сохранение отключено. Не забудьте сохранять свои работы! - - - 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? - Проект был восстановлен из предыдущей сессии. Сейчас он не сохранён и будет потерян, если его не сохранить. -Хотите сохранить его сейчас? - - - LMMS Project - ЛММС Проект - - - LMMS Project Template - Шаблон ЛММС Проекта - - - Overwrite default template? - Перезаписать обычный шаблон? - - - This will overwrite your current default template. - Это перезапишет текущий обычный шаблон. - - + Volume as dBFS + Smooth scroll Плавная прокрутка + Enable note labels in piano roll Включить обозначение нот в музыкальном редакторе - - Save project template - - MeterDialog + + Meter Numerator Шкала чисел + + Meter Denominator Шкала делений + TIME SIG ПЕРИОД @@ -4069,10 +5108,12 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MeterModel + Numerator Числитель + Denominator Знаменатель @@ -4080,10 +5121,12 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MidiController + MIDI Controller Контроллер MIDI + unnamed_midi_controller нераспознанный миди контроллер @@ -4091,86 +5134,105 @@ 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. Вы не установили SoundFont по умолчанию в параметрах (Правка->Настройки), поэтому после импорта миди файла звук воспроизводиться не будет. Вам следует загрузить основной MiDi SoundFont, указать его в параметрах и попробовать снова. + 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. Вы не включили поддержку проигрывателя SoundFont2 при компиляции ЛММС, он используется для добавления основного звука в импортируемые Миди файлы, поэтому звука не будет после импорта этого миди файла. + Track - + Дорожка MidiJack + JACK server down When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (title) JACK-сервер не доступен + The JACK server seems to be shuted down. When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (dialog message) - + JACK-сервер, похоже, не запущен. MidiPort + Input channel Вход + Output channel Выход + Input controller Контроллер входа + Output controller Контроллер выхода + Fixed input velocity Постоянная скорость ввода + Fixed output velocity Постоянная скорость вывода - Output MIDI program - Программа для вывода MiDi - - - Receive MIDI-events - Принимать события MIDI - - - Send MIDI-events - Отправлять события MIDI - - + Fixed output note Постоянный вывод нот + + Output MIDI program + Программа для вывода MiDi + + + Base velocity Базовая скорость + + + Receive MIDI-events + Принимать события MIDI + + + + Send MIDI-events + Отправлять события MIDI + MidiSetupWidget + DEVICE УСТРОЙСТВО @@ -4178,474 +5240,595 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MonstroInstrument + Osc 1 Volume - + Осциллятор 1 громкость + Osc 1 Panning - + Осциллятор 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 - + Осциллятор 2 громкость + Osc 2 Panning - + Осциллятор 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 - + Осциллятор 3 громкость + Osc 3 Panning - + Осциллятор 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 + LFO 1 Attack + LFO 1 Rate + LFO 1 Phase + LFO 2 Waveform + LFO 2 Attack + LFO 2 Rate + LFO 2 Phase + Env 1 Pre-delay + Env 1 Attack + 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 - + Кривая 2 Наклон + Osc2-3 modulation + Selected view - + Выбранный вид + Vol1-Env1 + Vol1-Env2 + Vol1-LFO1 + Vol1-LFO2 + Vol2-Env1 + Vol2-Env2 + Vol2-LFO1 + Vol2-LFO2 + Vol3-Env1 + Vol3-Env2 + Vol3-LFO1 + Vol3-LFO2 + Phs1-Env1 + Phs1-Env2 + Phs1-LFO1 + Phs1-LFO2 + Phs2-Env1 + Phs2-Env2 + Phs2-LFO1 + Phs2-LFO2 + Phs3-Env1 + Phs3-Env2 + Phs3-LFO1 + Phs3-LFO2 + Pit1-Env1 + Pit1-Env2 + Pit1-LFO1 + Pit1-LFO2 + Pit2-Env1 + Pit2-Env2 + Pit2-LFO1 + Pit2-LFO2 + Pit3-Env1 + Pit3-Env2 + Pit3-LFO1 + Pit3-LFO2 + PW1-Env1 + PW1-Env2 + PW1-LFO1 + PW1-LFO2 + Sub3-Env1 + Sub3-Env2 + Sub3-LFO1 + Sub3-LFO2 + + Sine wave Синусоида + Bandlimited Triangle wave Ограниченная по частоте треугольная волна + Bandlimited Saw wave Ограниченная по частоте острая волна + Bandlimited Ramp wave - + Ограничение по частоте ниспадающая волна + Bandlimited Square wave Ограниченная по частоте квадратная волна + Bandlimited Moog saw wave - Ограниченная по частоте Муг острая волна + Ограниченная по частоте Муг-зигзаг волна + + Soft square wave Сглаженная квадратная волна + Absolute sine wave + + Exponential wave Экспоненциальная волна + White noise Белый шум + Digital Triangle wave Цифровая треугольная волна + Digital Saw wave Цифровая острая волна + Digital Ramp wave + Digital Square wave Цифровая квадратная волна + Digital Moog saw wave Цифровая Муг острая волна + Triangle wave Треугольная волна + Saw wave Зигзаг + Ramp wave + Square wave Квадрат + Moog saw wave + Abs. sine wave + Random Случайно + Random smooth Случайное сглаживание @@ -4653,10 +5836,12 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MonstroView + Operators view Операторский вид + 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. @@ -4665,10 +5850,12 @@ Knobs and other widgets in the Operators view have their own what's this -t Регуляторы и другие виджеты в Операторском виде имеют свои подписи "Что это?", можно получить по ним более детальную справку таким образом. + Matrix view Матричный вид + 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. @@ -4681,80 +5868,266 @@ Each modulation target has 4 knobs, one for each modulator. By default the knobs Каждая цель модуляции имеет 4 регулятора, один на каждый модулятор. По умолчанию регуляторы установлены на 0, то есть без модуляции. Включая регулятор на 1 ведёт к тому, что модулятор влияет на цель модуляции на столько на сколько возможно. Включая его на -1 делает то же, но с обратной модуляцией. + + + + Volume + Громкость + + + + + + Panning + Баланс + + + + + + Coarse detune + Грубая расстройка + + + + + + semitones + полутона + + + + + Finetune left + + + + + + + + cents + + + + + + 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 + Вступление + + + + + Rate + Частота выборки + + + + + Phase + + + + + + Pre-delay + Пре-дилэй + + + + + Hold + Удерживание + + + + + Decay + Затихание + + + + + Sustain + Выдержка + + + + + Release + Убывание + + + + + Slope + Фронт + + + Mix Osc2 with Osc3 Смешать Осц2 с Осц3 + Modulate amplitude of Osc3 with Osc2 Модулировать амплитуду осциллятора 3 сигналом с осц2 + Modulate frequency of Osc3 with Osc2 Модулировать частоту осциллятора 3 сигналом с осц2 + Modulate phase of Osc3 with Osc2 Модулировать фазу Осц3 осциллятором2 + The CRS knob changes the tuning of oscillator 1 in semitone steps. Регулятор CRS меняет настройку осциллятора 1 в размере полутона. + The CRS knob changes the tuning of oscillator 2 in semitone steps. Регулятор CRS меняет настройку осциллятора 2 в размере полутона. + The CRS knob changes the tuning of oscillator 3 in semitone steps. Регулятор CRS меняет настройку осциллятора 3 в размере полутона. + + + + 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. FTL и FTR меняют подстройку осциллятора для левого и правого канала соответственно. Они могут добавить стерео расстраивания осциллятора, которое расширяет стерео картину и создаёт иллюзию космоса. + + + The SPO knob modifies the difference in phase between left and right channels. Higher difference creates a wider stereo image. Регулятор SPO меняет фазовую разницу между левым и правым каналами. Высокая разница создаёт более широкую стерео картину. + 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. PW регулятор контролирует ширину пульсаций, также известную как рабочий цикл осциллятора 1. Осциллятор 1 это цифровой импульсный волновой генератор, он не воспроизводит сигнал с ограниченной полосой, это значит, что его можно использовать как слышимый осциллятор, но приведёт к наложению сигналов (или сглаживанию). Его можно использовать и как не слышимый источник синхронизирующего сигнала, для использования в синхронизации осцилляторов 2 и 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. Посылать синхронизацию при повышении: при включении, сигнал синхронизации посылается каждый раз когда состояние осциллятора 1 меняется с низкого на высокое, т.е. когда амплитуда меняется от -1 до 1. Тон осциллятора 1, фаза и ширина пульсаций может влиять на время синхронизации, но громкость не имеет эффекта. Сигнал синхронизации посылается независимо для левого и правого каналов. + 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. Посылать синхронизацию при падении: при включении, сигнал синхронизации посылается каждый раз когда состояние осциллятора 1 меняется с выского на низкое, т.е. когда амплитуда меняется от 1 до -1. Тон осциллятора 1, фаза и ширина пульсаций может влиять на время синхронизации, но громкость не имеет эффекта. Сигнал синхронизации посылается независимо для левого и правого каналов. + + Hard sync: Every time the oscillator receives a sync signal from oscillator 1, its phase is reset to 0 + whatever its phase offset is. Жесткая синхр. : Каждый раз при получении осциллятором сигнала синхронизации от осциллятора 1, его фаза сбрасывается до 0 + его граница фазы, какой бы она ни была. + + Reverse sync: Every time the oscillator receives a sync signal from oscillator 1, the amplitude of the oscillator gets inverted. Обратная синхронизация: Каждый раз при получении сигнала синхронизации от осциллятора 1, амплитуда осцилятора переворачивается. + Choose waveform for oscillator 2. Выбрать форму волны для осциллятора 2. + Choose waveform for oscillator 3's first sub-osc. Oscillator 3 can smoothly interpolate between two different waveforms. Выберите форму волны для первого доп. осциллятора осциллятора 3. Осциллятор 3 может мягко переходить между двумя разными волнами. + Choose waveform for oscillator 3's second sub-osc. Oscillator 3 can smoothly interpolate between two different waveforms. Выберите форму волны для второго доп. осциллятора осциллятора 3. Осциллятор 3 может мягко переходить между двумя разными волнами. + 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. SUB меняет смешивание двух доп. осяцилляторов осциллятора 3. Каждый доп. осц. может быть установлен для создания разных волн и осциллятор 3 может мягко переходить между ними. Все входящие модуляции для осциллятора 3 применяются на оба доп.осц./волны одним и тем же образом. + 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. @@ -4763,6 +6136,7 @@ Mix mode means no modulation: the outputs of the oscillators are simply mixed to Смешанный (Mix) режим значит без модуляции: выходы осцилляторов просто смешиваются друг с другом. + 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. @@ -4771,6 +6145,7 @@ AM means amplitude modulation: Oscillator 3's amplitude (volume) is modulat AM режим значит Амплитуда Модуляции: Осциллятор 2 модулирует амплитуду (громкость) осциллятора 3. + 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. @@ -4779,6 +6154,7 @@ FM means frequency modulation: Oscillator 3's frequency (pitch) is modulate FM (ЧМ) режим значит Частотная Модуляция: Осциллятор 2 модулирует частоту (pitch, тональность) осциллятора 3. Частота модуляции происходит в фазе модуляции, которая даёт более стабильный общий тон, чем "чистая" частотная модуляция. + 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. @@ -4787,6 +6163,7 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PM (ФМ) режим значит фазовая модуляция: Осциллятор 2 модулирует фазу осциллятора 3. Это отличается от частотной модуляции тем, что изменения фаз не суммируются. + 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... Выберите форму волны для LFO 1 (НизкоЧастотныйГенератор). @@ -4794,6 +6171,7 @@ PM (ФМ) режим значит фазовая модуляция: Осцил Сглаженная версия переходит между этими состояниями с косинусоидальной интерплояцией. Эти случайные режимы могут быть использованы, чтобы дать "жизни" вашим настройкам - добавить немного аналоговой непредсказуемости... + 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... Выберите форму волны для LFO 2 (НизкоЧастотныйГенератор). @@ -4801,150 +6179,110 @@ PM (ФМ) режим значит фазовая модуляция: Осцил Сглаженная версия переходит между этими состояниями с косинусоидальной интерплояцией. Эти случайные режимы могут быть использованы, чтобы дать "жизни" вашим настройкам - добавить немного аналоговой непредсказуемости... + + Attack causes the LFO to come on gradually from the start of the note. Атака отвечает за плавность поведения LFO от начала ноты. + + Rate sets the speed of the LFO, measured in milliseconds per cycle. Can be synced to tempo. Rate (Частота) устанавливает скорость LFO, измеряемую в миллисекундах за цикл. Может синхронизироваться с темпом. + + PHS controls the phase offset of the LFO. PHS контролирует сдвиг фазы LFO (НЧГ). + + PRE, or pre-delay, delays the start of the envelope from the start of the note. 0 means no delay. PRE предзадержка, задерживает старт огибающей от начала ноты. 0 значит без задержки. + + ATT, or attack, controls how fast the envelope ramps up at start, measured in milliseconds. A value of 0 means instant. ATT атака контролирует как быстро огибающая наращивается на старте, измеряясь в милисекундах. Значение 0 значит мгновенно. + + HOLD controls how long the envelope stays at peak after the attack phase. HOLD (УДЕРЖ) контролирует как долго огибающая остаётся на пике после фазы атаки. + + 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. DEC (decay) затухание контролирует как быстро огибающая спадает с пикового значения, измеряется в милисекундах, как долго будет идти с пика до нуля. Реальное затухание может быть короче, если используется выдержка. + + 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. SUS (sustain) выдержка, контролирует уровень огибающей. Затухание фазы не пойдёт ниже этого уровня пока нота удерживается. + + 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. REL (release) отпуск контролирует как долго нота отпускается, измеряясь в долготе падения от пика до нуля. Реальный отпуск может быть короче, в зависимости от фазы, в которой нота отпущена. + + 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. Регулятор наклона контролирует кривую или образ огибающей. Значение 0 создаёт прямые подъёмы и спады. Отрицательные величины создают кривые с замедленным началом, быстрым пиком и снова замедленным спадом. Позитивные значения создают кривые которые начинаются и кончаются быстро, но долбше остаются на пиках. - Volume - Громкость - - - Panning - Баланс - - - Coarse detune - - - - semitones - полутона - - - Finetune left - - - - cents - - - - 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 - Вступление - - - Rate - Частота выборки - - - Phase - - - - Pre-delay - - - - Hold - Удерживание - - - Decay - Затихание - - - Sustain - Выдержка - - - Release - Убывание - - - Slope - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Modulation amount Глубина модуляции @@ -4952,34 +6290,42 @@ PM (ФМ) режим значит фазовая модуляция: Осцил MultitapEchoControlDialog + Length Длина + Step length: - + Длина шага: + Dry - + Высушить + Dry Gain: + Stages + Lowpass stages: + Swap inputs - + Переставить входы местами + Swap left and right input channel for reflections Поменять вход левого и правого канала для отзвуков @@ -4987,82 +6333,102 @@ PM (ФМ) режим значит фазовая модуляция: Осцил NesInstrument + Channel 1 Coarse detune - + Канал 1 - грубая расстройка + Channel 1 Volume Громкость 1 канала + Channel 1 Envelope length - + Канал 1 - Длина огибающей + Channel 1 Duty cycle + Channel 1 Sweep amount + Channel 1 Sweep rate + Channel 2 Coarse detune + Channel 2 Volume Громкость 2 канала + Channel 2 Envelope length + Channel 2 Duty cycle + Channel 2 Sweep amount + Channel 2 Sweep rate + Channel 3 Coarse detune + Channel 3 Volume Громкость 3 канала + Channel 4 Volume Громкость 4 канала + Channel 4 Envelope length + Channel 4 Noise frequency + Channel 4 Noise frequency sweep + Master volume Основная громкость + Vibrato Вибрато @@ -5070,114 +6436,155 @@ PM (ФМ) режим значит фазовая модуляция: Осцил NesInstrumentView + + + + Volume Громкость + + + Coarse detune - + Грубая расстройка + + + Envelope length - + Длина огибающей + Enable channel 1 - + Включить канал 1 + Enable envelope 1 - + Включить кривую 1 + Enable envelope 1 loop + Enable sweep 1 + + Sweep amount - + Амплитуда биений + + Sweep rate - + Частота биений + + 12.5% Duty cycle - + 12.5% Рабочий цикл + + 25% Duty cycle - + 25% Рабочий цикл + + 50% Duty cycle - + 50% Рабочий цикл + + 75% Duty cycle - + 75% Рабочий цикл + Enable channel 2 - + Включить канал 2 + Enable envelope 2 - + Включить кривую 2 + Enable envelope 2 loop - + Включить повтор кривой 2 + Enable sweep 2 + Enable channel 3 + Noise Frequency - + Частота шума + Frequency sweep + Enable channel 4 + Enable envelope 4 + Enable envelope 4 loop + Quantize noise frequency when using note frequency + Use note frequency for noise - + Использовние частоты ноты для шума + Noise mode - + Режим шума + Master Volume - + Мастер-громкость + Vibrato Вибрато @@ -5185,81 +6592,103 @@ PM (ФМ) режим значит фазовая модуляция: Осцил OscillatorObject - Osc %1 volume - Громкость осциллятора %1 - - - Osc %1 panning - Стереобаланс для осциллятора %1 - - - Osc %1 coarse detuning - Подстройка осциллятора %1 грубая - - - Osc %1 fine detuning left - Подстройка левого канала осциллятора %1 тонкая - - - Osc %1 fine detuning right - Подстройка правого канала осциллятора %1 тонкая - - - Osc %1 phase-offset - Сдвиг фазы для осциллятора %1 - - - Osc %1 stereo phase-detuning - Подстройка стерео-фазы осциллятора %1 - - - Osc %1 wave shape - Гладкость сигнала осциллятора %1 - - - Modulation type %1 - Тип модуляции %1 - - + Osc %1 waveform Форма сигнала осциллятора %1 + Osc %1 harmonic Осц %1 гармонический + + + + Osc %1 volume + Громкость осциллятора %1 + + + + + Osc %1 panning + Стереобаланс для осциллятора %1 + + + + + Osc %1 fine detuning left + Подстройка левого канала осциллятора %1 тонкая + + + + Osc %1 coarse detuning + Подстройка осциллятора %1 грубая + + + + Osc %1 fine detuning right + Подстройка правого канала осциллятора %1 тонкая + + + + Osc %1 phase-offset + Сдвиг фазы для осциллятора %1 + + + + Osc %1 stereo phase-detuning + Подстройка стерео-фазы осциллятора %1 + + + + Osc %1 wave shape + Гладкость сигнала осциллятора %1 + + + + Modulation type %1 + Тип модуляции %1 + PatchesDialog + Qsynth: Channel Preset + Bank selector - + Выбор банка + Bank Банк + Program selector Выбор программ + Patch Патч + Name Имя + OK ОК + Cancel Отмена @@ -5267,46 +6696,57 @@ PM (ФМ) режим значит фазовая модуляция: Осцил PatmanView + Open other patch Открыть другой патч + Click here to open another patch-file. Loop and Tune settings are not reset. Нажмите чтобы открыть другой патч-файл. Цикличность и настройки при этом сохранятся. + Loop Повтор + Loop mode Режим повтора + Here you can toggle the Loop mode. If enabled, PatMan will use the loop information available in the file. Здесь включается/выключается режим повтора, при включёнии PatMan будет использовать информацию о повторе из файла. + Tune Подстроить + Tune mode Тип подстройки + Here you can toggle the Tune mode. If enabled, PatMan will tune the sample to match the note's frequency. Здесь включается/выключается режим подстройки. Если он включён, то PatMan изменит запись так, чтобы она совпадала по частоте с нотой. + No file selected Не выбран файл + Open patch file Открыть патч-файл + Patch-Files (*.pat) Патч-файлы (*.pat) @@ -5314,38 +6754,47 @@ PM (ФМ) режим значит фазовая модуляция: Осцил PatternView - Open in piano-roll - Открыть в редакторе нот - - - Clear all notes - Очистить все ноты - - - Reset name - Сбросить название - - - Change name - Переименовать - - - Add steps - Добавить такты - - - Remove steps - Удалить такты - - + use mouse wheel to set velocity of a step + double-click to open in Piano Roll Двойной щелчок открывает в Редакторе Нот + + Open in piano-roll + Открыть в редакторе нот + + + + Clear all notes + Очистить все ноты + + + + Reset name + Сбросить название + + + + Change name + Переименовать + + + + Add steps + Добавить такты + + + + Remove steps + Удалить такты + + + Clone Steps Клонировать такты @@ -5353,14 +6802,17 @@ PM (ФМ) режим значит фазовая модуляция: Осцил 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. Из-за ошибки в старой версии LMMS контроллеры вершин не могут правильно подключаться. Пж. убедитесь, что контроллеры вершин правильно подсоединены и пересохраните этот файл, извините, за причинённые неудобства. @@ -5368,10 +6820,12 @@ PM (ФМ) режим значит фазовая модуляция: Осцил PeakControllerDialog + PEAK ПИК + LFO Controller Контроллер LFO @@ -5379,307 +6833,383 @@ PM (ФМ) режим значит фазовая модуляция: Осцил PeakControllerEffectControlDialog + BASE БАЗА + Base amount: Базовое значение: - Modulation amount: - Глубина модуляции: - - - Attack: - Вступление: - - - Release: - Убывание: - - + AMNT ГЛУБ + + Modulation amount: + Глубина модуляции: + + + MULT МНОЖ + Amount Multiplicator: Величина множителя: + ATCK ВСТУП + + Attack: + Вступление: + + + DCAY СПАД - Treshold: - + + Release: + Убывание: + TRSH - + ПОР + + + + Treshold: + Порог: PeakControllerEffectControls + Base value Опорное значение + Modulation amount Глубина модуляции - Mute output - Заглушить вывод - - + Attack Вступление + Release Убывание + + Treshold + Порог + + + + Mute output + Заглушить вывод + + + Abs Value Абс значение + Amount Multiplicator Величина множителя - - Treshold - - PianoRoll - Please open a pattern by double-clicking on it! - Откройте мелодию с помощью двойного щелчка мышью! - - - Last note - По посл. ноте - - - Note lock - Фиксация нот - - + Note Velocity Громкость нот + Note Panning Стереофония нот + Mark/unmark current semitone Отметить/Снять отметку с текущего полутона - Mark current scale - Отметить текущий подъём - - - Mark current chord - Отметить текущий аккорд - - - Unmark all - Снять выделение - - - No scale - Без подъёма - - - No chord - Убрать аккорды - - - Velocity: %1% - Громкость %1% - - - Panning: %1% left - Баланс: %1% лево - - - Panning: %1% right - Баланс: %1% право - - - Panning: center - Баланс: центр - - - Please enter a new value between %1 and %2: - Введите новое значение от %1 до %2: - - + 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% + Громкость %1% + + + + Panning: %1% left + Баланс: %1% лево + + + + Panning: %1% right + Баланс: %1% право + + + + Panning: center + Баланс: центр + + + + Please open a pattern by double-clicking on it! + Откройте мелодию с помощью двойного щелчка мышью! + + + + + Please enter a new value between %1 and %2: + Введите новое значение от %1 до %2: + PianoRollWindow + Play/pause current pattern (Space) Игра/Пауза текущей мелодии (Пробел) + Record notes from MIDI-device/channel-piano Записать ноты с музыкального инструмента (MIDI)/канала + Record notes from MIDI-device/channel-piano while playing song or BB track Записать ноты с цифрового музыкального инструмента (MIDI) во время воспроизведения композиции или дорожки Ритм-Баса + 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. Нажмите эту кнопку, если вы хотите записать ноты с устройства MIDI или виртуального синтезатора соответствующего канала. Позже вы сможете отредактировать записанную мелодию. + 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. Нажмите эту кнопку, если вы хотите записать ноты с устройства MIDI или виртуального синтезатора соответствующего канала. Во время записи все ноты записываются в эту мелодию, и вы будете слышать композицию или РБ дорожку на заднем плане. + Click here to stop playback of current pattern. Нажмите здесь, если вы хотите остановить воспроизведение текущей мелодии. + + Edit actions + Правка: + + + Draw mode (Shift+D) Режим рисования (Shift+D) + Erase mode (Shift+E) Режим стирания (Shift+E) + Select mode (Shift+S) Режим выбора нот (Shift+S) - Detune mode (Shift+T) - Режим подстраивания (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. Режим рисования нот, в нём вы можете добавлять/перемещать и изменять длительность одиночных нот. Это режим по умолчанию и используется большую часть времени. Для включения этого режима можно использовать комбинацию клавиш Shift+D, удерживайте %1 для временного переключения в режим выбора. + 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. Режим стирания. В этом режиме вы можете стирать ноты. Для включения этого режима можно использовать комбинацию клавиш Shift+E. + 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. Режим выделения. В этом режиме можно выделять ноты, можно также удерживать %1 в режиме рисования, чтобы можно было на время войти в режим выделения. - 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. - Режим подстройки. В этом режиме можно выбирать ноты для автоматизации их подстраивания. Можно использовать это для переходов нот от одной к другой. Для активации с клавиатуры <Shift+T>. + + Pitch Bend mode (Shift+T) + - Cut selected notes (%1+X) - Переместить выделенные ноты в буфер (%1+X) + + 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. + Нажмите здесь для активации Pitch Blend режима. Вы сможете кликнуть на ноту, чтобы начать автоматическией детюн. Можно использовать это для "скольжения" от одной ноты к другой. Можно включить этот режим при помощи Shift + T. - Copy selected notes (%1+C) - Копировать выделенные ноты в буфер (%1+X) - - - Paste notes from clipboard (%1+V) - Вставить ноты из буфера (%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. - При нажатии на эту кнопку ноты из буфера будут вставлены в первый видимый такт. - - - 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. - "Q" обозначает квантизацию и контролирует размер нотной сетки и контрольные точки притяжения. С меньшей величиной квантизации, можно рисовать короткие ноты в редаторе нот и более точно контролировать точки в Редакторе Автоматизации. - - - 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 - Позволяет выбрть длину новой ноты. "Последняя Нота" значит, что LMMS будет использовать длину ноты, изменённой в последний раз - - - 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! - Функция напрямую связана с контекстным меню на виртуальной клавиатуре слева в нотном редакторе. После того, как выбран масштаб в выпадающем меню, можно кликнуть правой кнопкой в виртуальной клавиатуре и выбрать "Mark Current Scale" (Отметить текущий масштаб). LMMS подсветит все ноты лежащие в выбранном масштабе для выбранной клавиши! - - - 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. - Позволяет выбрать аккорд, который LMMS затем сможет нарисовать или подсветить. В этом меню можно найти ниболее популярные аккорды. После того, как вы выбрали аккорд, кликните в любом месте, чтобы поставить его и правым кликом по виртуальной клавиатуре открывается контекстное меню и подсветка аккорда. Для возврата в режим одной ноты нужно выбрать "Без аккорда" в этом выпадающем меню. - - - Edit actions - Правка: + + Quantize + + Copy paste controls Копировать-вставить управление + + Cut selected notes (%1+X) + Переместить выделенные ноты в буфер (%1+X) + + + + Copy selected notes (%1+C) + Копировать выделенные ноты в буфер (%1+X) + + + + Paste notes from clipboard (%1+V) + Вставить ноты из буфера (%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. + "Q" обозначает квантизацию и контролирует размер нотной сетки и контрольные точки притяжения. С меньшей величиной квантизации, можно рисовать короткие ноты в редаторе нот и более точно контролировать точки в Редакторе Автоматизации. + + + + 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 + Позволяет выбрть длину новой ноты. "Последняя Нота" значит, что LMMS будет использовать длину ноты, изменённой в последний раз + + + + 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! + Функция напрямую связана с контекстным меню на виртуальной клавиатуре слева в нотном редакторе. После того, как выбран масштаб в выпадающем меню, можно кликнуть правой кнопкой в виртуальной клавиатуре и выбрать "Mark Current Scale" (Отметить текущий масштаб). LMMS подсветит все ноты лежащие в выбранном масштабе для выбранной клавиши! + + + + 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. + Позволяет выбрать аккорд, который LMMS затем сможет нарисовать или подсветить. В этом меню можно найти ниболее популярные аккорды. После того, как вы выбрали аккорд, кликните в любом месте, чтобы поставить его и правым кликом по виртуальной клавиатуре открывается контекстное меню и подсветка аккорда. Для возврата в режим одной ноты нужно выбрать "Без аккорда" в этом выпадающем меню. + + + + Piano-Roll - %1 Нотный редактор - %1 + + Piano-Roll - no pattern - - - - Quantize - + Пианоролл — нет шаблона PianoView + Base note Опорная нота @@ -5687,20 +7217,24 @@ PM (ФМ) режим значит фазовая модуляция: Осцил Plugin + Plugin not found Модуль не найден + The plugin "%1" wasn't found or could not be loaded! Reason: "%2" Модуль «%1» отсутствует либо не может быть загружен! Причина: «%2» + Error while loading plugin Ошибка загрузки модуля + Failed to load plugin "%1"! Не получилось загрузить модуль «%1»! @@ -5708,25 +7242,30 @@ Reason: "%2" PluginBrowser + + Instrument Plugins + Плагины инструментов + + + Instrument browser Обзор инструментов + Drag an instrument into either the Song-Editor, the Beat+Bassline Editor or into an existing instrument track. Вы можете переносить нужные вам инструменты из этой панели в музыкальный, ритм-бас редактор или в существующую дорожку инструмента. - - Instrument Plugins - - PluginFactory + Plugin not found. Плагин не найден + LMMS plugin %1 does not have a plugin descriptor named %2! ЛММС плагин %1 не имеет описания плагина с именем %2! @@ -5734,261 +7273,422 @@ Reason: "%2" ProjectNotes - Project notes - Заметки к проекту + + Project Notes + Показать/скрыть заметки к проекту - Put down your project notes here. - Здесь вы можете держать заметки к своему проекту. + + Enter project notes here + Напишите заметки, касающиеся проекта здесь + Edit Actions Правка + &Undo &U Отменить + %1+Z %1+Z + &Redo &R Повторить + %1+Y %1+Y + &Copy &C Копировать + %1+C %1+C + Cu&t &t Вырезать + %1+X %1+X + &Paste &P Вставить + %1+V %1+V + Format Actions Форматирование + &Bold &b Полужирный + %1+B %1+B + &Italic &i Курсив + %1+I %1+I + &Underline &U Подчеркнутый + %1+U %1+U + &Left &L По левому краю + %1+L %1+L + C&enter По &центру + %1+E + &Right + %1+R + &Justify - + &Выравнивать + %1+J + &Color... - + &Цвет... ProjectRenderer + WAV-File (*.wav) Файл WAV (*.wav) + Compressed OGG-File (*.ogg) Сжатый файл OGG (*.ogg) + + + Compressed MP3-File (*.mp3) + + QWidget + + + Name: Название: + + Maker: Создатель: + + Copyright: Правообладатель: + + Requires Real Time: Требуется обработка в реальном времени: + + + + + + Yes Да + + + + + + No Нет + + Real Time Capable: Работа в реальном времени: + + In Place Broken: Вместо сломанного: + + Channels In: Каналы в: + + Channels Out: Каналы из: - File: - Файл: - - + File: %1 Файл: %1 + + + File: + Файл: + RenameDialog + Rename... Переименовать... + + ReverbSCControlDialog + + + Input + Ввод + + + + Input Gain: + Входная мощность: + + + + Size + Размер + + + + Size: + Размер: + + + + Color + Цвет + + + + Color: + Цвет: + + + + Output + Вывод + + + + Output Gain: + Выходная мощность: + + + + ReverbSCControls + + + Input Gain + Входная мощность + + + + Size + Размер + + + + Color + Цвет + + + + Output Gain + Выходная мощность + + 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) + Все аудио файлы (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + + + Wave-Files (*.wav) Файлы Wave (*.wav) + OGG-Files (*.ogg) Файлы OGG (*.ogg) + DrumSynth-Files (*.ds) Файлы DrumSynth (*.ds) + FLAC-Files (*.flac) Файлы FLAC (*.flac) + SPEEX-Files (*.spx) Файлы SPEEX (*.spx) + VOC-Files (*.voc) Файлы VOC (*.voc) + AIFF-Files (*.aif *.aiff) Файлы AIFF (*.aif *.aiff) + AU-Files (*.au) Файлы AU (*.au) + RAW-Files (*.raw) Файлы RAW (*.raw) - - All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) - Все аудио файлы (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) - SampleTCOView + double-click to select sample Выберите запись двойным нажатием мыши + Delete (middle mousebutton) Удалить (средняя кнопка мыши) + Cut Вырезать + Copy Копировать + Paste Вставить + Mute/unmute (<%1> + middle click) Заглушить/включить (<%1> + средняя кнопка мыши) @@ -5996,41 +7696,51 @@ Reason: "%2" SampleTrack - Sample track - Дорожка записи - - + Volume Громкость + Panning Баланс + + + + Sample track + Дорожка записи + SampleTrackView + Track volume Громкость дорожки + Channel volume: Громкость канала: + VOL ГРОМ + Panning Баланс + Panning: Баланс: + PAN БАЛ @@ -6038,496 +7748,658 @@ Reason: "%2" SetupDialog + Setup LMMS Настройка 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 Синхронизировать VST плагины с хостом воспроизведения + 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 + Встроить с использованием QT API + + + + Embed using native Win32 API + Встроить с использованием Win32 API + + + + Embed using XEmbed protocol + Встроить с использованием протокола XEmbed + + + LANGUAGE ЯЗЫК + + Paths Пути + + Directories + Папки + + + LMMS working directory Рабочий каталог LMMS - VST-plugin directory - Каталог модулей VST + + Themes directory + Папка тем + Background artwork Фоновое изображение + + VST-plugin directory + Каталог модулей VST + + + + GIG directory + Папка GIG + + + + SF2 directory + Папка SF2 + + + + LADSPA plugin directories + Папка плагинов LADSPA + + + STK rawwave directory Каталог STK rawwave + Default Soundfont File Основной Soundfont файл + + 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 Показывать указатель воспроизведения в процессоре аудио файлов (AFP) + + Audio settings Параметры звука + AUDIO INTERFACE ЗВУКОВАЯ СИСТЕМА + + MIDI settings Параметры MIDI + MIDI INTERFACE MIDI СИСТЕМА + OK - ОГА + ОК + Cancel Отменить + Restart LMMS Перезапустить LMMS + Please note that most changes won't take effect until you restart LMMS! Учтите, что большинство настроек не вступят в силу до перезапуска ЛММС! + Frames: %1 Latency: %2 ms Фрагментов: %1 Отклик: %2 + 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. Здесь вы можете настроить размер внутреннего звукового буфера LMMS. Меньшие значения дают меньшее время отклика программы, но повышают потребление ресурсов - это особенно заметно на старых машинах и системах, ядро которых не поддерживает приоритета реального времени. Если наблюдается прерывистый звук, попробуйте увеличить размер буфера. + Choose LMMS working directory Выбор рабочего каталога LMMS - Choose your VST-plugin directory - Выбор своего каталога для модулей VST - - - Choose artwork-theme directory - Выбор каталога с темой оформления для LMMS - - - Choose LADSPA plugin directory - Выбор каталога с модулями LADSPA - - - Choose STK rawwave directory - Выбор каталога STK rawwave - - - Choose default SoundFont - Выбрать главный SoundFont - - - Choose background artwork - Выбрать фоновое изображение - - - 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. - Пожалуйста, выберите желаемую звуковую систему. В зависимости от конфигурации во время компилирования программы вы можете использовать ALSA, JACK, OSS и другие. В нижней части окна настройки можно задать специфические параметры выбранной системы. - - - 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. - Пожалуйста, выберите интерфейс MIDI. В зависимости от конфигурации во время компилирования программы вы можете использовать ALSA, OSS и другие. В нижней части окна настройки можно задать специфические параметры выбранного интерфейса. - - - Reopen last project on start - Открыть последний проект на старте - - - Directories - Папки - - - Themes directory - Папка тем - - - GIG directory - Папка GIG - - - SF2 directory - Папка SF2 - - - LADSPA plugin directories - Папка плагинов LADSPA - - - Auto save - Автосохранение - - + Choose your GIG directory Выберите вашу папку GIG + Choose your SF2 directory Выберите вашу папку SF2 + + Choose your VST-plugin directory + Выбор своего каталога для модулей VST + + + + Choose artwork-theme directory + Выбор каталога с темой оформления для LMMS + + + + Choose LADSPA plugin directory + Выбор каталога с модулями LADSPA + + + + Choose STK rawwave directory + Выбор каталога STK rawwave + + + + Choose default SoundFont + Выбрать главный SoundFont + + + + Choose background artwork + Выбрать фоновое изображение + + + minutes - + Минуты + minute - - - - Enable auto-save - - - - Allow auto-save while playing - + Минута + Disabled - + Отключено + Auto-save interval: %1 - + Интервал автосорхранения: %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. - + Установить время между автоматическим бэкапом на %1. Не забывайте сохранять проект вручную. + + + + 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. + Пожалуйста, выберите желаемую звуковую систему. В зависимости от конфигурации во время компилирования программы вы можете использовать ALSA, JACK, OSS и другие. В нижней части окна настройки можно задать специфические параметры выбранной системы. + + + + 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. + Пожалуйста, выберите интерфейс MIDI. В зависимости от конфигурации во время компилирования программы вы можете использовать ALSA, OSS и другие. В нижней части окна настройки можно задать специфические параметры выбранного интерфейса. Song + Tempo Темп + Master volume Основная громкость + Master pitch Основная тональность + + LMMS Error report + Отчет об ошибке LMMS + + + Project saved Проект сохранён + The project %1 is now saved. Проект %1 сохранён. + Project NOT saved. Проект НЕ СОХРАНЁН. + The project %1 was not saved! Проект %1 не сохранён! + Import file Импорт файла + MIDI sequences MiDi последовательности + Hydrogen projects Hydrogen проекты + 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) + MIDI-файл (*.mid) + + + The following errors occured while loading: Следующие ошибки возникли при загрузке: - - MIDI File (*.mid) - - - - LMMS Error report - - - - Save project - - SongEditor + Could not open file Не могу открыть файл - Could not write 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. Невозможно открыть файл %1, вероятно, нет разрешений на его чтение. Пж. убедитесь, что есть по крайней мере права на чтение этого файла и попробуйте ещё раз. - Error in file - Ошибка в файле - - - The file %1 seems to contain errors and therefore can't be loaded. - Файл %1 возможно содержит ошибки из-за которых не может загрузиться. - - - Tempo - Темп - - - TEMPO/BPM - ТЕМП/BPM - - - tempo of song - Темп музыки - - - 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). - Это значение задаёт темп музыки в ударах в минуту (англ. аббр. BPM). На каждый такт приходится четыре удара, так что темп в ударах в минуту фактически указывает, сколько четвертей такта проигрывается за минуту (или, что то же, количество тактов, проигрываемых за четыре минуты). - - - High quality mode - Высокое качество - - - Master volume - Основная громкость - - - master volume - основная громкость - - - Master pitch - Основная тональность - - - master pitch - основная тональность - - - Value: %1% - Значение: %1% - - - Value: %1 semitones - Значение: %1 полутон(а/ов) + + 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. Невозможно открыть %1 для записи, возможно, нет разрешений на запись в этот файл, пж. удостоверьтесь, что есть доступ к этому файлу и попробуйте снова. - template - + + Error in file + Ошибка в файле - project - + + The file %1 seems to contain errors and therefore can't be loaded. + Файл %1 возможно содержит ошибки из-за которых не может загрузиться. + Version difference - + Версия отличается + This %1 was created with LMMS %2. - + %1 был создан в LMMS %2. + + + + template + шаблон + + + + project + проект + + + + Tempo + Темп + + + + TEMPO/BPM + ТЕМП/BPM + + + + tempo of song + Темп музыки + + + + 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). + Это значение задаёт темп музыки в ударах в минуту (англ. аббр. BPM). На каждый такт приходится четыре удара, так что темп в ударах в минуту фактически указывает, сколько четвертей такта проигрывается за минуту (или, что то же, количество тактов, проигрываемых за четыре минуты). + + + + High quality mode + Высокое качество + + + + + Master volume + Основная громкость + + + + master volume + основная громкость + + + + + Master pitch + Основная тональность + + + + master pitch + основная тональность + + + + Value: %1% + Значение: %1% + + + + Value: %1 semitones + Значение: %1 полутон(а/ов) SongEditorWindow + Song-Editor Музыкальный редактор + Play song (Space) Начать воспроизведение (Пробел) + Record samples from Audio-device Записать сэмпл со звукового устройства + Record samples from Audio-device while playing song or BB track Записать сэмпл с аудио-устройства во время воспроизведения в музыкальном или ритм/бас редакторе + Stop song (Space) Остановить воспроизведение (Пробел) - Add beat/bassline - Добавить ритм/бас - - - Add sample-track - Добавить дорожку записи - - - Add automation-track - Добавить дорожку автоматизации - - - Draw mode - Режим рисования - - - Edit mode (select and move) - Правка (выделение/перемещение) - - + 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. Нажмите, чтобы прослушать созданную мелодию. Воспроизведение начнётся с позиции курсора (зелёный треугольник); вы можете двигать его во время проигрывания. + 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 - + Действия трека + + Add beat/bassline + Добавить ритм/бас + + + + Add sample-track + Добавить дорожку записи + + + + Add automation-track + Добавить дорожку автоматизации + + + Edit actions Правка: + + Draw mode + Режим рисования + + + + Edit mode (select and move) + Правка (выделение/перемещение) + + + Timeline controls Управление временем + Zoom controls Приблизить управление @@ -6535,10 +8407,12 @@ Remember to also save your project manually. You can choose to disable saving wh SpectrumAnalyzerControlDialog + Linear spectrum Линейный спектр + Linear Y axis Линейная ось ординат (Y) @@ -6546,14 +8420,17 @@ Remember to also save your project manually. You can choose to disable saving wh SpectrumAnalyzerControls + Linear spectrum Линейный спектр + Linear Y axis Линейная ось ординат (Y) + Channel mode Режим канала @@ -6561,21 +8438,26 @@ Remember to also save your project manually. You can choose to disable saving wh SubWindow + Close - + Закрыть + Maximize - + Развернуть + Restore - + Восстановить TabWidget + + Settings for %1 Настройки для %1 @@ -6583,74 +8465,93 @@ Remember to also save your project manually. You can choose to disable saving wh TempoSyncKnob + + Tempo Sync Синхронизация темпа + No Sync Синхронизации нет + Eight beats Восемь ударов (две ноты) + Whole note Целая нота + Half note Полунота + Quarter note Четверть ноты + 8th note Восьмая ноты + 16th note 1/16 ноты + 32nd note 1/32 ноты + Custom... Своя... + Custom Своя + Synced to Eight Beats Синхро по 8 ударам + Synced to Whole Note Синхро по целой ноте + Synced to Half Note Синхро по половине ноты + Synced to Quarter Note Синхро по четверти ноты + Synced to 8th Note Синхро по 1/8 ноты + Synced to 16th Note Синхро по 1/16 ноты + Synced to 32nd Note Синхро по 1/32 ноты @@ -6658,65 +8559,81 @@ Remember to also save your project manually. You can choose to disable saving wh TimeDisplayWidget + click to change time units нажми для изменения единиц времени + MIN - + МИН + SEC - + СЕК + MSEC - + мСЕК + BAR - + ДЕЛЕНИЕ + BEAT - + БИТ + TICK - + ТИК TimeLineWidget + Enable/disable auto-scrolling Вкл/выкл автопрокрутку + Enable/disable loop-points Вкл/выкл точки петли + After stopping go back to begin После остановки переходить к началу + After stopping go back to position at which playing was started После остановки переходить к месту, с которого началось воспроизведение + After stopping keep position Оставаться на месте остановки + + Hint Подсказка + Press <%1> to disable magnetic loop points. Нажмите <%1>, чтобы убрать прилипание точек петли. + Hold <Shift> to move the begin loop point; Press <%1> to disable magnetic loop points. Зажмите <Shift> чтобы сдвинуть начало точек петли; Нажмите <%1>, чтобы убрать прилипание точек петли. @@ -6724,10 +8641,12 @@ Remember to also save your project manually. You can choose to disable saving wh Track + Mute Тихо + Solo Соло @@ -6735,38 +8654,63 @@ Remember to also save your project manually. You can choose to disable saving wh TrackContainer + Couldn't import file Не могу импортировать файл + Couldn't find a filter for importing file %1. You should convert this file into a format supported by LMMS using another software. Не могу найти фильтр для импорта файла %1. Для подключения этого файла преобразуйте его в формат, поддерживаемый LMMS. + Couldn't open file Не могу открыть файл + 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! Не могу открыть файл %1 для записи. Проверьте, обладаете ли вы правами на запись в выбранный файл и содержащий его каталог и попробуйте снова! + Loading project... Чтение проекта... + + Cancel Отменить + + Please wait... Подождите, пожалуйста... + + Loading cancelled + Загрузка отменена. + + + + Project loading was cancelled. + Загрузка проекта была отменена. + + + + Loading Track %1 (%2/Total %3) + + + + Importing MIDI-file... Импортирую файл MIDI... @@ -6774,6 +8718,7 @@ Please make sure you have read-permission to the file and the directory containi TrackContentObject + Mute Тихо @@ -6781,46 +8726,59 @@ Please make sure you have read-permission to the file and the directory containi TrackContentObjectView + Current position Текущая позиция + + Hint Подсказка + Press <%1> and drag to make a copy. Нажмите <%1> и тащите мышью, чтобы создать копию. + Current length Текущая длительность + Press <%1> for free resizing. Для свободного изменения размера нажмите <%1>. + + %1:%2 (%3:%4 to %5:%6) %1:%2 (от %3:%4 до %5:%6) + Delete (middle mousebutton) Удалить (средняя кнопка мыши) + Cut Вырезать + Copy Копировать + Paste Вставить + Mute/unmute (<%1> + middle click) Тихо/громко (<%1> + middle click) @@ -6828,193 +8786,243 @@ 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. Зажмите <Сtrl> и нажимайте мышь во время движения, чтобы начать новую переброску. + Actions for this track Действия для этой дорожки + Mute Тихо + + Solo Соло + Mute this track Заглушить эту дорожку + Clone this track Клонировать дорожку + Remove this track Удалить дорожку + Clear this track Очистить эту дорожку + FX %1: %2 ЭФ %1: %2 + + Assign to new FX Channel + Назначить на другой канал ЭФфектов + + + Turn all recording on Включить всё на запись + Turn all recording off Выключить всю запись - - Assign to new FX Channel - Назначить на другой канал ЭФфектов - TripleOscillatorView + Use phase modulation for modulating oscillator 1 with oscillator 2 Модулировать фазу осциллятора 2 сигналом с 1 + Use amplitude modulation for modulating oscillator 1 with oscillator 2 Модулировать амплитуду осциллятора 2 сигналом с первого + Mix output of oscillator 1 & 2 Смешать выводы 1 и 2 осцилляторов + Synchronize oscillator 1 with oscillator 2 Синхронизировать первый осциллятор по второму + Use frequency modulation for modulating oscillator 1 with oscillator 2 Модулировать частоту осциллятора 2 сигналом с 1 + Use phase modulation for modulating oscillator 2 with oscillator 3 Модулировать фазу осциллятора 3 сигналом с 2 + Use amplitude modulation for modulating oscillator 2 with oscillator 3 Модулировать амплитуду осциллятора 3 сигналом с 2 + Mix output of oscillator 2 & 3 Совместить вывод осцилляторов 2 и 3 + Synchronize oscillator 2 with oscillator 3 Синхронизировать осциллятор 2 и 3 + Use frequency modulation for modulating oscillator 2 with oscillator 3 Модулировать частоту осциллятора 3 сигналом со 2 + Osc %1 volume: Громкость осциллятора %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. Эта ручка устанавливает громкость осциллятора %1. Если 0, то осциллятор выключается, иначе будет слышно настолько громко , как тут установлено. + Osc %1 panning: Баланс для осциллятора %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. Регулятор стереобаланса осциллятора %1. Величина -100 обозначает, что 100% сигнала идёт в левый канал, а 100 - в правый. + Osc %1 coarse detuning: Грубая подстройка осциллятора %1: + semitones полутон[а,ов] + 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. Грубая регулировка подстройки осциллятора %1. Возможна подстройка до 24 полутонов (до 2 октавы) вверх и вниз. Полезно для создания аккордов. + Osc %1 fine detuning left: Точная подстройка левого канала осциллятора %1: + + cents Проценты + 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. Эта ручка устанавливает точную подстройку для левого канала осциллятора %1. Подстройка задаётся в диапазоне от -100 сотых до +100 сотых. Это полезно для создания "сочных" звуков. + Osc %1 fine detuning right: Точная подстройка правого канала осциллятора %1: + 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. Эта ручка устанавливает точную подстройку для правого канала осциллятора %1. Подстройка задаётся в диапазоне от -100 сотых до +100 сотых. Это полезно для создания "сочных" звуков. + Osc %1 phase-offset: Сдвиг фазы осциллятора %1: + + degrees градусы + 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. Эта ручка устанавливает начальную фазу осциллятора %1, т. е. точку, с которой осциллятор начинает вырабатывать сигнал. Например, если вы задали синусоидальную форму сигнала и начальную фазу 180º, волна сначала пойдёт вниз, а не вверх. То же для меандра (сигнала прямоугольной формы). + Osc %1 stereo phase-detuning: Подстройка стерео фазы осциллятора %1: + 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. Эта ручка устанавливает фазовую подстройку осциллятора %1 между каналами, то есть разность фаз между левым и правым каналами. Это удобно для создания расширения стереоэффектов. + Use a sine-wave for current oscillator. - Использовать гармонический (синусоидальный) сигнал для этого осциллятора. + Генерировать гармонический (синусоидальный) сигнал. + Use a triangle-wave for current oscillator. - Использовать треугольный сигнал для этого осциллятора. + Генерировать треугольный сигнал. + Use a saw-wave for current oscillator. - Использовать зигзагообразный сигнал для этого осциллятора. + Генерировать зигзагообразный сигнал. + Use a square-wave for current oscillator. - Использовать квадратный сигнал (меандр) для этого осциллятора. + Генерировать квадрат (меандр). + Use a moog-like saw-wave for current oscillator. Использовать муг-зигзаг для этого осциллятора. + Use an exponential wave for current oscillator. Использовать экспоненциальный сигнал для этого осциллятора. + Use white-noise for current oscillator. - Использовать белый шум для этого осциллятора. + Генерировать белый шум. + Use a user-defined waveform for current oscillator. Задать форму сигнала. @@ -7022,105 +9030,131 @@ Please make sure you have read-permission to the file and the directory containi VersionedSaveDialog + Increment version number Увеличивающийся номер версии + Decrement version number Понижающийся номер версии + already exists. Do you want to replace it? - + уже существует. Хотите перезаписать? VestigeInstrumentView + Open other VST-plugin Открыть другой VST плагин + 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. Открыть другой модуль VST. После нажатия на кнопку появится стандартный диалог выбора файла, где вы сможете выбрать нужный модуль. - Show/hide GUI - Показать/скрыть интерфейс - - - Click here to show or hide the graphical user interface (GUI) of your VST-plugin. - Скрывает/показывает графический пользовательский интерфейс (GUI) выбранного модуля VST. - - - Turn off all notes - Выключить все ноты - - - Open VST-plugin - Открыть модуль VST - - - DLL-files (*.dll) - Бибилиотеки DLL (*.dll) - - - EXE-files (*.exe) - Программы EXE (*.exe) - - - No VST-plugin loaded - Модуль VST не загружен - - + Control VST-plugin from LMMS host - Управление VST плагином через LMMS + Управление VST плагином через LMMS хост + Click here, if you want to control VST-plugin from host. - Нажмите здесь для контроля VST плагина через хост. + Нажмите здесь, для контроля VST плагином через хост. + Open VST-plugin preset - Открыть предустановку VST модуля + Открыть предустановку VST плагина + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. Открыть другую .fxp . fxb предустановку VST. + Previous (-) Предыдущий <-> + + Click here, if you want to switch to another VST-plugin preset program. - Нажмите здесь для переключения на другую предустановку программы VST плагина. + Переключение на другую предустановку программы VST плагина. + Save preset Сохранить предустановку + Click here, if you want to save current VST-plugin preset program. Сохранить текущую предустановку программы VST плагина. + Next (+) Следующий <+> + Click here to select presets that are currently loaded in VST. Выбор из уже загруженных в VST предустановок. + + Show/hide GUI + Показать/скрыть интерфейс + + + + Click here to show or hide the graphical user interface (GUI) of your VST-plugin. + Скрывает/показывает графический пользовательский интерфейс (GUI) выбранного модуля VST. + + + + Turn off all notes + Выключить все ноты + + + + Open VST-plugin + Открыть модуль VST + + + + DLL-files (*.dll) + Бибилиотеки DLL (*.dll) + + + + EXE-files (*.exe) + Программы EXE (*.exe) + + + + No VST-plugin loaded + Модуль VST не загружен + + + Preset Предустановка + by от + - VST plugin control - управление VST плагином @@ -7128,10 +9162,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 Нажать для включения @@ -7139,54 +9175,69 @@ Please make sure you have read-permission to the file and the directory containi VstEffectControlDialog + Show/hide Показать/Скрыть + Control VST-plugin from LMMS host Управление VST плагином через LMMS хост + Click here, if you want to control VST-plugin from host. Нажмите здесь, для контроля VST плагином через хост. + Open VST-plugin preset Открыть предустановку VST плагина + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. Открыть другую .fxp . fxb предустановку VST. + Previous (-) Предыдущий <-> + + Click here, if you want to switch to another VST-plugin preset program. Переключение на другую предустановку программы VST плагина. + Next (+) Следующий <+> + Click here to select presets that are currently loaded in VST. Выбор из уже загруженных в VST предустановок. + Save preset Сохранить настройку + Click here, if you want to save current VST-plugin preset program. Сохранить текущую предустановку программы VST плагина. + + Effect by: Эффекты по: + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> @@ -7194,387 +9245,509 @@ Please make sure you have read-permission to the file and the directory containi VstPlugin - Loading plugin - Загрузка модуля + + + The VST plugin %1 could not be loaded. + VST плагин %1 не может быть загружен. + Open Preset Открыть предустановку + + Vst Plugin Preset (*.fxp *.fxb) Предустановка VST плагина (*.fxp *.fxb) + : default : основные + " " + ' ' + Save Preset Сохранить предустановку + .fxp .fxp + .FXP .FXP + .FXB .FXB + .fxb .fxb - Please wait while loading VST plugin... - Пожалуйста, подождите пока грузится VST плагин... + + Loading plugin + Загрузка модуля - The VST plugin %1 could not be loaded. - VST плагин %1 не может быть загружен. + + Please wait while loading VST plugin... + Пожалуйста, подождите пока грузится VST плагин... WatsynInstrument + Volume A1 - + Громкость А1 + Volume A2 - + Громкость А2 + Volume B1 - + Громкость B1 + Volume B2 - + Громкость B2 + Panning A1 + Panning A2 + Panning B1 + Panning B2 + Freq. multiplier A1 - + Множитель частоты А1 + Freq. multiplier A2 - + Множитель частоты А2 + Freq. multiplier B1 - + Множитель частоты B1 + Freq. multiplier B2 - + Множитель частоты B2 + Left detune A1 + Left detune A2 + Left detune B1 + Left detune B2 + Right detune A1 + Right detune A2 + Right detune B1 + Right detune B2 + 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 + B2-B1 modulation + Selected graph - + Выбранный график WatsynView - Select oscillator A1 - - - - Select oscillator A2 - - - - Select oscillator B1 - - - - Select oscillator B2 - - - - Mix output of A2 to A1 - - - - Modulate amplitude of A1 with output of A2 - Модулировать амплитуду A1 сигналом с A2 - - - Ring-modulate A1 and A2 - Кольцевая модуляция А1 и А2 - - - Modulate phase of A1 with output of A2 - Модулировать фазу A1 сигналом с A2 - - - Mix output of B2 to B1 - - - - Modulate amplitude of B1 with output of B2 - Модулировать амплитуду B1 сигналом с B2 - - - Ring-modulate B1 and B2 - Кольцевая модуляция B1 и B2 - - - Modulate phase of B1 with output of B2 - Модулировать фазу B1 сигналом с B2 - - - Draw your own waveform here by dragging your mouse on this graph. - Здесь вы можете рисовать собственный сигнал передвигая зажатой мышью по этому графу. - - - Load waveform - - - - Click to load a waveform from a sample file - Кликнуть для загрузки формы звука из файла с образцом - - - Phase left - Фаза слева - - - Click to shift phase by -15 degrees - - - - Phase right - Фаза справа - - - Click to shift phase by +15 degrees - - - - Normalize - Нормализовать - - - Click to normalize - - - - Invert - - - - Click to invert - - - - Smooth - Сгладить - - - Click to smooth - - - - Sine wave - Синусоида - - - Click for sine wave - - - - Triangle wave - Треугольная волна - - - Click for triangle wave - - - - Click for saw wave - - - - Square wave - Квадрат - - - Click for square wave - - - + + + + Volume Громкость + + + + Panning Баланс + + + + Freq. multiplier - + Множитель частоты + + + + Left detune + + + + + + + + cents + + + + Right detune + A-B Mix + Mix envelope amount + Mix envelope attack + Mix envelope hold + Mix envelope decay + Crosstalk + + + Select oscillator A1 + + + + + Select oscillator A2 + + + + + Select oscillator B1 + + + + + Select oscillator B2 + + + + + Mix output of A2 to A1 + + + + + Modulate amplitude of A1 with output of A2 + Модулировать амплитуду A1 сигналом с A2 + + + + Ring-modulate A1 and A2 + Кольцевая модуляция А1 и А2 + + + + Modulate phase of A1 with output of A2 + Модулировать фазу A1 сигналом с A2 + + + + Mix output of B2 to B1 + + + + + Modulate amplitude of B1 with output of B2 + Модулировать амплитуду B1 сигналом с B2 + + + + Ring-modulate B1 and B2 + Кольцевая модуляция B1 и B2 + + + + Modulate phase of B1 with output of B2 + Модулировать фазу B1 сигналом с B2 + + + + + + + Draw your own waveform here by dragging your mouse on this graph. + Здесь вы можете рисовать собственный сигнал передвигая зажатой мышью по этому графу. + + + + Load waveform + + + + + Click to load a waveform from a sample file + Кликнуть для загрузки формы звука из файла с образцом + + + + Phase left + Фаза слева + + + + Click to shift phase by -15 degrees + + + + + Phase right + Фаза справа + + + + Click to shift phase by +15 degrees + + + + + Normalize + Нормализовать + + + + Click to normalize + + + + + Invert + Инвертировать + + + + Click to invert + + + + + Smooth + Сгладить + + + + Click to smooth + + + + + Sine wave + Синусоида + + + + Click for sine wave + + + + + + Triangle wave + Треугольная волна + + + + Click for triangle wave + + + + + Click for saw wave + + + + + Square wave + Квадрат + + + + Click for square wave + + ZynAddSubFxInstrument + Portamento Портаменто + Filter Frequency Фильтр Частот + Filter Resonance Фильтр резонанса + Bandwidth Ширина полосы + FM Gain Усил FM + Resonance Center Frequency Частоты центра резонанса + Resonance Bandwidth Ширина полосы резонанса + Forward MIDI Control Change Events Переслать изменение событий MiDi управления @@ -7582,121 +9755,150 @@ Please make sure you have read-permission to the file and the directory containi ZynAddSubFxView - Show GUI - Показать интерфейс - - - Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. - Скрыть или показать графический интерфейс ZynAddSubFX. - - + Portamento: Портаменто: + PORT PORT + Filter Frequency: Фильтр частот: + FREQ FREQ + Filter Resonance: Фильтр резонанса: + RES RES + Bandwidth: Полоса пропускания: + BW BW + FM Gain: Усиление частоты модуляции (FM): + FM GAIN FM GAIN + Resonance center frequency: Частоты центра резонанса: + RES CF RES CF + Resonance bandwidth: Ширина полосы резонанса: + RES BW RES BW + Forward MIDI Control Changes Переслать изменение событий MiDi управления + + + Show GUI + Показать интерфейс + + + + Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. + Скрыть или показать графический интерфейс ZynAddSubFX. + audioFileProcessor + Amplify Усиление + Start of sample Начало записи + End of sample Конец записи - Reverse sample - Перевернуть запись - - - Stutter - Запинание - - + Loopback point Точка петли + + Reverse sample + Перевернуть запись + + + Loop mode Режим повтора + + Stutter + Запинание + + + Interpolation mode Режим интерполяции + None Нет + Linear - + Линеарный + Sinc + Sample not found: %1 Сэмпл не найден: %1 @@ -7704,6 +9906,7 @@ Please make sure you have read-permission to the file and the directory containi bitInvader + Samplelength Длительность @@ -7711,165 +9914,205 @@ Please make sure you have read-permission to the file and the directory containi bitInvaderView + Sample Length Длительность записи - Sine wave - Синусоида - - - Triangle wave - Треугольник - - - Saw wave - Зигзаг - - - Square wave - Квадрат (Меандр) - - - White noise wave - Белый шум - - - User defined wave - Пользовательская - - - Smooth - Сгладить - - - Click here to smooth waveform. - Щёлкните чтобы сгладить форму сигнала. - - - Interpolation - Интерполяция - - - Normalize - Нормализовать - - + Draw your own waveform here by dragging your mouse on this graph. Здесь вы можете рисовать собственный сигнал. + + Sine wave + Синусоида + + + Click for a sine-wave. Сгенерировать гармонический (синусоидальный) сигнал. + + Triangle wave + Треугольник + + + Click here for a triangle-wave. Сгенерировать треугольный сигнал. + + Saw wave + Зигзаг + + + Click here for a saw-wave. - Сгенерировать загзагообразный сигнал. + Сгенерировать зигзаг. + + Square wave + Квадрат (Меандр) + + + Click here for a square-wave. - Сгенерировать квадратную волну (меандр). + Сгенерировать квадрат. + + White noise wave + Белый шум + + + Click here for white-noise. Сгенерировать белый шум. + + User defined wave + Пользовательская + + + Click here for a user-defined shape. Задать форму сигнала вручную. + + + Smooth + Сгладить + + + + Click here to smooth waveform. + Щёлкните чтобы сгладить форму сигнала. + + + + Interpolation + Интерполяция + + + + Normalize + Нормализовать + dynProcControlDialog + INPUT ВХОД + Input gain: Входная мощность: + OUTPUT Выход + Output gain: Выходная мощность: + ATTACK АТАКА + Peak attack time: Время пиковой атаки: + RELEASE ОТПУСК + Peak release time: Время отпуска пика: + Reset waveform Сбросить волну + Click here to reset the wavegraph back to default - Нажмите здесь, чтобы скинуть граф волны обратно по умолчанию + Сбросить граф волны обратно по умолчанию + Smooth waveform Сгладить волну + Click here to apply smoothing to wavegraph - Нажмите здесь, чтобы применить сглаживание графа волны + Применить сглаживание к графу волны + Increase wavegraph amplitude by 1dB - Повысить амплитуду графа волны на 1дБ + Повысить амплитуду графа волны на 1 дБ + Click here to increase wavegraph amplitude by 1dB - Нажмите здесь, чтобы увеличить амплитуду графа волны на 1дБ + Нажмите здесь, чтобы повысить амплитуду графа волны на 1 дБ + Decrease wavegraph amplitude by 1dB - Снизить амплитуду графа волны на 1дБ + Снизить амплитуду графа волны на 1 дБ + Click here to decrease wavegraph amplitude by 1dB - Нажмите здесь, чтобы снизить амплитуду графа волны на 1дБ + Снизить амплитуду графа волны на 1 дБ + 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 Обрабатывает каждый стерео канал независимо @@ -7877,22 +10120,27 @@ Please make sure you have read-permission to the file and the directory containi dynProcControls + Input gain Входная мощность + Output gain Выходная мощность + Attack time Время атаки + Release time Время отпуска + Stereo mode Режим стерео @@ -7900,10 +10148,12 @@ Please make sure you have read-permission to the file and the directory containi fxLineLcdSpinBox + Assign to: - + Назначить на: + New FX Channel Новый канал ЭФ @@ -7911,6 +10161,7 @@ Please make sure you have read-permission to the file and the directory containi graphModel + Graph Граф @@ -7918,93 +10169,115 @@ Please make sure you have read-permission to the file and the directory containi kickerInstrument + Start frequency Начальная частота + End frequency Конечная частота - Gain - Усиление - - + Length Длина + Distortion Start Начало искажения + Distortion End Конец искажения - Envelope Slope - + + Gain + Усиление + + Envelope Slope + Сглаживание кривой + + + Noise Шум + Click - + Клик + Frequency Slope - + Сглаживание частоты + Start from note + End to note - + Конец для ноты kickerInstrumentView + Start frequency: Начальная частота: + End frequency: Конечная частота: - Gain: - Усиление: - - + Frequency Slope: + + Gain: + Усиление: + + + Envelope Length: + Envelope Slope: + Click: - + Клик: + Noise: Шум: + Distortion Start: + Distortion End: @@ -8012,26 +10285,37 @@ Please make sure you have read-permission to the file and the directory containi ladspaBrowserView + + Available Effects Доступные эффекты + + Unavailable Effects Недоступные эффекты + + Instruments Инструменты + + Analysis Tools Анализаторы + + Don't know Неизвестные + 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. @@ -8060,6 +10344,7 @@ Double clicking any of the plugins will bring up information on the ports. + Type: Тип: @@ -8067,10 +10352,12 @@ Double clicking any of the plugins will bring up information on the ports. ladspaDescription + Plugins Модули + Description Описание @@ -8078,66 +10365,83 @@ Double clicking any of the plugins will bring up information on the ports. ladspaPortDialog + Ports Порты + Name Название + Rate Частота выборки + Direction Направление + Type Тип + Min < Default < Max Меньше < Стандарт < Больше + Logarithmic Логарифмический + SR Dependent Зависимость от SR + Audio Аудио + Control Управление + Input Ввод + Output Вывод + Toggled Включено + Integer Целое + Float Дробное + + Yes Да @@ -8145,46 +10449,57 @@ Double clicking any of the plugins will bring up information on the ports. lb302Synth + VCF Cutoff Frequency Частота среза VCF + VCF Resonance Усиление VCF + VCF Envelope Mod Модуляция огибающей VCF + VCF Envelope Decay Спад огибающей VCF + Distortion Искажение + Waveform Форма сигнала + Slide Decay Сдвиг затухания + Slide Сдвиг + Accent Акцент + Dead Глухо + 24dB/oct Filter 24дБ/окт фильтр @@ -8192,122 +10507,153 @@ Double clicking any of the plugins will bring up information on the ports. lb302SynthView + Cutoff Freq: Частота среза: + Resonance: Отзвук: + Env Mod: Мод Огиб: + Decay: - Спад: + Затухание: + 303-es-que, 24dB/octave, 3 pole filter 303-ий, 24дБ/октаву, 3-польный фильтр + Slide Decay: - Сдвиг спада: + Сдвиг затухания: + DIST: ИСК: + Saw wave Зигзаг + Click here for a saw-wave. Сгенерировать зигзаг. + Triangle wave Треугольная волна + Click here for a triangle-wave. Сгенерировать треугольный сигнал. + Square wave Квадрат + Click here for a square-wave. Сгенерировать квадрат. + Rounded square wave Волна скругленного квадрата + Click here for a square-wave with a rounded end. Создать квадратную волну закруглённую в конце. + Moog wave Муг волна + Click here for a moog-like wave. Сгенерировать волну похожую на муг. + Sine wave Синусоида + Click for a sine-wave. Сгенерировать гармонический (синусоидальный) сигнал. + + White noise wave Белый шум + Click here for an exponential wave. Генерировать экспоненциальный сигнал. + Click here for white-noise. Сгенерировать белый шум. + 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. Нажать здесь для пилообразной муг (moog) волны с ограниченной полосой. @@ -8315,118 +10661,147 @@ Double clicking any of the plugins will bring up information on the ports. malletsInstrument + Hardness Жёсткость + Position Положение + Vibrato Gain Усиление вибрато + Vibrato Freq Частота вибрато + Stick Mix Сведение ручек + Modulator Модулятор + Crossfade Переход + LFO Speed Скорость LFO + LFO Depth Глубина LFO + ADSR ADSR + Pressure Давление + Motion Движение + Speed Скорость + Bowed Наклон + Spread Разброс + Marimba Маримба + Vibraphone Вибрафон + Agogo Дискотека + Wood1 Дерево1 + Reso Резо + Wood2 Дерево2 + Beats Удары + Two Fixed Два фиксированных + Clump Тяжёлая поступь + Tubular Bells Трубные колокола + Uniform Bar Равномерные полосы + Tuned Bar Подстроенные полосы + Glass Стекло + Tibetan Bowl Тибетские шары @@ -8434,149 +10809,186 @@ Double clicking any of the plugins will bring up information on the ports. malletsInstrumentView + Instrument Инструмент + Spread Разброс + Spread: Разброс: - Hardness - Жёсткость - - - Hardness: - Жёсткость: - - - Position - Положение - - - Position: - Положение: - - - Vib Gain - Усил. вибрато - - - Vib Gain: - Усил. вибрато: - - - Vib Freq - Част. виб - - - Vib Freq: - Вибрато: - - - Stick Mix - Сведение ручек - - - Stick Mix: - Сведение ручек: - - - Modulator - Модулятор - - - Modulator: - Модулятор: - - - Crossfade - Переход - - - Crossfade: - Переход: - - - LFO Speed - Скорость LFO - - - LFO Speed: - Скорость LFO: - - - LFO Depth - Глубина LFO - - - LFO Depth: - Глубина LFO: - - - ADSR - ADSR - - - ADSR: - ADSR: - - - Pressure - Давление - - - Pressure: - Давление: - - - Speed - Скорость - - - Speed: - Скорость: - - + Missing files Файлы отсутствуют + Your Stk-installation seems to be incomplete. Please make sure the full Stk-package is installed! Похоже устновка Stk прошла не полностью. Пожалуйста, убедитесь, что пакет Stk полностью установлен! + + + Hardness + Жёсткость + + + + Hardness: + Жёсткость: + + + + Position + Положение + + + + Position: + Положение: + + + + Vib Gain + Усил. вибрато + + + + Vib Gain: + Усил. вибрато: + + + + Vib Freq + Част. виб + + + + Vib Freq: + Вибрато: + + + + Stick Mix + Сведение ручек + + + + Stick Mix: + Сведение ручек: + + + + Modulator + Модулятор + + + + Modulator: + Модулятор: + + + + Crossfade + Переход + + + + Crossfade: + Переход: + + + + LFO Speed + Скорость LFO + + + + LFO Speed: + Скорость LFO: + + + + LFO Depth + Глубина LFO + + + + LFO Depth: + Глубина LFO: + + + + ADSR + ADSR + + + + ADSR: + ADSR: + + + + Pressure + Давление + + + + Pressure: + Давление: + + + + Speed + Скорость + + + + Speed: + Скорость: + manageVSTEffectView + - VST parameter control Управление VST параметрами + VST Sync VST синхронизация + Click here if you want to synchronize all parameters with VST plugin. - Нажмите здесь для синхронизации всех параметров с VST плагином. + Нажмите здесь для синхронизации всех параметров VST плагина. + + Automated Автоматизировано + Click here if you want to display automated parameters only. Нажмите здесь, если хотите видеть только автоматизированные параметры. + Close Закрыть + Close VST effect knob-controller window. Закрыть окно управления регуляторами VST эффектов. @@ -8584,30 +10996,39 @@ Double clicking any of the plugins will bring up information on the ports. manageVestigeInstrumentView + + - VST plugin control Управление VST плагином + VST Sync VST синхронизация + Click here if you want to synchronize all parameters with VST plugin. Нажмите здесь для синхронизации всех параметров VST плагина. + + Automated Автоматизировано + Click here if you want to display automated parameters only. Нажмите здесь, если хотите видеть только автоматизированные параметры. + Close Закрыть + Close VST plugin knob-controller window. Закрыть окно управления регуляторами VST плагина. @@ -8615,118 +11036,147 @@ Double clicking any of the plugins will bring up information on the ports. opl2instrument + Patch Патч + Op 1 Attack ОП 1 Вступление + Op 1 Decay ОП 1 Спад + Op 1 Sustain ОП 1 Выдержка + Op 1 Release ОП 1 Убывание + Op 1 Level ОП 1 Уровень + Op 1 Level Scaling ОП 1 Уровень увеличения + Op 1 Frequency Multiple ОП 1 Множитель частот + Op 1 Feedback ОП 1 Возврат + Op 1 Key Scaling Rate ОП 1 Ключевая ставка увеличения + Op 1 Percussive Envelope ОП 1 Ударная огибающая + Op 1 Tremolo ОП 1 Тремоло + Op 1 Vibrato Оп 1 Вибрато + Op 1 Waveform ОП 1 Волна + Op 2 Attack ОП 2 Вступление + Op 2 Decay ОП 2 Спад + Op 2 Sustain ОП 2 Выдержка + Op 2 Release ОП 2 Убывание + Op 2 Level ОП 2 Уровень + Op 2 Level Scaling ОП 2 Уровень увеличения + Op 2 Frequency Multiple ОП 2 Множитель частот + Op 2 Key Scaling Rate ОП 2 Ключевая ставка множителя + Op 2 Percussive Envelope ОП 2 Ударная огибающая + Op 2 Tremolo ОП 2 Тремоло + Op 2 Vibrato Оп 2 Вибрато + Op 2 Waveform ОП 2 Волна + FM FM + Vibrato Depth Глубина вибрато + Tremolo Depth Глубина тремоло @@ -8734,29 +11184,39 @@ Double clicking any of the plugins will bring up information on the ports. opl2instrumentView + + Attack Вступление + + Decay Затихание + + Release Убывание + + Frequency multiplier - + Множитель частоты organicInstrument + Distortion Искажение + Volume Громкость @@ -8764,50 +11224,63 @@ Double clicking any of the plugins will bring up information on the ports. organicInstrumentView + Distortion: Искажение: - Volume: - Громкость: - - - Randomise - Случайно - - - Osc %1 waveform: - Форма сигнала для осциллятора %1: - - - Osc %1 volume: - Громкость осциллятора %1: - - - Osc %1 panning: - Баланс для осциллятора %1: - - - cents - сотые - - + The distortion knob adds distortion to the output of the instrument. Дисторшн добавляет искажения к выводу инструмента. + + 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: + Форма сигнала для осциллятора %1: + + + + Osc %1 volume: + Громкость осциллятора %1: + + + + Osc %1 panning: + Баланс для осциллятора %1: + + + Osc %1 stereo detuning Осц %1 стерео расстройка + + cents + сотые + + + Osc %1 harmonic: Осц %1 гармоника: @@ -8815,265 +11288,351 @@ Double clicking any of the plugins will bring up information on the ports. papuInstrument + Sweep time Время распространения + Sweep direction Направление распространения + Sweep RtShift amount - Кол-во распространения сдвига вправо + Кол-во развёртки сдвиг вправо + + Wave Pattern Duty Рабочая форма волны + Channel 1 volume Громкость первого канала + + + Volume sweep direction Объём направления распространения + + + Length of each step in sweep Длина каждого такта в распространении + Channel 2 volume Громкость второго канала + Channel 3 volume Громкость третьего канала + Channel 4 volume Громкость четвёртого канала + + Shift Register width + Сдвиг ширины регистра + + + Right Output level Выходной уровень справа + Left Output level Выходной уровень слева + Channel 1 to SO2 (Left) От первого канала к SO2 (левый канал) + Channel 2 to SO2 (Left) От второго канала к SO2 (левый канал) + Channel 3 to SO2 (Left) От третьего канала к SO2 (левый канал) + Channel 4 to SO2 (Left) От четвёртого канала к SO2 (левый канал) + Channel 1 to SO1 (Right) От первого канала к SO1 (правый канал) + Channel 2 to SO1 (Right) От второго канала к SO1 (правый канал) + Channel 3 to SO1 (Right) От третьего канала к SO1 (правый канал) + Channel 4 to SO1 (Right) От четвёртого канала к SO1 (правый канал) + Treble Верхние + Bass Нижние - - Shift Register width - Сдвиг ширины регистра - papuInstrumentView + Sweep Time: Время развёртки: + Sweep Time Время развёртки - Sweep RtShift amount: - Кол-во развёртки сдвиг вправо: - - - Sweep RtShift amount - Кол-во развёртки сдвиг вправо - - - Wave pattern duty: - Рабочая форма волны: - - - Wave Pattern Duty - Рабочая форма волны - - - Square Channel 1 Volume: - Громкость квадратного канала 1: - - - Length of each step in sweep: - Длина каждого такта в развёртке: - - - Length of each step in sweep - Длина каждого такта в распространении - - - Wave pattern duty - Рабочая форма волны - - - Square Channel 2 Volume: - Громкость квадратного канала 2: - - - Square Channel 2 Volume - Громкость квадратного канала 2 - - - Wave Channel Volume: - Громкость волнового канала: - - - Wave Channel Volume - Громкость волнового канала - - - Noise Channel Volume: - Громкость канала шума: - - - Noise Channel Volume - Громкость канала шума - - - SO1 Volume (Right): - Громкость SO1 (Правый): - - - SO1 Volume (Right) - Громкость SO1 (Правый) - - - SO2 Volume (Left): - Громкость SO2 (Левый): - - - SO2 Volume (Left) - Громкость SO2 (Левый) - - - Treble: - Верхние: - - - Treble - Верхние - - - Bass: - Нижние: - - - Bass - Нижние - - - Sweep Direction - Направление развёртки - - - Volume Sweep Direction - Громкость направления развёртки - - - Shift Register Width - Сдвиг ширины регистра - - - Channel1 to SO1 (Right) - Канал1 в SO1 (Правый) - - - Channel2 to SO1 (Right) - Канал2 в SO1 (Правый) - - - Channel3 to SO1 (Right) - Канал3 в SO1 (Правый) - - - Channel4 to SO1 (Right) - Канал4 в SO1 (Правый) - - - Channel1 to SO2 (Left) - Канал1 в SO2 (Левый) - - - Channel2 to SO2 (Left) - Канал2 в SO2 (Левый) - - - Channel3 to SO2 (Left) - Канал2 в SO2 (Левый) - - - Channel4 to SO2 (Left) - Канал4 в SO2 (Левый) - - - Wave Pattern - Рисунок волны - - + 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: + Громкость квадратного канала 1: + + + Square Channel 1 Volume Громкость квадратного канала 1 + + + + Length of each step in sweep: + Длина каждого такта в развёртке: + + + + + + Length of each step in sweep + Длина каждого такта в распространении + + + + + The delay between step change Задержка между изменениями такта + + Wave pattern duty + Рабочая форма волны + + + + Square Channel 2 Volume: + Громкость квадратного канала 2: + + + + + Square Channel 2 Volume + Громкость квадратного канала 2 + + + + Wave Channel Volume: + Громкость волнового канала: + + + + + Wave Channel Volume + Громкость волнового канала + + + + Noise Channel Volume: + Громкость канала шума: + + + + + Noise Channel Volume + Громкость канала шума + + + + SO1 Volume (Right): + Громкость SO1 (Правый): + + + + SO1 Volume (Right) + Громкость SO1 (Правый) + + + + SO2 Volume (Left): + Громкость SO2 (Левый): + + + + SO2 Volume (Left) + Громкость SO2 (Левый) + + + + Treble: + Верхние: + + + + Treble + Верхние + + + + Bass: + Нижние: + + + + Bass + Нижние + + + + Sweep Direction + Направление развёртки + + + + + + + + Volume Sweep Direction + Громкость направления развёртки + + + + Shift Register Width + Сдвиг ширины регистра + + + + Channel1 to SO1 (Right) + Канал1 в SO1 (Правый) + + + + Channel2 to SO1 (Right) + Канал2 в SO1 (Правый) + + + + Channel3 to SO1 (Right) + Канал3 в SO1 (Правый) + + + + Channel4 to SO1 (Right) + Канал4 в SO1 (Правый) + + + + Channel1 to SO2 (Left) + Канал1 в SO2 (Левый) + + + + Channel2 to SO2 (Left) + Канал2 в SO2 (Левый) + + + + Channel3 to SO2 (Left) + Канал2 в SO2 (Левый) + + + + Channel4 to SO2 (Left) + Канал4 в SO2 (Левый) + + + + Wave Pattern + Рисунок волны + + + Draw the wave here Рисовать волну здесь @@ -9081,34 +11640,42 @@ Double clicking any of the plugins will bring up information on the ports. patchesDialog + Qsynth: Channel Preset + Bank selector - + Выбор банка + Bank Банк + Program selector Выбор программ + Patch Патч + Name Имя + OK ОК + Cancel Отмена @@ -9116,239 +11683,302 @@ Double clicking any of the plugins will bring up information on the ports. pluginBrowser + no description описание отсутствует - Incomplete monophonic imitation tb303 - Незавершённая монофоническая имитация tb303 + + A native amplifier plugin + Родной плагин усилителя - Plugin for freely manipulating stereo output - Модуль для произвольного управления стереовыходом + + Simple sampler with various settings for using samples (e.g. drums) in an instrument-track + Простой сэмплер с разными установками по использованию сэмплов (как барабаны) в инструментальной дорожке - Plugin for controlling knobs with sound peaks - Модуль для установки значений регуляторов по пикам громкости + + Boost your bass the fast and simple way + Накачай свой бас быстро и просто - Plugin for enhancing stereo separation of a stereo input file - Модуль, усиливающий разницу между каналами стереозаписи + + Customizable wavetable synthesizer + Настраиваемый синтезатор звукозаписей (wavetable) + + An oversampling bitcrusher + + + + + Carla Patchbay Instrument + + + + + Carla Rack Instrument + Карла инструментальная стойка + + + + A 4-band Crossover Equalizer + + + + + A native delay plugin + Встроенный delay плагин + + + + A Dual filter plugin + Двух фильтровый плагин + + + + plugin for processing dynamics in a flexible way + + + + + A native eq plugin + Родной плагин эквалайзера + + + + A native flanger plugin + + + + + Player for GIG files + Проигрыватель GIG-файлов + + + + Filter for importing Hydrogen files into LMMS + Фильтр для импорта Hydrogen файлов в LMMS + + + + Versatile drum synthesizer + Универсальный барабанный синтезатор + + + List installed LADSPA plugins Показать установленные модули LADSPA - GUS-compatible patch instrument - Патч-инструмент, совместимый с GUS - - - Additive Synthesizer for organ-like sounds - Синтезатор звуков вроде органа - - - Tuneful things to bang on - Мелодичные ударные - - - VST-host for using VST(i)-plugins within LMMS - VST - хост для поддержки модулей VST(i) в LMMS - - - Vibrating string modeler - Эмуляция вибрирующих струн - - + plugin for using arbitrary LADSPA-effects inside LMMS. Модуль, позволяющий использовать в LMMS любые эффекты LADSPA. + + Incomplete monophonic imitation tb303 + Незавершённая монофоническая имитация tb303 + + + + Filter for exporting MIDI-files from LMMS + Фильтр для экспорта MIDI файлов из LMMS + + + Filter for importing MIDI-files into LMMS Фильтр для включения файла MIDI в проект ЛММС + + Monstrous 3-oscillator synth with modulation matrix + Монстро 3-осциляторный синт с матрицей модуляции + + + + A multitap echo delay plugin + + + + + A NES-like synthesizer + Синтезатор типа NES + + + + 2-operator FM Synth + 2-режимный синт модуляции частот (FM synth) + + + + Additive Synthesizer for organ-like sounds + Синтезатор звуков вроде органа + + + + Emulation of GameBoy (TM) APU + Эмуляция GameBoy (TM) + + + + GUS-compatible patch instrument + Патч-инструмент, совместимый с GUS + + + + Plugin for controlling knobs with sound peaks + Модуль для установки значений регуляторов по пикам громкости + + + + Reverb algorithm by Sean Costello + + + + + Player for SoundFont files + Проигрыватель файлов SoundFont + + + + LMMS port of sfxr + LMMS порт SFXR + + + Emulation of the MOS6581 and MOS8580 SID. This chip was used in the Commodore 64 computer. Эмуляция MOS6581 и MOS8580. Использовалось на компьютере Commodore 64. - Player for SoundFont files - Проигрыватель файлов SoundFont - - - Emulation of GameBoy (TM) APU - Эмуляция GameBoy (TM) - - - Customizable wavetable synthesizer - Настраиваемый синтезатор звукозаписей (wavetable) - - - Embedded ZynAddSubFX - Встроенный ZynAddSubFX - - - 2-operator FM Synth - 2-режимный синт модуляции частот (FM synth) - - - Filter for importing Hydrogen files into LMMS - Фильтр для импорта Hydrogen файлов в LMMS - - - LMMS port of sfxr - LMMS порт SFXR - - - Monstrous 3-oscillator synth with modulation matrix - Монстро 3-осциляторный синт с матрицей модуляции - - - Three powerful oscillators you can modulate in several ways - Три мощных осциллятора, которые можно модулировать несколькими способами - - - A native amplifier plugin - Родной плагин усилителя - - - Carla Rack Instrument - Карла инструментальная стойка - - - 4-oscillator modulatable wavetable synth - - - - plugin for waveshaping - Плагин для сглаживания волн - - - Boost your bass the fast and simple way - Накачай свой бас быстро и просто - - - Versatile drum synthesizer - - - - Simple sampler with various settings for using samples (e.g. drums) in an instrument-track - Простой сэмплер с разными установками по использованию сэмплов (как барабаны) в инструментальной дорожке - - - plugin for processing dynamics in a flexible way - - - - Carla Patchbay Instrument - - - - plugin for using arbitrary VST effects inside LMMS. - Плагин для использования любых VST эффектов в ЛММС - - + Graphical spectrum analyzer plugin Плагин графического анализа спектра - A NES-like synthesizer - Синтезатор типа NES + + Plugin for enhancing stereo separation of a stereo input file + Модуль, усиливающий разницу между каналами стереозаписи - A native delay plugin - + + Plugin for freely manipulating stereo output + Модуль для произвольного управления стереовыходом - Player for GIG files - + + Tuneful things to bang on + Мелодичные ударные - A multitap echo delay plugin - + + Three powerful oscillators you can modulate in several ways + Три мощных осциллятора, которые можно модулировать несколькими способами - A native flanger plugin - + + VST-host for using VST(i)-plugins within LMMS + VST - хост для поддержки модулей VST(i) в LMMS - An oversampling bitcrusher - + + Vibrating string modeler + Эмуляция вибрирующих струн - A native eq plugin - Родной плагин эквалайзера + + plugin for using arbitrary VST effects inside LMMS. + Плагин для использования любых VST эффектов в ЛММС - A 4-band Crossover Equalizer - + + 4-oscillator modulatable wavetable synth + 4-осцилляторный модулируемый волновой синтезатор - A Dual filter plugin - + + plugin for waveshaping + Плагин для сглаживания волн - Filter for exporting MIDI-files from LMMS - + + Embedded ZynAddSubFX + Встроенный ZynAddSubFX sf2Instrument + Bank Банк + Patch Патч + 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 не удаётся загрузить. @@ -9356,74 +11986,92 @@ This chip was used in the Commodore 64 computer. sf2InstrumentView + Open other SoundFont file Открыть другой файл SoundFront + Click here to open another SF2 file Нажмите здесь чтобы открыть другой файл SF2 + 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 Открыть файл SoundFront + SoundFont2 Files (*.sf2) Файлы SoundFont2 (*.sf2) @@ -9431,6 +12079,7 @@ This chip was used in the Commodore 64 computer. sfxrInstrument + Wave Form Форма волны @@ -9438,26 +12087,32 @@ This chip was used in the Commodore 64 computer. sidInstrument + Cutoff Срез + Resonance Усиление + Filter type Тип фильтра + Voice 3 off Голос 3 откл + Volume Громкость + Chip model Модель чипа @@ -9465,134 +12120,172 @@ This chip was used in the Commodore 64 computer. sidInstrumentView + Volume: Громкость: + Resonance: Усиление: + + Cutoff frequency: Частота среза: + High-Pass filter Выс.ЧФ + Band-Pass filter Сред.ЧФ + Low-Pass filter Низ.ЧФ + Voice3 Off Голос 3 откл + MOS6581 SID - + MOS6581 SID + MOS8580 SID - + MOS8580 SID + + Attack: Вступление: + Attack rate determines how rapidly the output of Voice %1 rises from zero to peak amplitude. Длительность вступления определяет, насколько быстро громкость %1-го голоса возрастает от нуля до наибольшего значения. + + Decay: - Спад: + Затухание: + Decay rate determines how rapidly the output falls from the peak amplitude to the selected Sustain level. Длительность спада определяет, насколько быстро громкость падает от максимума до остаточного уровня. + Sustain: Выдержка: + Output of Voice %1 will remain at the selected Sustain amplitude as long as the note is held. Громкость %1-го голоса будет оставаться на уровне амплитуды выдержки, пока длится нота. + + Release: Убывание: + The output of of Voice %1 will fall from Sustain amplitude to zero amplitude at the selected Release rate. Громкость %1-го голоса будет падать от остаточного уровня до нуля с указанной здесь скоростью. + + 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. Длительность импульса позволяет мягко регулировать прохождение импульса без заметных сбоев. Импульсная волна должна быть выбрана на осцилляторе %1, чтобы получить звучание. + Coarse: Грубость: + The Coarse detuning allows to detune Voice %1 one octave up or down. Грубая настройка позволяет подстроить Голос %1 на одну октаву вверх или вниз. + Pulse Wave Пульсирующая волна + Triangle Wave Треугольник + SawTooth Зигзаг + Noise Шум + Sync Синхро + Sync synchronizes the fundamental frequency of Oscillator %1 with the fundamental frequency of Oscillator %2 producing "Hard Sync" effects. Синхро синхронизирует фундаментальную частоту осцилляторов %1 фундаментальной частотой осциллятора %2, создавая эффект "Железной синхронизации". + Ring-Mod Круговой режим + Ring-mod replaces the Triangle Waveform output of Oscillator %1 with a "Ring Modulated" combination of Oscillators %1 and %2. Круговой режим заменяет треугольные волны на выходе осциллятора %1 "Круговой модуляцией" комбинацией осцилляторов %1 и %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. Если этот флажок установлен, то %1-й голос будет проходить через фильтр. Иначе голос №%1 будет подаваться прямо на выход. + Test Тест + Test, when set, resets and locks Oscillator %1 at zero until Test is turned off. Если «флажок» установлен, то %1-й осциллятор выдаёт нулевой сигнал (пока флажок не снимется). @@ -9600,10 +12293,12 @@ This chip was used in the Commodore 64 computer. stereoEnhancerControlDialog + WIDE ШИРЕ + Width: Ширина: @@ -9611,6 +12306,7 @@ This chip was used in the Commodore 64 computer. stereoEnhancerControls + Width Ширина @@ -9618,18 +12314,22 @@ This chip was used in the Commodore 64 computer. stereoMatrixControlDialog + Left to Left Vol: От левого на левый: + Left to Right Vol: От левого на правый: + Right to Left Vol: От правого на левый: + Right to Right Vol: От правого на правый: @@ -9637,18 +12337,22 @@ This chip was used in the Commodore 64 computer. stereoMatrixControls + Left to Left От левого на левый + Left to Right От левого на правый + Right to Left От правого на левый + Right to Right От правого на правый @@ -9656,10 +12360,12 @@ This chip was used in the Commodore 64 computer. vestigeInstrument + Loading plugin Загрузка модуля + Please wait while loading VST-plugin... Подождите, пока загрузится модуль VST... @@ -9667,42 +12373,52 @@ This chip was used in the Commodore 64 computer. vibed + String %1 volume Громкость %1-й струны + String %1 stiffness Жёсткость %1-й струны + Pick %1 position Лад %1 + Pickup %1 position Положение %1-го звукоснимателя + Pan %1 Бал %1 + Detune %1 Подстройка %1 + Fuzziness %1 Нечёткость %1 + Length %1 Длина %1 + Impulse %1 Импульс %1 + Octave %1 Октава %1 @@ -9710,90 +12426,112 @@ This chip was used in the Commodore 64 computer. vibedView + Volume: Громкость: + The 'V' knob sets the volume of the selected string. Регулятор 'V' устанавливает громкость текущей струны. + 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. Регулятор 'S' устанавливает жёсткость текущей струны. Этот параметр отвечает за длительность звучания струны (чем больше значение жёсткости, тем дольше звенит струна). + Pick position: Лад: + 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. Регулятор 'P' устанавливает место струны, где она будет „прижата“. Чем ниже значение, тем ближе это место будет к кобылке. + Pickup position: Положение звукоснимателя: + 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. Регулятор 'PU' устанавливает место струны, откуда будет сниматься звук. Чем ниже значение, тем ближе это место будет к кобылке. + Pan: Бал: + The Pan knob determines the location of the selected string in the stereo field. Эта ручка устанавливает стереобаланс для текущей струны. + 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: Нечёткость: + 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: Длина: + 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. Переключатель „Imp“ устанавливает режим работы струны: если он включён, то указанная форма сигнала интерпретируется как начальный импульс, иначе — как начальная форма струны. + Octave Октава + 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. Переключатель октав позволяет указать гармонику основной частоты, на которой будет звучать струна. Например, „-2“ означает, что струна будет звучать двумя октавами ниже основной частоты, „F“ заставит струну звенеть на основной частоте инструмента, а „6“ — на частоте, на шесть октав более высокой, чем основная. + Impulse Editor Редактор сигнала + 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. @@ -9811,6 +12549,7 @@ The 'N' button will normalize the waveform. Кнопка 'N' нормализует уровень. + 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. @@ -9841,129 +12580,160 @@ The LED in the lower right corner of the waveform editor determines whether the Индикатор-переключатель слева внизу определяет, включена ли текущая струна. + Enable waveform Включить + Click here to enable/disable waveform. Нажмите, чтобы включить/выключить сигнал. + String Струна + 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. Переключатель струн позволяет выбрать струну, чьи свойства редактируются. Инструмент Vibed содержит до девяти независимо звучащих струн, индикатор в левом нижнем углу показывает, активна ли текущая струна (т. е. будет ли она слышна). + Sine wave Синусоида - Triangle wave - Треугольник - - - Saw wave - Зигзаг - - - Square wave - Квадратная волна - - - White noise wave - Белый шум - - - User defined wave - Пользовательская - - - Smooth - Сгладить - - - Click here to smooth waveform. - Щёлкните чтобы сгладить форму сигнала. - - - Normalize - Нормализовать - - - Click here to normalize waveform. - Нажмите, чтобы нормализовать сигнал. - - + Use a sine-wave for current oscillator. Генерировать гармонический (синусоидальный) сигнал. + + Triangle wave + Треугольник + + + Use a triangle-wave for current oscillator. Генерировать треугольный сигнал. + + Saw wave + Зигзаг + + + Use a saw-wave for current oscillator. Генерировать зигзагообразный сигнал. + + Square wave + Квадратная волна + + + Use a square-wave for current oscillator. Генерировать квадрат (меандр). + + White noise wave + Белый шум + + + Use white-noise for current oscillator. Генерировать белый шум. + + User defined wave + Пользовательская + + + Use a user-defined waveform for current oscillator. Задать форму сигнала. + + + Smooth + Сгладить + + + + Click here to smooth waveform. + Щёлкните чтобы сгладить форму сигнала. + + + + Normalize + Нормализовать + + + + Click here to normalize waveform. + Нажмите, чтобы нормализовать сигнал. + voiceObject + Voice %1 pulse width Голос %1 длина сигнала + Voice %1 attack Вступление %1-го голоса + Voice %1 decay - Спад %1-го голоса + Затухание %1-го голоса + Voice %1 sustain Выдержка для %1-го голоса + Voice %1 release Убывание %1-го голоса + Voice %1 coarse detuning Подстройка %1-го голоса (грубо) + Voice %1 wave shape Форма сигнала для %1-го голоса + Voice %1 sync Синхронизация %1-го голоса + Voice %1 ring modulate Голос %1 кольцевой модулятор + Voice %1 filtered Фильтрованный %1-й голос + Voice %1 test Голос %1 тест @@ -9971,58 +12741,72 @@ The LED in the lower right corner of the waveform editor determines whether the waveShaperControlDialog + INPUT ВХОД + Input gain: Входная мощность: + OUTPUT Выход + Output gain: Выходная мощность: + Reset waveform Сбросить волну + Click here to reset the wavegraph back to default Сбросить граф волны обратно по умолчанию + Smooth waveform Сгладить волну + Click here to apply smoothing to wavegraph Применить сглаживание к графу волны + Increase graph amplitude by 1dB - + Повысить амплитуду графа на 1 дБ + Click here to increase wavegraph amplitude by 1dB - Повыситьить амплитуду графа волны на 1дБ + Нажмите здесь, чтобы повысить амплитуду графа волны на 1 дБ + Decrease graph amplitude by 1dB - + Снизить амплитуду графа на 1 дБ + Click here to decrease wavegraph amplitude by 1dB - Снизить амплитуду графа волны на 1дБ + Снизить амплитуду графа волны на 1 дБ + Clip input - + Срезать выходной сигнал + Clip input signal to 0dB Срезать входной сигнал до 0дБ @@ -10030,10 +12814,12 @@ The LED in the lower right corner of the waveform editor determines whether the waveShaperControls + Input gain Входная мощность + Output gain Выходная мощность diff --git a/data/locale/sv.ts b/data/locale/sv.ts index 29f99f555..7b2557cfd 100644 --- a/data/locale/sv.ts +++ b/data/locale/sv.ts @@ -2,121 +2,148 @@ AboutDialog + About LMMS Om LMMS + + LMMS + LMMS + + + Version %1 (%2/%3, Qt %4, %5) Version %1 (%2/%3, Qt %4, %5) + About Om + LMMS - easy music production for everyone LMMS - enkel musikproduktion för alla - Authors - Medverkande + + Copyright © %1 + Copyright © %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 + Upphovsmän + + + + Involved + Engagerade + + + + Contributors ordered by number of commits: + Bidragsgivare ordnade efter mängd bidrag: + + + Translation Översättning + 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! + License Licens - - LMMS - LMMS - - - Involved - Involverad - - - Contributors ordered by number of commits: - Medverkande, ordnade efter mängd bidrag: - - - Copyright © %1 - Copyright © %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> - - AmplifierControlDialog + VOL VOL + Volume: Volym: + PAN - PANORERA + PAN + Panning: Panorering: + LEFT VÄNSTER + Left gain: - Vänster förstärkning: + Vänsterförstärkning: + RIGHT HÖGER + Right gain: - Höger förstärkning: + Högerförstärkning: AmplifierControls + Volume Volym + Panning Panorering + Left gain - Vänster förstärkning + Vänsterförstärkning + Right gain - Höger förstärkning + Högerförstärkning AudioAlsaSetupWidget + DEVICE ENHET + CHANNELS KANALER @@ -124,78 +151,98 @@ If you're interested in translating LMMS in another language or want to imp AudioFileProcessorView + Open other sample Öppna annan ljudfil + 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. Klicka här för att öppna en annan ljudfil. En dialog visas där du väljer din fil. Inställningar som looping, start och slutpunkter, amplifiering och sådant omställs inte. Därför låter det kanske inte som originalfilen. + Reverse sample Spela baklänges + If you enable this button, the whole sample is reversed. This is useful for cool effects, e.g. a reversed crash. - Den här knappen gör att ljudfilen spelas baklänges. Den kan användas för intressanta effeker t.ex. en baklänges cymbal. - - - Amplify: - Förstärkning: - - - 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!) - Med detta vred ställer du in förstärkningen. Vid 100% blir det ingen skillnad. Annars blir din ljudfil mer eller mindre högljudd, men originalfilen förändras inte. - - - Startpoint: - Startpunkt: - - - Endpoint: - Slutpunkt: - - - Continue sample playback across notes - Forsätt spela ljudfil över noter - - - 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) - Denna inställningen gör att ljudfilen förtsätter spela över noter. Om en not avslutas före ljudfilen är slut fortsätter nästa not där den förra slutade. Om du vill starta från början av ljudfilen innan den spelat färdigt, placera en not på botten av pianot (vid 20Hz) + Den här knappen gör att ljudfilen spelas baklänges. Den kan användas för intressanta effekter t.ex. en baklänges cymbal. + Disable loop - Avaktivera looping + Inaktivera slinga + This button disables looping. The sample plays only once from start to end. Den här knappen avaktiverar looping. Ljudfilen spelas bara en gång från start till slut. + + Enable loop - Aktivera looping + Aktivera slinga + This button enables forwards-looping. The sample loops between the end point and the loop point. Den här knappen aktiverar looping. Ljudfilen loopar mellan slutpunkten och looppunkten. + This button enables ping-pong-looping. The sample loops backwards and forwards between the end point and the loop point. - Den här knappen aktiverar "ping-pong" looping. Ljudfilen spelar från start till slut, och sen tilbaks, och fortsäter så. + Den här knappen aktiverar "ping-pong" looping. Ljudfilen spelar från start till slut, och sen tillbaka, och fortsätter så. + + Continue sample playback across notes + Fortsätt spela ljudfil över noter + + + + 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) + Denna inställningen gör att ljudfilen fortsätter spela över noter. Om en not avslutas före ljudfilen är slut fortsätter nästa not där den förra slutade. Om du vill starta från början av ljudfilen innan den spelat färdigt, placera en not på botten av pianot (vid 20Hz) + + + + Amplify: + Förstärkning: + + + + 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!) + Med detta vred ställer du in förstärkningen. Vid 100% blir det ingen skillnad. Annars blir din ljudfil mer eller mindre högljudd, men originalfilen förändras inte. + + + + Startpoint: + Startpunkt: + + + With this knob you can set the point where AudioFileProcessor should begin playing your sample. Med den här vreden ställer du in vartifrån ljudfilen ska börja spela. + + Endpoint: + Slutpunkt: + + + With this knob you can set the point where AudioFileProcessor should stop playing your sample. Med den här vreden ställer du in vart ljudfilen slutar spela. + Loopback point: - Loopback punkt: + Slinga-tillbaka punkt: + With this knob you can set the point where the loop starts. Den här vreden ställer in vart loopen startar. @@ -203,6 +250,7 @@ If you're interested in translating LMMS in another language or want to imp AudioFileProcessorWaveView + Sample length: Ljudfilens längd: @@ -210,26 +258,32 @@ If you're interested in translating LMMS in another language or want to imp AudioJack + JACK client restarted - JACK klienten omstartades + JACK-klienten omstartad + 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 blev bortkopplat från JACK. LMMS JACK backend omstartades därfor. Du får manuellt koppla om igen. + LMMS blev bortkopplat från JACK. LMMS JACK backend omstartades därfor. Du behöver koppla om manuellt. + JACK server down JACK-server nerstängd + 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. JACK-servern stängdes ned och det gick inte starta en ny. LMMS kan inte fortsätta. Du bör spara ditt projekt och starta om både JACK och LMMS. + CLIENT-NAME KLIENT-NAMN + CHANNELS KANALER @@ -237,10 +291,12 @@ If you're interested in translating LMMS in another language or want to imp AudioOss::setupWidget + DEVICE ENHET + CHANNELS KANALER @@ -248,10 +304,12 @@ If you're interested in translating LMMS in another language or want to imp AudioPortAudio::setupWidget + BACKEND BACKEND + DEVICE ENHET @@ -259,10 +317,12 @@ If you're interested in translating LMMS in another language or want to imp AudioPulseAudio::setupWidget + DEVICE ENHET + CHANNELS KANALER @@ -270,6 +330,7 @@ If you're interested in translating LMMS in another language or want to imp AudioSdl::setupWidget + DEVICE ENHET @@ -277,10 +338,12 @@ If you're interested in translating LMMS in another language or want to imp AudioSndio::setupWidget + DEVICE ENHET + CHANNELS KANALER @@ -288,10 +351,12 @@ If you're interested in translating LMMS in another language or want to imp AudioSoundIo::setupWidget + BACKEND BAKÄNDE + DEVICE ENHET @@ -299,61 +364,75 @@ If you're interested in translating LMMS in another language or want to imp AutomatableModel + &Reset (%1%2) &Nollställ (%1%2) + &Copy value (%1%2) - Kopiera värde (%1%2) + &Kopiera värde (%1%2) + &Paste value (%1%2) &Klistra in värde (%1%2) + Edit song-global automation - Redigera global automation - - - Connected to %1 - Kopplad till %1 - - - Connected to controller - Kopplad till controller - - - Edit connection... - Redigera koppling... - - - Remove connection - Ta bort koppling - - - Connect to controller... - Koppla till kontroller... + Redigera låt-global automation + Remove song-global automation Ta bort global automation + Remove all linked controls Ta bort alla kopplade kontroller + + + Connected to %1 + Kopplad till %1 + + + + Connected to controller + Kopplad till controller + + + + Edit connection... + Redigera koppling... + + + + Remove connection + Ta bort koppling + + + + Connect to controller... + Koppla till kontroller... + AutomationEditor + Please open an automation pattern with the context menu of a control! - Öppna ett automationsmönster ifrån en kontrollers kontextmeny! + Öppna ett automationsmönster från en kontrollers kontextmeny! + Values copied Värden kopierade + All selected values were copied to the clipboard. Alla valda värden blev kopierade till urklipp. @@ -361,142 +440,184 @@ If you're interested in translating LMMS in another language or want to imp AutomationEditorWindow + Play/pause current pattern (Space) Spela/pausa aktuellt mönster (Mellanslag) + 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. Klicka här för att spela det aktuella mönstret, detta är användbart när man redigerar. Mönstret spelas från början igen när det nått sitt slut. + Stop playing of current pattern (Space) - Sluta spela aktuellt mönster (mellanslag) + Sluta spela aktuellt mönster (Mellanslag) + Click here if you want to stop playing of the current pattern. Klicka här för att stoppa uppspelning av de aktuella mönstret. - Draw mode (Shift+D) - Ritläge (Shift+D) - - - Erase mode (Shift+E) - Suddläge (Shift+E) - - - Flip vertically - Spegla vertikalt - - - Flip horizontally - Spegla horizontellt - - - Click here and the pattern will be inverted.The points are flipped in the y direction. - Klicka här för att spegla mönstret. Punkterna förflyttas på y-axeln - - - Click here and the pattern will be reversed. The points are flipped in the x direction. - Klicka här för att spegla mönstret. Punkterna förflyttas på x-axeln - - - 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. - Klicka här för att aktivera ritläget. I detta läget kan du lägga till och förflytta individuella värden. Det här är standardläget. Det går också att trycka 'Shift+D' på tangentborded för att aktivera detta läget. - - - 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. - Klicka här för att aktivera suddläget. I detta läget kan du ta bort individuella värden. Det går också att trycka 'Shift+E' på tangentborded för att aktivera detta läget. - - - Discrete progression - Diskret talföljd - - - Linear progression - Linjär talföljd - - - Cubic Hermite progression - Cubic Hermite talföljd - - - Tension value for spline - Spänning i mönstrets 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. - Högre spänning ger en mjuk kurva som ibland missar individuella punkter. Med lägre spänning planar kurvan ut nära punkterna. - - - 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. - Klicka här för att aktivera diskret talföljd. Värdet är konstant mella kontroll punkter och ändras direkt när en ny kontrollpunkt nås. - - - 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. - Klicka här för att aktivera linjär talföljd. Värdet ändras vid en stadig takt mellan kontrollpunkter för att gradvis nå nästa värde. - - - 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. - Klicka här för att aktivera cubic hermite talföljd. Värdet följer en mjuk kurva mellan kontrollpunkter. - - - Cut selected values (%1+X) - Klipp ut valda värden (%1+X) - - - Copy selected values (%1+C) - Kopiera valda värden (%1+C) - - - Paste values from clipboard (%1+V) - Klistra värden (%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. - Klicka här för att klippa de valda värderna. Du kan sen klistra dem var som helst genom att klicka på klistra knappen. - - - 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. - Klicka här för att kopiera de valda värderna. Du kan sedan klistra dem var som helst genom att klicka på klistra knappen. - - - Click here and the values from the clipboard will be pasted at the first visible measure. - Klicka här för att klistra kopierade värderna vid den första synliga metern. - - - Tension: - Spänning: - - - Automation Editor - no pattern - Redigera Automation - inget automationsmönster - - - Automation Editor - %1 - Redigera Automation - %1 - - + Edit actions Redigera åtgärder + + Draw mode (Shift+D) + Ritläge (Skift+D) + + + + Erase mode (Shift+E) + Suddläge (Skift+E) + + + + Flip vertically + Spegla vertikalt + + + + Flip horizontally + Spegla horizontellt + + + + Click here and the pattern will be inverted.The points are flipped in the y direction. + Klicka här för att spegla mönstret. Punkterna förflyttas på y-axeln + + + + Click here and the pattern will be reversed. The points are flipped in the x direction. + Klicka här för att spegla mönstret. Punkterna förflyttas på x-axeln + + + + 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. + Klicka här för att aktivera ritläget. I detta läget kan du lägga till och förflytta individuella värden. Det här är standardläget. Det går också att trycka "Skift+D" på tangentbordet för att aktivera detta läget. + + + + 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. + Klicka här för att aktivera suddläget. I detta läget kan du ta bort individuella värden. Det går också att trycka "Skift+E" på tangentbordet för att aktivera detta läget. + + + Interpolation controls Interpoleringskontroller - Timeline controls - Tidslinjekontroller + + Discrete progression + Diskret talföljd + + Linear progression + Linjär talföljd + + + + Cubic Hermite progression + Cubic Hermite talföljd + + + + Tension value for spline + Spänning i mönstrets 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. + Högre spänning ger en mjuk kurva som ibland missar individuella punkter. Med lägre spänning planar kurvan ut nära punkterna. + + + + 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. + Klicka här för att aktivera diskret talföljd. Värdet är konstant mella kontroll punkter och ändras direkt när en ny kontrollpunkt nås. + + + + 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. + Klicka här för att aktivera linjär talföljd. Värdet ändras vid en stadig takt mellan kontrollpunkter för att gradvis nå nästa värde. + + + + 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. + Klicka här för att aktivera cubic hermite talföljd. Värdet följer en mjuk kurva mellan kontrollpunkter. + + + + Tension: + Spänning: + + + + Cut selected values (%1+X) + Klipp ut valda värden (%1+X) + + + + Copy selected values (%1+C) + Kopiera valda värden (%1+C) + + + + Paste values from clipboard (%1+V) + Klistra värden (%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. + Klicka här för att klippa de valda värderna. Du kan sen klistra dem var som helst genom att klicka på klistra knappen. + + + + 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. + Klicka här för att kopiera de valda värderna. Du kan sedan klistra dem var som helst genom att klicka på klistra knappen. + + + + Click here and the values from the clipboard will be pasted at the first visible measure. + Klicka här för att klistra kopierade värderna vid den första synliga metern. + + + Zoom controls Zoomningskontroller + Quantization controls + Kvantiseringskontroller + + + + Quantization + Kvantisering + + + + 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 + Redigera Automation - inget automationsmönster + + + + + Automation Editor - %1 + Redigera Automation - %1 + + + Model is already connected to this pattern. Modellen är redan ansluten till det här mönstret. @@ -504,6 +625,7 @@ If you're interested in translating LMMS in another language or want to imp AutomationPattern + Drag a control while pressing <%1> Dra en kontroll samtidigt som du håller <%1> @@ -511,46 +633,57 @@ If you're interested in translating LMMS in another language or want to imp AutomationPatternView + double-click to open this pattern in automation editor dubbelklicka för att öppna det här automationsmönstret för redigering + Open in Automation editor Redigera automationsmönster + Clear Rensa + Reset name Nollställ namn + Change name Byt namn - %1 Connections - %1 Kopplingar - - - Disconnect "%1" - Avkoppla "%1" - - + Set/clear record + Flip Vertically (Visible) Spegla Vertikalt (Synligt) + Flip Horizontally (Visible) Spegla Horizontellt (Synligt) + + %1 Connections + %1 Kopplingar + + + + Disconnect "%1" + Koppla bort "%1" + + + Model is already connected to this pattern. Modellen är redan ansluten till det här mönstret. @@ -558,6 +691,7 @@ If you're interested in translating LMMS in another language or want to imp AutomationTrack + Automation track Automationsspår @@ -565,88 +699,108 @@ If you're interested in translating LMMS in another language or want to imp BBEditor + Beat+Bassline Editor - Redigera Trummor+Bas + Takt+Basgång-redigeraren + Play/pause current beat/bassline (Space) - Spela/pause Trummor+Bas + Spela/pausa nuvarande takt/basgång (Mellanslag) + Stop playback of current beat/bassline (Space) - Avsluta uppspelning av trummor/bas + Avsluta uppspelning av nuvarande takt/basgång (Mellanslag) + Click here to play the current beat/bassline. The beat/bassline is automatically looped when its end is reached. - Klicka här för att spela trummor/bas. Mönstret loopar när det nåt sitt slut. + Klicka här för att spela takt/basgång. Takt/basgång återupprepas automatiskt när dess slut nås. + Click here to stop playing of current beat/bassline. - Klicka här för att sluta spela trummor/bas. - - - Add beat/bassline - Lägg till trummor/bas - - - Add automation-track - Lägg till automationsspår - - - Remove steps - Ta bort steg - - - Add steps - Lägg till steg + Klicka här för att sluta spela takt/basgång. + Beat selector Taktväljare + Track and step actions Spår och stegåtgärder - Clone Steps - Klona steg + + Add beat/bassline + Lägg till takt/basgång + Add sample-track - Lägg till ljudfils-spår + Lägg till ljudspår + + + + Add automation-track + Lägg till automationsspår + + + + Remove steps + Ta bort steg + + + + Add steps + Lägg till steg + + + + Clone Steps + Klona steg BBTCOView + Open in Beat+Bassline-Editor - Redigera Trummor+Bas + Öppna Takt+Basgång-redigeraren + Reset name Nollställ namn + Change name Byt namn + Change color Byt färg + Reset color to default - Byt färg till standard + Nollställ färg till standard BBTrack + Beat/Bassline %1 - Trum/Basmönster %1 + Takt/Basgång %1 + Clone of %1 Kopia av %1 @@ -654,124 +808,149 @@ If you're interested in translating LMMS in another language or want to imp BassBoosterControlDialog + FREQ FREQ + Frequency: Frekvens: + GAIN - FÖRST + FÖRSTÄRKNING + Gain: Förstärkning: + RATIO - RATIO + FÖRHÅLLANDE + Ratio: - Ratio: + Förhållande: BassBoosterControls + Frequency Frekvens + Gain Förstärkning + Ratio - Ratio + Förhållande BitcrushControlDialog + IN IN + OUT UT + + GAIN - FÖRST + FÖRSTÄRKNING + Input Gain: - Input Förstärkning: + Ingång förstärkning: - NOIS - NOIS + + NOISE + BRUS + Input Noise: + Output Gain: Output Förstärkning + CLIP KLIPP + Output Clip: - Rate - Värdera - - + Rate Enabled - + Hastighet Aktiverad + Enable samplerate-crushing - Depth - Djup - - + Depth Enabled + Enable bitdepth-crushing + + FREQ + FREKV. + + + Sample rate: - + Samplingsfrekvens: - STD - STD + + STEREO + STEREO + Stereo difference: + Stereo skillnad: + + + + QUANT - Levels - Nivåer - - + Levels: Nivåer: @@ -779,10 +958,12 @@ If you're interested in translating LMMS in another language or want to imp CaptionMenu + &Help &Hjälp + Help (not available) Hjälp (inte tillgängligt) @@ -790,10 +971,12 @@ If you're interested in translating LMMS in another language or want to imp CarlaInstrumentView + Show GUI Visa användargränssnitt + Click here to show or hide the graphical user interface (GUI) of Carla. Klicka här för att visa eller gömma användargränssnittet för Carla. @@ -801,6 +984,7 @@ If you're interested in translating LMMS in another language or want to imp Controller + Controller %1 Kontroller %1 @@ -808,58 +992,73 @@ If you're interested in translating LMMS in another language or want to imp ControllerConnectionDialog + Connection Settings Kopplingsinställningar + MIDI CONTROLLER MIDI-KONTROLLER + Input channel - Inputkanal + Ingångskanal + CHANNEL KANAL + Input controller - Inputkontroller + Ingångsregulator + CONTROLLER KONTROLLER + + Auto Detect Upptäck Automatiskt + MIDI-devices to receive MIDI-events from - MIDI-enheter att ta emot MIDI-events från + MIDI-enheter för att ta emot MIDI-händelser från + USER CONTROLLER ANVÄNDARKONTROLLER + MAPPING FUNCTION - + KARTLÄGGNINGSFUNKTION + OK OK + Cancel Avbryt + LMMS LMMS + Cycle Detected. @@ -867,18 +1066,22 @@ If you're interested in translating LMMS in another language or want to imp ControllerRackView + Controller Rack Kontrollrack + Add Lägg till + Confirm Delete Bekräfta Borttagning + Confirm delete? There are existing connection(s) associated with this controller. There is no way to undo. Vill du verkligen ta bort? Det finns kopplingar till den här kontrollern, och operationen går inte ångra. @@ -886,93 +1089,115 @@ If you're interested in translating LMMS in another language or want to imp ControllerView + Controls Kontroller + Controllers are able to automate the value of a knob, slider, and other controls. Kontroller kan automatisera värdet på en vred, reglage, och andra kontroller + Rename controller Byt namn på kontroller + Enter the new name for this controller Skriv nya namnet på kontrollern + + LFO + LFO + + + &Remove this controller &Ta bort den här kontrollen + Re&name this controller Döp& om den här kontrollern - - LFO - LFO - CrossoverEQControlDialog + Band 1/2 Crossover: + Band 2/3 Crossover: + Band 3/4 Crossover: + Band 1 Gain: Band 1 Förstärkn.: + Band 2 Gain: Band 2 Förstärkn.: + Band 3 Gain: Band 3 Förstärkn.: + Band 4 Gain: Band 4 Förstärkn.: + Band 1 Mute Band 1 Tyst + Mute Band 1 Tysta Band 1 + Band 2 Mute Band 2 Tyst + Mute Band 2 Tysta Band 2 + Band 3 Mute Band 3 Tyst + Mute Band 3 Tysta Band 3 + Band 4 Mute Band 4 Tyst + Mute Band 4 Tysta Band 4 @@ -980,22 +1205,27 @@ If you're interested in translating LMMS in another language or want to imp DelayControls + Delay Samples - Fördröj Samplingar + Fördröj samplingar + Feedback Återkoppling + Lfo Frequency Lfo-frekvens + Lfo Amount Lfo-mängd + Output gain Utgångsförstärkning @@ -1003,228 +1233,311 @@ If you're interested in translating LMMS in another language or want to imp DelayControlsDialog - Lfo Amt - + + DELAY + FÖRDRÖJNING + Delay Time Tidsfördröjning - Feedback Amount - Återgivningsmängd - - - Lfo - Lfo - - - Out Gain - Ut-förstärkning - - - Gain - Förstärkning - - - DELAY - - - + FDBK + + Feedback Amount + Återgivningsmängd + + + RATE + HASTIGHET + + + + Lfo + Lfo + + + + AMNT - AMNT + + Lfo Amt + + + Out Gain + Ut-förstärkning + + + + Gain + Förstärkning + DualFilterControlDialog - Filter 1 enabled - Filter 1 aktiverat - - - Filter 2 enabled - Filter 2 aktiverat - - - Click to enable/disable Filter 1 - Klicka för att aktivera/inaktivera Filter 1 - - - Click to enable/disable Filter 2 - Klicka för att aktivera/inaktivera Filter 2 - - + + FREQ - FREQ + FREKV. + + Cutoff frequency Cutoff frekvens + + RESO RESO + + Resonance Resonans + + GAIN FÖRST. + + Gain Förstärkning + MIX MIX + Mix Mix + + + Filter 1 enabled + Filter 1 aktiverat + + + + Filter 2 enabled + Filter 2 aktiverat + + + + Click to enable/disable Filter 1 + Klicka för att aktivera/inaktivera Filter 1 + + + + Click to enable/disable Filter 2 + Klicka för att aktivera/inaktivera Filter 2 + DualFilterControls + Filter 1 enabled Filter 1 aktiverat + Filter 1 type Filter 1 typ + Cutoff 1 frequency Cutoff 1 frekvens + Q/Resonance 1 Q/Resonans 1 + Gain 1 Förstärkning 1 + Mix Mix + Filter 2 enabled Filter 2 aktiverat + Filter 2 type Filter 2 typ + Cutoff 2 frequency Cutoff 2 frekvens + Q/Resonance 2 Q/Resonans 2 + Gain 2 Förstärkning 2 + + LowPass Lågpass + + HiPass Högpass + + BandPass csg - + BandPass csg + + BandPass czpg - + BandPass czpg + + Notch + + Allpass - + Allpass + + Moog Moog + + 2x LowPass 2x Lågpass + + RC LowPass 12dB RC Lågpass 12dB + + RC BandPass 12dB RC BandPass 12dB + + RC HighPass 12dB RC Högpass 12dB + + RC LowPass 24dB RC Lågpass 24dB + + RC BandPass 24dB RC BandPass 24dB + + RC HighPass 24dB RC Högpass 24dB + + Vocal Formant Filter + + 2x Moog - + 2x Moog + + SV LowPass SV Lågpass + + SV BandPass SV BandPass + + SV HighPass SV Högpass + + SV Notch + + Fast Formant + + Tripole @@ -1232,48 +1545,58 @@ If you're interested in translating LMMS in another language or want to imp Editor + + Transport controls + Transportkontroller + + + Play (Space) Play (Mellanslag) + Stop (Space) Stop (Mellanslag) + Record Spela in + Record while playing Spela in under uppspelningen - - Transport controls - Transportkontroller - Effect + Effect enabled Effekt aktiverad + Wet/Dry mix Blöt/Torr mix + Gate - + Gate + Decay - Decay + Förfall EffectChain + Effects enabled Effekter aktiverade @@ -1281,10 +1604,12 @@ If you're interested in translating LMMS in another language or want to imp EffectRackView + EFFECTS CHAIN EFFEKTKEDJA + Add effect Lägg till effekt @@ -1292,22 +1617,28 @@ If you're interested in translating LMMS in another language or want to imp EffectSelectDialog + Add effect Lägg till effekt + + Name Namn + Type Typ + Description Beskrivning + Author Författare @@ -1315,54 +1646,67 @@ If you're interested in translating LMMS in another language or want to imp EffectView + Toggles the effect on or off. Slår på eller av effekten. + On/Off På/Av + W/D - W/D + B/T + Wet Level: - + Blöt Nivå: + The Wet/Dry knob sets the ratio between the input signal and the effect signal that forms the output. + DECAY - DECAY + FÖRFALL + Time: Tid: + 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 + Gate: Gate: + The Gate knob controls the signal level that is considered to be 'silence' while deciding when to stop processing signals. + Controls Kontroller + 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. @@ -1379,73 +1723,90 @@ Right clicking will bring up a context menu where you can change the order in wh + Move &up Flytta &upp + Move &down Flytta &ner + &Remove this plugin - &Ta bort det här insticksprogrammet + &Ta bort den här insticksmodulen EnvelopeAndLfoParameters + Predelay För-fördröjning + Attack Attack + Hold Hold + Decay Decay + Sustain Sustain + Release Release + Modulation Modulering + LFO Predelay + LFO Attack LFO-Attack + LFO speed LFO-hastighet + LFO Modulation LFO-Modulering + LFO Wave Shape LFO-vågform + Freq x 100 - Freq x 100 + Frekv. x 100 + Modulate Env-Amount Modulera Env-mängd @@ -1453,349 +1814,439 @@ Right clicking will bring up a context menu where you can change the order in wh EnvelopeAndLfoView + + DEL - DEL + RAD + Predelay: För-fördröjning: + 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 - AMT + MÄNGD + + Modulation amount: Moduleringsmängd: + 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: LFO-för-fördröjning: + Use this knob for setting predelay-time of the current LFO. The bigger this value the the time until the LFO starts to oscillate. Använd denna ratt för att ställa för-fördröjningen för aktuell LFO. Ju högre värdet är desto längre tid tar det innan LFO'n börjar oscillera. + LFO- attack: LFO-attack: + 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. Använd denna ratt för att ställa attack-tiden för aktuell LFO. Ju högre värdet är desto längre tid tar det för LFO'n att nå sin maximala amplitud. + SPD - + SPD + LFO speed: - + LFO-hastighet: + 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. Använd denna ratt för att ställa hastigheten för aktuell LFO. Ju högre värdet är desto snabbare oscillerar LFO'n och desto snabbare är effekten. + 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. Använd denna ratt för att ställa mängden modulering för aktuell LFO. Ju högre värdet är desto större valt värde (volym eller cutoff-frekvens) kommer influeras av denna LFO. + Click here for a sine-wave. Klicka här för sinusvåg. + Click here for a triangle-wave. Klicka här för triangelvåg. + Click here for a saw-wave for current. Klicka här för sågtandsvåg för aktuell. + Click here for a square-wave. - Klicka här för fyrkantvåg + Klicka här för fyrkantvåg. + Click here for a user-defined wave. Afterwards, drag an according sample-file onto the LFO graph. - FREQ x 100 - FREQ x 100 + + Click here for random wave. + Klicka här för en slumpmässig vågform. + + FREQ x 100 + FREKV. x 100 + + + Click here if the frequency of this LFO should be multiplied by 100. Klicka här för att multiplicera frekvensen för denna LFO med 100. + multiply LFO-frequency by 100 multiplicera LFO-frekvensen med 100 + MODULATE ENV-AMOUNT + Click here to make the envelope-amount controlled by this LFO. + control envelope-amount by this LFO + ms/LFO: ms/LFO: + Hint Ledtråd + Drag a sample from somewhere and drop it in this window. Dra en ljudfil till det här fönstret. - - Click here for random wave. - Klicka här för en slumpmässig vågform. - EqControls + Input gain Ingångsförstärkning + Output gain Utgångsförstärkning + Low shelf gain + Peak 1 gain + Peak 2 gain + Peak 3 gain + Peak 4 gain + High Shelf gain + HP res + Low Shelf res + Peak 1 BW + Peak 2 BW + Peak 3 BW + Peak 4 BW + High Shelf res + LP res + HP freq + Low Shelf freq + Peak 1 freq + Peak 2 freq + Peak 3 freq + Peak 4 freq + High shelf freq + LP freq + HP active + Low shelf active + Peak 1 active + Peak 2 active + Peak 3 active + Peak 4 active + High shelf active + LP active - + LP aktiv + 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 Lågpass-typ + high pass type Högpass-typ + Analyse IN Analysera IN + Analyse OUT Analysera UT @@ -1803,260 +2254,352 @@ Right clicking will bring up a context menu where you can change the order in wh EqControlsDialog + HP - + HP + Low Shelf + Peak 1 + Peak 2 + Peak 3 + Peak 4 + High Shelf + LP - + LP + In Gain In-förstärkning + + + Gain Förstärkning + Out Gain Ut-förstärkning + Bandwidth: Bandbredd: + + Octave + Oktav + + + Resonance : Resonans: + Frequency: Frekvens: + lp grp + hp grp - - Octave - Oktav - EqHandle + Reso: Reso.: + BW: + + Freq: - Freq: + Frekv.: ExportProjectDialog + Export project Exportera projekt + Output Utgång + File format: - Fil-format: + Filformat: + Samplerate: Samplingshastighet: + 44100 Hz 44100 Hz + 48000 Hz 48000 Hz + 88200 Hz 88200 Hz + 96000 Hz 96000 Hz + 192000 Hz 192000 Hz - Bitrate: - Bit-hastighet: - - - 64 KBit/s - 64 KBit/s - - - 128 KBit/s - 128 KBit/s - - - 160 KBit/s - 160 KBit/s - - - 192 KBit/s - 192 KBit/s - - - 256 KBit/s - 256 KBit/s - - - 320 KBit/s - 320 KBit/s - - + Depth: Djup: + 16 Bit Integer + + 24 Bit Integer + + + + 32 Bit Float - Please note that not all of the parameters above apply for all file formats. - Alla inställningar ovan gäller för samtliga filformat + + Stereo mode: + Stereoläge: + + Stereo + Stereo + + + + Joint Stereo + + + + + Mono + Mono + + + + Bitrate: + Bithastighet: + + + + 64 KBit/s + 64 KBit/s + + + + 128 KBit/s + 128 KBit/s + + + + 160 KBit/s + 160 KBit/s + + + + 192 KBit/s + 192 KBit/s + + + + 256 KBit/s + 256 KBit/s + + + + 320 KBit/s + 320 KBit/s + + + + Use variable bitrate + Använd variabel bithastighet + + + Quality settings Kvalitetsinställningar + Interpolation: Interpolering: + Zero Order Hold + Sinc Fastest + Sinc Medium (recommended) + Sinc Best (very slow!) + Oversampling (use with care!): Översampling (använd varsamt!): + 1x (None) 1x (Ingen) + 2x 2x + 4x 4x + 8x 8x - Start - Starta - - - Cancel - Avbryt - - + Export as loop (remove end silence) Exportera som loop (ta bort slut-tystnad) + Export between loop markers - Exportera mellan loop-markeringar + Exportera mellan slinga-markeringar + + Start + Starta + + + + Cancel + Avbryt + + + Could not open file Kunde inte öppna fil + + 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! + Det gick inte att öppna filen %1 för att skriva. +Se till att du har skrivbehörighet till filen och mappen som innehåller filen och försök igen! + + + Export project to %1 Exportera projekt till %1 + Error Fel + Error while determining file-encoder device. Please try to choose a different output format. - + Fel vid bestämning av filkodarenhet. Vänligen försök att välja ett annat utmatningsformat. + Rendering: %1% Renderar: %1% - - 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! - - Fader + + Please enter a new value between %1 and %2: Ange ett nytt värde mellan %1 och %2: @@ -2064,72 +2607,88 @@ Please make sure you have write permission to the file and the directory contain FileBrowser + Browser - + Bläddrare FileBrowserTreeWidget + Send to active instrument-track Skicka till aktivt instrument-spår + + Open in new instrument-track/Song Editor + Öppna i nytt instrument-spår/Låt-redigeraren + + + Open in new instrument-track/B+B Editor + Loading sample - Laddar ljudfil + Läser in ljudfil + Please wait, loading sample for preview... - Ljudfilen laddas för förhandslyssning... - - - --- Factory files --- - --- Grundfiler --- - - - Open in new instrument-track/Song Editor - Öppna i nytt instrument-spår/Sång Editor + Ljudfilen läses in för förhandslyssning... + Error Fel + does not appear to be a valid verkar inte vara en giltig + file fil + + + --- Factory files --- + --- Grundfiler --- + FlangerControls + Delay Samples - Fördröj Samplingar + Fördröj samplingar + Lfo Frequency Lfo-frekvens + Seconds Sekunder + Regen + Noise Brus + Invert Invertera @@ -2137,46 +2696,57 @@ Please make sure you have write permission to the file and the directory contain FlangerControlsDialog - Delay Time: - - - - Feedback Amount: - - - - White Noise Amount: - - - + DELAY - + FÖRDRÖJNING + + Delay Time: + Fördröjningstid: + + + RATE - + HASTIGHET - Rate: - + + Period: + Period: + AMNT + Amount: - + Mängd: + FDBK - NOISE + + Feedback Amount: + + NOISE + BRUS + + + + White Noise Amount: + + + + Invert Invertera @@ -2184,10 +2754,12 @@ Please make sure you have write permission to the file and the directory contain FxLine + Channel send amount - + Kanalsändningsbelopp + 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. @@ -2198,22 +2770,27 @@ You can remove and move FX channels in the context menu, which is accessed by ri + Move &left Flytta &vänster + Move &right Flytta &höger + Rename &channel Byt namn på &kanal + R&emove channel T&a bort kanal + Remove &unused channels Ta bort &oanvända kanaler @@ -2221,37 +2798,62 @@ You can remove and move FX channels in the context menu, which is accessed by ri FxMixer + Master Master + + + FX %1 FX %1 + + + Volume + Volym + + + + Mute + Tysta + + + + Solo + Solo + FxMixerView + FX-Mixer FX-Mixer + FX Fader %1 FX Fader %1 + Mute Tysta + Mute this FX channel Tysta denna FX-kanal + Solo Solo + Solo FX channel FX-kanal Solo @@ -2259,6 +2861,8 @@ You can remove and move FX channels in the context menu, which is accessed by ri FxRoute + + Amount to send from channel %1 to channel %2 Mängd att skicka från kanal %1 till kanal %2 @@ -2266,14 +2870,17 @@ You can remove and move FX channels in the context menu, which is accessed by ri GigInstrument + Bank Bank + Patch + Gain Förstärkning @@ -2281,46 +2888,58 @@ You can remove and move FX channels in the context menu, which is accessed by ri GigInstrumentView + Open other GIG file Öppna en annan GIG-fil + Click here to open another GIG file Klicka här för att öppna en annan GIG-fil + Choose the patch + Click here to change which patch of the GIG file to use + + Change which instrument of the GIG file is being played Välj vilket instrument i GIG-filen som ska spelas + Which GIG file is currently being used Vilken GIG-fil används för närvarande + Which patch of the GIG file is currently being used Vilken del av GIG-filen används för närvarande + Gain Förstärkning + Factor to multiply samples by Faktor att multiplicera samplingar med + Open GIG file Öppna GIG-fil + GIG Files (*.gig) GIG-filer (*.gig) @@ -2328,704 +2947,880 @@ You can remove and move FX channels in the context menu, which is accessed by ri GuiApplication + Working directory - Arbetskatalog + Arbetsmapp + The LMMS working directory %1 does not exist. Create it now? You can change the directory later via Edit -> Settings. - Arbetskatalogen %1 för LMMS existerar inte. Vill du skapa detta nu? Du kan ändra katalog senare under Redigera -> Inställningar. + Arbetsmappen %1 för LMMS finns inte. Vill du skapa denna nu? Du kan ändra mappen senare via Redigera -> Inställningar. + Preparing UI Förbereder användargränssnitt + Preparing song editor - Förbereder sång-editor + Förbereder låtredigeraren + Preparing mixer Förbereder mixer + Preparing controller rack Förbereder kontrollrack + Preparing project notes Förbereder projektanteckningar + Preparing beat/bassline editor - Förbereder Takt/Bas-editor + Förbereder takt/basgång-redigeraren + Preparing piano roll Förbereder pianorulle + Preparing automation editor - Förbereder automations-editor + Förbereder automationsredigeraren InstrumentFunctionArpeggio + Arpeggio Arpeggio + Arpeggio type Arpeggio-typ + Arpeggio range Arpeggio-omfång - Arpeggio time - Arpeggio-tid - - - Arpeggio gate + + Cycle steps - Arpeggio direction - Arpeggio-riktning - - - Arpeggio mode - Arpeggio-typ - - - Up - Upp - - - Down - Ner - - - Up and down - Upp och ner - - - Random - Slumpmässig - - - Free - - - - Sort - - - - Sync - - - - Down and up - Ner och upp - - + Skip rate + Miss rate - Cycle steps + + Arpeggio time + Arpeggio-tid + + + + Arpeggio gate + + + Arpeggio direction + Arpeggio-riktning + + + + Arpeggio mode + Arpeggio-typ + + + + Up + Upp + + + + Down + Ner + + + + Up and down + Upp och ner + + + + Down and up + Ner och upp + + + + Random + Slumpmässig + + + + Free + Fritt + + + + Sort + Sortera + + + + Sync + Synkronisera + 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 OMFÅNG + Arpeggio range: Arpeggio-omfång: + octave(s) oktav(er) + Use this knob for setting the arpeggio range in octaves. The selected arpeggio will be played within specified number of octaves. - TIME - TID - - - Arpeggio time: - Arpeggio-tid: - - - ms - ms - - - Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. - Använd denna ratt för att ställa arpeggio-tiden i millisekunder. Arpeggio-tiden anger hur länge varje arpeggio-ton ska spelas. - - - GATE - GATE - - - 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: - Ackord: - - - Direction: - Riktning: - - - Mode: - Läge: - - - SKIP - - - - Skip rate: - - - - 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. - - - + CYCLE + Cycle notes: + note(s) not(er) + 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 + + + + + Skip rate: + + + + + + + % + % + + + + 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 + TID + + + + Arpeggio time: + Arpeggio-tid: + + + + ms + ms + + + + Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. + Använd denna ratt för att ställa arpeggio-tiden i millisekunder. Arpeggio-tiden anger hur länge varje arpeggio-ton ska spelas. + + + + GATE + GATE + + + + 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: + Ackord: + + + + Direction: + Riktning: + + + + Mode: + Läge: + InstrumentFunctionNoteStacking + octave oktav + + Major - + Dur + Majb5 + minor - + moll + minb5 + sus2 + sus4 + aug + augsus4 + tri + 6 - + 6 + 6sus4 + 6add9 + m6 + m6add9 + 7 - + 7 + 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 + 7add13 + 7#11 - + 7#11 + Maj7 + Maj7b5 + Maj7#5 + Maj7#11 + Maj7add13 + m7 + m7b5 + m7b9 + m7add11 + m7add13 + m-Maj7 + m-Maj7add11 + m-Maj7add13 + 9 - + 9 + 9sus4 + add9 + 9#5 - + 9#5 + 9b5 - + 9b5 + 9#11 - + 9#11 + 9b13 - + 9b13 + Maj9 + Maj9sus4 + Maj9#5 + Maj9#11 + m9 + madd9 + m9b5 + m9-Maj7 + 11 - + 11 + 11b9 + Maj11 + m11 + m-Maj11 + 13 - + 13 + 13#9 - + 13#9 + 13b9 - + 13b9 + 13b5b9 - + 13b5b9 + Maj13 + m13 + m-Maj13 + Harmonic minor - + Harmonisk moll + Melodic minor - + Melodisk moll + Whole tone - + Hela tonen + Diminished - + Minskad + Major pentatonic + Minor pentatonic + Jap in sen + Major bebop + Dominant bebop + Blues - + Blues + Arabic - + Arabisk + Enigmatic - + Gåtfull + Neopolitan + Neopolitan minor + Hungarian minor + Dorian - Phrygolydian + + Phrygian + Lydian + Mixolydian + Aeolian + Locrian - Chords - Ackord - - - Chord type - Ackord-typ - - - Chord range - - - + Minor - + Moll + Chromatic - + Kromatisk + Half-Whole Diminished + 5 - + 5 + Phrygian dominant + Persian - + Persisk + + + + Chords + Ackord + + + + Chord type + Ackordtyp + + + + Chord range + Ackordomfång InstrumentFunctionNoteStackingView + + STACKING + STAPLA + + + + Chord: + Ackord: + + + RANGE OMFÅNG + Chord range: - + Ackordomfång: + octave(s) oktav(er) + Use this knob for setting the chord range in octaves. The selected chord will be played within specified number of octaves. - - STACKING - - - - Chord: - Ackord: - InstrumentMidiIOView + ENABLE MIDI INPUT AKTIVERA MIDI-INMATNING + + CHANNEL KANAL + + VELOCITY - + HASTIGHET + ENABLE MIDI OUTPUT - + AKTIVERA MIDI-UTGÅNG + PROGRAM - - - - MIDI devices to receive MIDI events from - - - - MIDI devices to send MIDI events to - + PROGRAM + NOTE - + NOT + + MIDI devices to receive MIDI events from + MIDI-enheter att ta emot MIDI-händelser från + + + + MIDI devices to send MIDI events to + MIDI-enheter att skicka MIDI-händelser till + + + CUSTOM BASE VELOCITY - + ANPASSAD BASHASTIGHET + Specify the velocity normalization base for MIDI-based instruments at 100% note velocity + BASE VELOCITY - + BASHASTIGHET InstrumentMiscView + MASTER PITCH + Enables the use of Master Pitch @@ -3033,126 +3828,158 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentSoundShaping + VOLUME VOLYM + Volume Volym + CUTOFF + + Cutoff frequency Cutoff frekvens + RESO RESO + Resonance Resonans + Envelopes/LFOs + Filter type Filtertyp + Q/Resonance Q/Resonans + LowPass Lågpass + HiPass Högpass + BandPass csg - + BandPass csg + BandPass czpg - + BandPass czpg + Notch + Allpass - + Allpass + Moog Moog + 2x LowPass 2x Lågpass + RC LowPass 12dB RC Lågpass 12dB + RC BandPass 12dB RC BandPass 12dB + RC HighPass 12dB RC Högpass 12dB + RC LowPass 24dB RC Lågpass 24dB + RC BandPass 24dB RC BandPass 24dB + RC HighPass 24dB RC Högpass 24dB + Vocal Formant Filter + 2x Moog - + 2x Moog + SV LowPass SV Lågpass + SV BandPass SV BandPass + SV HighPass SV Högpass + SV Notch + Fast Formant + Tripole @@ -3160,50 +3987,62 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentSoundShapingView + TARGET MÅL + 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. Här kan du välja vilket inbyggt filter du vill använda för detta instrument-spår. Filter är väldigt viktiga om man vill ändra karaktäristiken på ett ljud. - 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: - Resonans: - - - 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. - - - + FREQ - FREQ + FREKV. + cutoff frequency: cutoff-frekvens: + + 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: + Resonans: + + + + 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. @@ -3211,85 +4050,107 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentTrack - unnamed_track - namnlöst_spår - - - Volume - Volym - - - Panning - Panorering - - - Pitch - Tonhöjd - - - FX channel - FX-kanal - - - Default preset - Standardinställning - - + With this knob you can set the volume of the opened channel. Med denna ratt ställer du volymen för den öppnade kanalen. + + + unnamed_track + namnlöst_spår + + + Base note Grundton + + Volume + Volym + + + + Panning + Panorering + + + + Pitch + Tonhöjd + + + Pitch range Tonhöjdsomfång + + FX channel + FX-kanal + + + Master Pitch + + + + Default preset + Standardinställning + InstrumentTrackView + Volume Volym + Volume: Volym: + VOL VOL + Panning Panorering + Panning: Panorering: + PAN PAN + MIDI MIDI + Input Ingång + Output Utgång + FX %1: %2 FX %1: %2 @@ -3297,125 +4158,160 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentTrackWindow + GENERAL SETTINGS ÖVERGRIPANDE INSTÄLLNINGAR + + Use these controls to view and edit the next/previous track in the song editor. + Använd dessa kontroller för att visa och redigera nästa/föregående spår i låtredigeraren. + + + Instrument volume Instrument-volym + Volume: Volym: + VOL VOL + Panning Panorering + Panning: Panorering: + PAN PAN + Pitch Tonhöjd + Pitch: Tonhöjd: + cents + PITCH - FX channel - FX-kanal - - - ENV/LFO - - - - FUNC - - - - FX - - - - MIDI - MIDI - - - Save preset - Spara förinställning - - - XML preset file (*.xpf) - XML förinställnings-fil (*.xpf) - - - PLUGIN - - - + Pitch range (semitones) + RANGE OMFÅNG - Save current instrument track settings in a preset file - + + FX channel + FX-kanal + + FX + FX + + + + Save current instrument track settings in a preset file + Spara aktuella instrumentspårinställningar i en förinställd fil + + + 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. - MISC - - - - Use these controls to view and edit the next/previous track in the song editor. - - - + SAVE SPARA + + + Envelope, filter & LFO + + + + + Chord stacking & arpeggio + + + + + Effects + Effekter + + + + MIDI settings + MIDI-inställningar + + + + Miscellaneous + Diverse + + + + Save preset + Spara förinställning + + + + XML preset file (*.xpf) + XML förinställnings-fil (*.xpf) + + + + Plugin + Insticksmodul + Knob + Set linear - + Ställ in linjär + Set logarithmic - + Ställ in logaritmisk + Please enter a new value between -96.0 dBFS and 6.0 dBFS: - + Vänligen ange ett nytt värde mellan -96.0 dBFS och 6.0 dBFS: + Please enter a new value between %1 and %2: Ange ett nytt värde mellan %1 och %2: @@ -3423,6 +4319,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaControl + Link channels Länka kanaler @@ -3430,10 +4327,12 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaControlDialog + Link Channels Länka Kanaler + Channel Kanal @@ -3441,14 +4340,17 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaControlView + Link channels Länka kanaler + Value: Värde: + Sorry, no help available. Ledsen, ingen hjälp är tillgänglig. @@ -3456,13 +4358,15 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaEffect + Unknown LADSPA plugin %1 requested. - + Okänd LADSPA-insticksmodul %1 efterfrågad. LcdSpinBox + Please enter a new value between %1 and %2: Ange ett nytt värde mellan %1 och %2: @@ -3470,18 +4374,26 @@ You can remove and move FX channels in the context menu, which is accessed by ri LeftRightNav + + + Previous Tidigare + + + Next Nästa + Previous (%1) Tidigare (%1) + Next (%1) Nästa (%1) @@ -3489,145 +4401,180 @@ You can remove and move FX channels in the context menu, which is accessed by ri LfoController + LFO Controller + Base value Basvärde + Oscillator speed - + Oscillatorhastighet + Oscillator amount - + Oscillatormängd + Oscillator phase - + Oscillatorfas + Oscillator waveform - + Oscillatorvågform + Frequency Multiplier - + Frekvens Multiplikator LfoControllerDialog + LFO LFO + LFO Controller + BASE + Base amount: + todo + SPD - + SPD + LFO-speed: + Use this knob for setting speed of the LFO. The bigger this value the faster the LFO oscillates and the faster the effect. + + AMNT + + + + Modulation amount: Moduleringsmängd: + 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 + Phase offset: + degrees grader + 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. Klicka här för sinusvåg. + Click here for a triangle-wave. Klicka här för triangelvåg. + Click here for a saw-wave. - Klicka här för sågtandvåg + Klicka här för sågtandsvåg + Click here for a square-wave. - Klicka här för fyrkantvåg - - - Click here for an exponential wave. - - - - Click here for white-noise. - Klicka här för vitt brus. - - - Click here for a user-defined shape. -Double click to pick a file. - + Klicka här för fyrkantvåg. + Click here for a moog saw-wave. - AMNT + + Click here for an exponential wave. + + + Click here for white-noise. + Klicka här för vitt brus. + + + + Click here for a user-defined shape. +Double click to pick a file. + Klicka här för en användardefinierad form. +Dubbelklicka för att välja en fil. + LmmsCore + Generating wavetables + Initializing data structures - + Initierar datastrukturer + Opening audio and midi devices - + Öppnar ljud- och midienheter + Launching mixer threads @@ -3635,404 +4582,500 @@ Double click to pick a file. MainWindow - Could not save config-file - + + Configuration file + Konfigurationsfil - Could not save configuration file %1. You're probably not permitted to write to this file. -Please make sure you have write-access to the file and try again. - + + Error while parsing configuration file at line %1:%2: %3 + Fel vid inläsning av konfigurationsfil på rad %1:%2: %3 + + Could not open file + Kunde inte öppna fil + + + + 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! + Det gick inte att öppna filen %1 för att skriva. +Se till att du har skrivbehörighet till filen och mappen som innehåller filen och försök igen! + + + + Project recovery + Projektåterställning + + + + 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? + Det finns en återställningsfil tillgänglig. Det verkar som om programmet inte avslutades korrekt senast, eller så körs redan LMMS. Vill du återställa detta projekt? + + + + + + Recover + Återställ + + + + Recover the file. Please don't run multiple instances of LMMS when you do this. + Återställ filen. Se till att du bara har en instans av LMMS igång när du gör detta. + + + + + + Discard + Kasta bort + + + + Launch a default session and delete the restored files. This is not reversible. + Starta en standard-session och ta bort den återskapade filen. Detta går inte ångra. + + + + Version %1 + Version %1 + + + + Preparing plugin browser + Förbereder insticksmodulsbläddraren + + + + Preparing file browsers + Förbereder fil-browser + + + + My Projects + Mina projekt + + + + My Samples + Mina samplingar + + + + My Presets + Mina förinställningar + + + + My Home + Min hemmapp + + + + Root directory + Rotmapp + + + + Volumes + Volymer + + + + My Computer + Min dator + + + + Loading background artwork + Laddar bakgrunds-grafik + + + + &File + &Arkiv + + + &New &Ny + + New from template + Nytt från mall + + + &Open... &Öppna... + + &Recently Opened Projects + &Nyligen öppnade projekt + + + &Save &Spara + Save &As... Spara &som... + + Save as New &Version + Spara som ny &version + + + + Save as default template + Spara som standardmall + + + Import... Importera... + E&xport... E&xportera... + + E&xport Tracks... + E&xportera spår... + + + + Export &MIDI... + Exportera &MIDI... + + + &Quit &Avsluta + &Edit &Redigera + + Undo + Ångra + + + + Redo + Gör om + + + Settings Inställningar - &Tools - + + &View + &Visa + + &Tools + &Verktyg + + + &Help &Hjälp + + Online Help + Hjälp på nätet + + + Help Hjälp - What's this? - Vad är detta? + + What's This? + Vad är det här? + About Om + Create new project Skapa nytt projekt + Create new project from template Skapa nytt projekt från mall + Open existing project Öppna existerande projekt + Recently opened projects Nyligen öppnade projekt + Save current project Spara aktuellt projekt + Export current project Exportera aktuellt projekt - Song Editor - Sång-editor + + What's this? + Vad är detta? + + Toggle metronome + Slå på/av metronom + + + + Show/hide Song-Editor + Visa/dölj Låtredigeraren + + + 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. - + Genom att trycka på den här knappen kan du visa eller dölja Låtredigeraren. Med hjälp av Låtredigeraren kan du redigera låtspellista och ange när vilken låt ska spelas. Du kan också infoga och flytta samplingar (t.ex. rap-samplingar) direkt i spellistan. - Beat+Bassline Editor - Redigera Trummor+Bas + + Show/hide Beat+Bassline Editor + Visa/dölj Takt+Basgång-redigeraren + 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. - Piano Roll - Pianorulle + + Show/hide Piano-Roll + Visa/dölj pianorulle + Click here to show or hide the Piano-Roll. With the help of the Piano-Roll you can edit melodies in an easy way. Klicka här för att visa eller dölja pianorullen. Med hjälp av pianorullen kan du skapa melodier på ett enkelt sätt. - Automation Editor - Automations-editor + + Show/hide Automation Editor + Visa/dölj Automationsredigeraren + 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. - FX Mixer - + + Show/hide FX Mixer + Visa/dölj 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. - Project Notes - Projektanteckningar + + Show/hide project notes + Visa/dölj projektanteckningar + Click here to show or hide the project notes window. In this window you can put down your project notes. Klicka här för att visa eller dölja fönstret för projektanteckningar. I detta fönster kan du göra noteringar om ditt projekt, - Controller Rack - Kontrollrack + + Show/hide controller rack + Visa/dölj kontrollrack + Untitled Namnlös + + Recover session. Please save your work! + Återställnings-session. Spara ditt arbete! + + + LMMS %1 LMMS %1 - Project not saved - Projekt inte sparat + + Recovered project not saved + Återställt projekt inte sparat + + 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? + Projektet återställdes från den senaste sessionen. Det kommer försvinna om du inte sparar det. Vill du spara projektet nu? + + + + Project not saved + Projektet inte sparat + + + The current project was modified since last saving. Do you want to save it now? Projektet har ändrats sedan det sparades senast. Vill du spara nu? + + Open Project + Öppna projekt + + + + LMMS (*.mmp *.mmpz) + LMMS (*.mmp *.mmpz) + + + + Save Project + Spara projekt + + + + LMMS Project + LMMS-Projekt + + + + LMMS Project Template + LMMS-Projektmall + + + + Save project template + Spara projektmall + + + + Overwrite default template? + Vill du skriva över standardmallen? + + + + This will overwrite your current default template. + Detta kommer skriva över din nuvarande standardmall. + + + Help not available Hjälp inte tillgänglig + Currently there's no help available in LMMS. Please visit http://lmms.sf.net/wiki for documentation on LMMS. Just nu finns ingen hjälp tillgänglig i LMMS Besök https://lmms.io/documentation/ för dokumentation (Engelska). - LMMS (*.mmp *.mmpz) - + + Song Editor + Låtredigeraren - Version %1 - Version %1 + + Beat+Bassline Editor + Takt+Basgång-redigeraren - Configuration file - Konfigurationsfil + + Piano Roll + Pianorulle - Error while parsing configuration file at line %1:%2: %3 - Fel vid inläsning av konfigurationsfil på rad %1:%2: %3 + + Automation Editor + Automatiseringsredigeraren - Volumes - + + FX Mixer + FX-mixer - Undo - Ångra + + Project Notes + Projektanteckningar - Redo - Gör om - - - My Projects - Mina Projekt - - - My Samples - - - - My Presets - - - - My Home - - - - My Computer - Min dator - - - &File - &Fil - - - &Recently Opened Projects - &Nyligen öppnade projekt - - - Save as New &Version - Spara som Ny &Version - - - E&xport Tracks... - E&xportera spår... - - - Online Help - Online-hjälp - - - What's This? - Vad är det här? - - - Open Project - Öppna Projekt - - - Save Project - Spara Projekt - - - Project recovery - Projektåterställning - - - 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? - Det finns en återställningsfil tillgänglig. Det verkar som om programmet inte avslutades korrekt senast, eller så körs redan LMMS. Vill du återställa detta projekt? - - - Recover - Återställ - - - Recover the file. Please don't run multiple instances of LMMS when you do this. - Återställ filen. Se till att du bara har en instans av LMMS igång när du gör detta. - - - Ignore - Ignorera - - - Launch LMMS as usual but with automatic backup disabled to prevent the present recover file from being overwritten. - Starta LMMS som vanligt men med automatisk backup avstängt för att förhindra att den nuvarande återställningsfilen blir överskriven. - - - Discard - Kasta bort - - - Launch a default session and delete the restored files. This is not reversible. - Starta en standard-session och ta bort den återskapade filen. Detta går inte ångra. - - - Preparing plugin browser - Förbereder plugin-browser - - - Preparing file browsers - Förbereder fil-browser - - - Root directory - Rotkatalog - - - Loading background artwork - Laddar bakgrunds-grafik - - - New from template - Nytt från mall - - - Save as default template - Spara som standard-mall - - - &View - &Visa - - - Toggle metronome - Slå på/av metronom - - - Show/hide Song-Editor - Visa/dölj Sång-editor - - - Show/hide Beat+Bassline Editor - Visa/dölj Takt+Bas-editor - - - Show/hide Piano-Roll - Visa/dölj pianorulle - - - Show/hide Automation Editor - Visa/dölj Automations-editor - - - Show/hide FX Mixer - Visa/dölj FX Mixer - - - Show/hide project notes - Visa/dölj projektanteckningar - - - Show/hide controller rack - Visa/dölj kontrollrack - - - Recover session. Please save your work! - Återställnings-session. Spara ditt arbete! - - - Automatic backup disabled. Remember to save your work! - Automatisk backup avstängd. Kom ihåg att spara ditt arbete! - - - Recovered project not saved - Återställt projekt inte sparat - - - 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? - Projektet återställdes från den senaste sessionen. Det kommer försvinna om du inte sparar det. Vill du spara projektet nu? - - - LMMS Project - LMMS-Projekt - - - LMMS Project Template - LMMS-Projektmall - - - Overwrite default template? - Vill du skriva över standardmallen? - - - This will overwrite your current default template. - Detta kommer skriva över din nuvarande standardmall. + + Controller Rack + Kontrollrack + Volume as dBFS Volym som dBFS + Smooth scroll Mjuk rullning + Enable note labels in piano roll Visa noter i pianorulle - - Save project template - - MeterDialog + + Meter Numerator + + Meter Denominator + TIME SIG @@ -4040,107 +5083,130 @@ Besök https://lmms.io/documentation/ för dokumentation (Engelska). MeterModel + Numerator - + Täljare + Denominator - + Nämnare MidiController + MIDI Controller - + MIDI-styrenhet + unnamed_midi_controller - + unnamed_midi_controller MidiImport + + Setup incomplete Installation ofullständig + 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. - + Du har inte ställt in en standard soundfont i inställningsdialogrutan (Redigera->Inställningar). Därför spelas inget ljud upp efter att ha importerat denna MIDI-fil. Du bör hämta en allmän MIDI-soundfont, ange den i inställningsdialogrutan och försök igen. + 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. - + Du kompilerade inte LMMS med stöd för SoundFont2-spelaren, som används för att lägga till standardljud till importerade MIDI-filer. Därför spelas inget ljud upp efter att ha importerat denna MIDI-fil. + Track - + Spår MidiJack + JACK server down When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (title) - JACK server nerstängd + JACK-server nerstängd + The JACK server seems to be shuted down. When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (dialog message) - + JACK-servern verkar vara avstängd. MidiPort + Input channel Ingångskanal + Output channel Utgångskanal + Input controller Ingångskontroller + Output controller Utgångskontroller + Fixed input velocity - + Fast ingångshastighet + Fixed output velocity - + Fast utgångshastighet + + Fixed output note + Fast utgångsnot + + + Output MIDI program - + Utgång MIDI-program + + Base velocity + Bashastighet + + + Receive MIDI-events Ta emot MIDI-event + Send MIDI-events Skicka MIDI-event - - Fixed output note - Fast utgångs-not - - - Base velocity - - MidiSetupWidget + DEVICE ENHET @@ -4148,495 +5214,620 @@ Besök https://lmms.io/documentation/ för dokumentation (Engelska). MonstroInstrument + Osc 1 Volume Osc 1 Volym + Osc 1 Panning Osc 1 Panorering + 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 + Osc 2 Panning + 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 + Osc 3 Panning + 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 + LFO 1 Attack + LFO 1 Rate + LFO 1 Phase + LFO 2 Waveform + LFO 2 Attack + LFO 2 Rate + LFO 2 Phase + Env 1 Pre-delay + Env 1 Attack + 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 Vald vy + Vol1-Env1 + Vol1-Env2 + Vol1-LFO1 + Vol1-LFO2 + Vol2-Env1 + Vol2-Env2 + Vol2-LFO1 + Vol2-LFO2 + Vol3-Env1 + Vol3-Env2 + Vol3-LFO1 + Vol3-LFO2 + Phs1-Env1 + Phs1-Env2 + Phs1-LFO1 + Phs1-LFO2 + Phs2-Env1 + Phs2-Env2 + Phs2-LFO1 + Phs2-LFO2 + Phs3-Env1 + Phs3-Env2 + Phs3-LFO1 + Phs3-LFO2 + Pit1-Env1 + Pit1-Env2 + Pit1-LFO1 + Pit1-LFO2 + Pit2-Env1 + Pit2-Env2 + Pit2-LFO1 + Pit2-LFO2 + Pit3-Env1 + Pit3-Env2 + Pit3-LFO1 + Pit3-LFO2 + PW1-Env1 + PW1-Env2 + PW1-LFO1 + PW1-LFO2 + Sub3-Env1 + Sub3-Env2 + Sub3-LFO1 + Sub3-LFO2 + + Sine wave Sinusvåg + Bandlimited Triangle wave + Bandlimited Saw wave + Bandlimited Ramp wave + Bandlimited Square wave + Bandlimited Moog saw wave + + Soft square wave - + Mjuk fyrkantvåg + Absolute sine wave - + Absolut sinusvåg + + Exponential wave - + Exponentiell våg + White noise - + Vitt brus + Digital Triangle wave Digital Triangelvåg + Digital Saw wave Digital Sågtandsvåg + Digital Ramp wave + Digital Square wave + Digital Moog saw wave + Triangle wave Triangelvåg + Saw wave Sågtandsvåg + Ramp wave - + Rampvåg + Square wave Fyrkantvåg + Moog saw wave Moog sågtandsvåg + Abs. sine wave Abs. sinusvåg + Random Slumpmässig + Random smooth - + Slumpmässigt slät MonstroView + Operators view - + Operatörernas vy + 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 + 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. @@ -4645,256 +5836,407 @@ Each modulation target has 4 knobs, one for each modulator. By default the knobs + + + + Volume + Volym + + + + + + Panning + Panorering + + + + + + Coarse detune + + + + + + + semitones + halvtoner + + + + + Finetune left + + + + + + + + cents + + + + + + 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 + Värdera + + + + + Phase + Fas + + + + + Pre-delay + + + + + + Hold + Håll + + + + + Decay + Decay + + + + + Sustain + Sustain + + + + + Release + Släpp + + + + + Slope + Lutning + + + Mix Osc2 with Osc3 Mixa Osc2 med Osc3 + Modulate amplitude of Osc3 with Osc2 Modulera amplituden för Osc3 med Osc2 + Modulate frequency of Osc3 with Osc2 Modulera frekvensen för Osc3 med Osc2 + Modulate phase of Osc3 with Osc2 Modulera fasen för Osc3 med 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. - + Hard sync: varje gång oscillatorn tar emot en synkroniseringssignal från oscillator 1 återställs dess fas till 0 + vad dess fasförskjutning är. + + 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. Välj vågform för oscillator 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. - Volume - Volym - - - Panning - Panorering - - - Coarse detune - - - - semitones - halvtoner - - - Finetune left - - - - cents - - - - 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 - Värdera - - - Phase - - - - Pre-delay - - - - Hold - Håll - - - Decay - Decay - - - Sustain - Sustain - - - Release - Släpp - - - Slope - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Modulation amount Moduleringsmängd @@ -4902,34 +6244,42 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator MultitapEchoControlDialog + Length Längd + Step length: + Dry + Dry Gain: + Stages - + Stadier + Lowpass stages: + Swap inputs + Swap left and right input channel for reflections @@ -4937,82 +6287,102 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator NesInstrument + Channel 1 Coarse detune + Channel 1 Volume - + Kanal 1 volym + Channel 1 Envelope length + Channel 1 Duty cycle + Channel 1 Sweep amount + Channel 1 Sweep rate + Channel 2 Coarse detune + Channel 2 Volume - + Kanal 2 volym + Channel 2 Envelope length + Channel 2 Duty cycle + Channel 2 Sweep amount + Channel 2 Sweep rate + Channel 3 Coarse detune + Channel 3 Volume - + Kanal 3 volym + Channel 4 Volume - + Kanal 4 volym + Channel 4 Envelope length + Channel 4 Noise frequency + Channel 4 Noise frequency sweep + Master volume Huvudvolym + Vibrato @@ -5020,114 +6390,155 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator NesInstrumentView + + + + Volume Volym + + + Coarse detune + + + Envelope length + Enable channel 1 - + Aktivera kanal 1 + Enable envelope 1 + Enable envelope 1 loop + Enable sweep 1 - + Aktivera svep 1 + + Sweep amount - + Svepmängd + + Sweep rate - + Svephastighet + + 12.5% Duty cycle + + 25% Duty cycle + + 50% Duty cycle + + 75% Duty cycle + Enable channel 2 - + Aktivera kanal 2 + Enable envelope 2 + Enable envelope 2 loop + Enable sweep 2 + Enable channel 3 - + Aktivera kanal 3 + Noise Frequency - + Brusfrekvens + Frequency sweep + Enable channel 4 - + Aktivera kanal 4 + Enable envelope 4 + Enable envelope 4 loop + Quantize noise frequency when using note frequency - + Kvantifiera brusfrekvens vid användning av notfrekvens + Use note frequency for noise - + Använd notfrekvens för brus + Noise mode - + Brusläge + Master Volume - + Huvudvolym + Vibrato @@ -5135,81 +6546,103 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator OscillatorObject - Osc %1 volume - - - - Osc %1 panning - - - - Osc %1 coarse detuning - - - - Osc %1 fine detuning left - - - - Osc %1 fine detuning right - - - - Osc %1 phase-offset - - - - Osc %1 stereo phase-detuning - - - - Osc %1 wave shape - - - - Modulation type %1 - - - + Osc %1 waveform + Osc %1 harmonic + + + + Osc %1 volume + Osc %1 volym + + + + + Osc %1 panning + Osc %1 panorering + + + + + 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 + + + + + Modulation type %1 + Moduleringstyp %1 + PatchesDialog + Qsynth: Channel Preset - + Qsynth: Kanal förinställd + Bank selector - + Bankväljare + Bank Bank + Program selector - + Programväljare + Patch + Name Namn + OK OK + Cancel Avbryt @@ -5217,46 +6650,57 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PatmanView + Open other patch + Click here to open another patch-file. Loop and Tune settings are not reset. + Loop - + Slinga + Loop mode - + Slinga-läge + Here you can toggle the Loop mode. If enabled, PatMan will use the loop information available in the file. + Tune - + Tune + Tune mode - + Tune-läge + Here you can toggle the Tune mode. If enabled, PatMan will tune the sample to match the note's frequency. + No file selected Ingen fil vald + Open patch file Öppna patch-fil + Patch-Files (*.pat) Patch-filer (*.pat) @@ -5264,53 +6708,65 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PatternView - Open in piano-roll - Öppna i pianorulle - - - Clear all notes - Rensa alla noter - - - Reset name - Nollställ namn - - - Change name - Byt namn - - - Add steps - Lägg till steg - - - Remove steps - Ta bort steg - - + use mouse wheel to set velocity of a step - + använd mushjulet för att ställa in hastigheten på ett steg + double-click to open in Piano Roll Dubbelklicka för att öppna i Pianorulle + + Open in piano-roll + Öppna i pianorulle + + + + Clear all notes + Rensa alla noter + + + + Reset name + Nollställ namn + + + + Change name + Byt namn + + + + Add steps + Lägg till steg + + + + Remove steps + Ta bort steg + + + Clone Steps - Klona steg + Klona Steg 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. @@ -5318,10 +6774,12 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PeakControllerDialog + PEAK + LFO Controller @@ -5329,353 +6787,438 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PeakControllerEffectControlDialog + BASE + Base amount: - Modulation amount: - Moduleringsmängd: - - - Attack: - Attack: - - - Release: - Release: - - + AMNT + + Modulation amount: + Moduleringsmängd: + + + MULT + Amount Multiplicator: + ATCK + + Attack: + Attack: + + + DCAY - Treshold: + + Release: + Release: + + + + TRSH - TRSH - + + Treshold: + Tröskelvärde: PeakControllerEffectControls + Base value Basvärde + Modulation amount Moduleringsmängd - Mute output - Tysta utgångs-ljud - - + Attack Attack + Release Släpp + + Treshold + Tröskelvärde + + + + Mute output + Tysta utgångs-ljud + + + Abs Value Abs-värde + Amount Multiplicator - - Treshold - - PianoRoll - Please open a pattern by double-clicking on it! - Dubbelklicka för att öppna ett mönster! - - - Last note - Senaste noten - - - Note lock - - - + Note Velocity - + Nothastighet + Note Panning Not-panorering + Mark/unmark current semitone Markera/avmarkera nuvarande halvton + + Mark/unmark all corresponding octave semitones + Markera/avmarkera alla motsvarande oktavhalvtoner + + + Mark current scale Markera nuvarande skala + Mark current chord Markera nuvarande ackord + Unmark all Avmarkera allt + + Select all notes on this key + Välj alla noter på denna tangent + + + + Note lock + Notlås + + + + Last note + Senaste noten + + + No scale Ingen skala + No chord Inget ackord + Velocity: %1% - + Hastighet: %1% + Panning: %1% left Panorering: %1% vänster + Panning: %1% right Panorering: %1% höger + Panning: center Panorering: center + + Please open a pattern by double-clicking on it! + Dubbelklicka för att öppna ett mönster! + + + + Please enter a new value between %1 and %2: Ange ett nytt värde mellan %1 och %2: - - Mark/unmark all corresponding octave semitones - - - - Select all notes on this key - Välj alla noter på denna tangent - PianoRollWindow + Play/pause current pattern (Space) Spela/pausa aktuellt mönster (mellanslag) + Record notes from MIDI-device/channel-piano Spela in noter från MIDI-enhet/kanal-piano + Record notes from MIDI-device/channel-piano while playing song or BB track Spela in noter från MIDI-enhet/kanal-piano medan sång eller BB-spår spelas + Stop playing of current pattern (Space) Sluta spela aktuellt mönster (mellanslag) + Click here to play the current pattern. This is useful while editing it. The pattern is automatically looped when its end is reached. Klicka här för att spela det aktuella mönstret, detta är användbart när man redigerar. Mönstret spelas från början igen när det nått sitt slut. + 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. Klicka här för att stoppa uppspelning av de aktuella mönstret. - Draw mode (Shift+D) - Ritläge (Shift+D) - - - Erase mode (Shift+E) - Suddläge (Shift+E) - - - Select mode (Shift+S) - Markeringsläge (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. - - - - Cut selected notes (%1+X) - Klipp ut valda noter (%1+X) - - - Copy selected notes (%1+C) - Kopiera valda noter (%1+C) - - - Paste notes from clipboard (%1+V) - Klistra in noter (%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. - - - - 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. - - - + Edit actions Redigera åtgärder + + Draw mode (Shift+D) + Ritläge (Skift+D) + + + + Erase mode (Shift+E) + Suddläge (Skift+E) + + + + Select mode (Shift+S) + Markeringsläge (Skift+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. + Klicka här och ritläget kommer att aktiveras. I det här läget kan du lägga till, ändra storlek och flytta anteckningar. Detta är standardläget som används för det mesta. Du kan också trycka på 'Shift+D' på tangentbordet för att aktivera det här läget. I det här läget håller du %1 intryckt för att tillfälligt gå in i välja-läget. + + + + 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. + Klicka här och radera-läge kommer att aktiveras. I det här läget kan du radera anteckningar. Du kan också trycka på "Skift+E" på tangentbordet för att aktivera det här läget. + + + + 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. + Klicka här och välja-läget aktiveras. I det här läget kan du välja anteckningar. Alternativt kan du hålla %1 i ritläget för att tillfälligt använda välja-läget. + + + + 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) + Klipp ut valda noter (%1+X) + + + + Copy selected notes (%1+C) + Kopiera valda noter (%1+C) + + + + Paste notes from clipboard (%1+V) + Klistra in noter (%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. + Klicka här och de valda noterna kommer att klippas ut till urklipp. Du kan klistra in dem var som helst i något mönster genom att klicka på knappen klistra in. + + + + 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. + Klicka här och de valda anteckningarna kopieras till urklipp. Du kan klistra in dem var som helst i något mönster genom att klicka på knappen klistra in. + + + + Click here and the notes from the clipboard will be pasted at the first visible measure. + + + + Timeline controls Tidslinjekontroller + 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 Pianorulle - %1 + + Piano-Roll - no pattern Pianorulle - inget mönster - - Quantize - - PianoView + Base note - Bas-not + Basnot Plugin + Plugin not found - Plugin hittades inte + Instickmodulen hittades inte + The plugin "%1" wasn't found or could not be loaded! Reason: "%2" - Pluginet "%1" hittades inte eller kunde inte laddas! + Instickmodulen "%1" hittades inte eller kunde inte läsas in! Orsak: "%2" + Error while loading plugin - Fel vid inläsning av plugin + Fel vid inläsning av instickmodulen + Failed to load plugin "%1"! - Misslyckades att läsa in plugin "%1"! + Misslyckades att läsa in insticksmodulen "%1"! PluginBrowser - Instrument browser - - - - Drag an instrument into either the Song-Editor, the Beat+Bassline Editor or into an existing instrument track. - - - + Instrument Plugins - + Instrument insticksmoduler + + + + Instrument browser + Instrument bläddrare + + + + Drag an instrument into either the Song-Editor, the Beat+Bassline Editor or into an existing instrument track. + Dra ett instrument till antingen Låtredigeraren, Takt+Basgång-redigeraren eller till ett befintligt instrument spår. PluginFactory + Plugin not found. - Plugin hittades inte. + Insticksmodulen hittades inte. + LMMS plugin %1 does not have a plugin descriptor named %2! @@ -5683,118 +7226,147 @@ Orsak: "%2" ProjectNotes - Project notes + + Project Notes Projektanteckningar - Put down your project notes here. - Skriv ner dina anteckningar för projektet här. + + Enter project notes here + + Edit Actions - Redigera Händelser + Redigera Åtgärder + &Undo &Ångra + %1+Z - + %1+Z + &Redo &Gör om + %1+Y - + %1+Y + &Copy &Kopiera + %1+C - + %1+C + Cu&t Klipp u&t + %1+X - + %1+X + &Paste &Klistra in + %1+V %1+V + Format Actions + &Bold &Fet + %1+B %1+B + &Italic &Kursiv + %1+I %1+I + &Underline &Understruken + %1+U %1+U + &Left &Vänster + %1+L %1+L + C&enter C&entrera + %1+E %1+E + &Right &Höger + %1+R %1+R + &Justify - + &Justera + %1+J %1+J + &Color... &Färg... @@ -5802,185 +7374,326 @@ Orsak: "%2" ProjectRenderer + WAV-File (*.wav) WAV-Fil (*.wav) + Compressed OGG-File (*.ogg) Komprimerad OGG-Fil (*.ogg) + + + Compressed MP3-File (*.mp3) + Komprimerad MP3-fil ( *.mp3) + QWidget + + + Name: Namn: + + Maker: Skapare: + + Copyright: Copyright: + + Requires Real Time: + + + + + + Yes Ja + + + + + + No Nej + + Real Time Capable: + + In Place Broken: + + Channels In: Kanaler In: + + Channels Out: Kanaler Ut: - File: - Fil: - - + File: %1 Fil: %1 + + + File: + Fil: + RenameDialog + Rename... Byt namn... + + ReverbSCControlDialog + + + Input + Ingång + + + + Input Gain: + Input Förstärkning: + + + + Size + Storlek + + + + Size: + Storlek: + + + + Color + Färg + + + + Color: + Färg: + + + + Output + Utgång + + + + Output Gain: + Output Förstärkning + + + + ReverbSCControls + + + Input Gain + Ingångsförstärkning + + + + Size + Storlek + + + + Color + Färg + + + + Output Gain + Utgångsförstärkning + + SampleBuffer + + Fail to open file + Misslyckas med att öppna filen + + + + Audio files are limited to %1 MB in size and %2 minutes of playing time + Ljudfiler är begränsade till %1 MB i storlek och %2 minuters speltid + + + Open audio file Öppna ljudfil - Wave-Files (*.wav) - Wave-Filer (*.wav) - - - OGG-Files (*.ogg) - OGG-Filer (*.ogg) - - - DrumSynth-Files (*.ds) - - - - FLAC-Files (*.flac) - FLAC-Filer (*.flac) - - - SPEEX-Files (*.spx) - - - - VOC-Files (*.voc) - VOC-Filer - (*.voc) - - - AIFF-Files (*.aif *.aiff) - AIFF-Filer (*.aif *.aiff) - - - AU-Files (*.au) - AU-Filer (*.au) - - - RAW-Files (*.raw) - RAW-Filer (*.raw) - - + All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) - Alla Ljudfiler (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + Alla ljudfiler (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + + + + Wave-Files (*.wav) + Wave-filer (*.wav) + + + + OGG-Files (*.ogg) + OGG-filer (*.ogg) + + + + DrumSynth-Files (*.ds) + DrumSynth-filer (*.ds) + + + + FLAC-Files (*.flac) + FLAC-filer (*.flac) + + + + SPEEX-Files (*.spx) + SPEEX-filer (*.spx) + + + + VOC-Files (*.voc) + VOC-filer (*.voc) + + + + AIFF-Files (*.aif *.aiff) + AIFF-filer (*.aif *.aiff) + + + + AU-Files (*.au) + AU-filer (*.au) + + + + RAW-Files (*.raw) + RAW-filer (*.raw) SampleTCOView + double-click to select sample dubbelklicka för att välja ljudfil + Delete (middle mousebutton) Ta bort (musens mitt-knapp) + Cut Klipp ut + Copy Kopiera + Paste Klistra in + Mute/unmute (<%1> + middle click) - + Tysta/avtysta (<%1> + mittenklick) SampleTrack - Sample track - Ljudfils-spår - - + Volume Volym + Panning Panorering + + + + Sample track + Ljudspår + SampleTrackView + Track volume - + Spårvolym + Channel volume: - + Kanalvolym: + VOL VOL + Panning Panorering + Panning: Panorering: + PAN PAN @@ -5988,494 +7701,658 @@ Orsak: "%2" SetupDialog + Setup LMMS - Inställningar + Ställ in LMMS + + General settings - + Allmänna inställningar + BUFFER SIZE - + BUFFERTSTORLEK + + Reset to default-value Återställ till standardvärde + MISC + Enable tooltips - Aktivera verktygs-tips + Aktivera verktygstips + Show restart warning after changing settings - + Visa omstartsvarning efter att ha ändrat inställningar + Display volume as dBFS Visa volym som dBFS + Compress project files per default Komprimera projektfiler som standard + One instrument track window mode + HQ-mode for output audio-device - + HQ-läge för ljudenhetsutgång + Compact track buttons - + Kompakta spårknappar + Sync VST plugins to host playback + Enable note labels in piano roll Visa noter i pianorulle + Enable waveform display by default - + Aktivera vågformsvisning som standard + Keep effects running even without input - + Håll effekter igång även utan ingång + Create backup file when saving a project Skapa en backup-fil när ett projekt sparas + + Reopen last project on start + Öppna senaste projektet vid start + + + + Use built-in NaN handler + Använd inbyggd NaN-hanterare + + + + PLUGIN EMBEDDING + + + + + No embedding + + + + + Embed using Qt API + + + + + Embed using native Win32 API + + + + + Embed using XEmbed protocol + + + + LANGUAGE SPRÅK + + Paths Sökvägar - LMMS working directory - LMMS arbetskatalog - - - VST-plugin directory - Katalog för VST-plugin - - - Background artwork - - - - STK rawwave directory - Katalog för STK vågformer - - - Default Soundfont File - - - - Performance settings - - - - UI effects vs. performance - - - - Smooth scroll in Song Editor - Mjuk rullning i Sång-editorn - - - Show playback cursor in AudioFileProcessor - - - - Audio settings - - - - AUDIO INTERFACE - - - - MIDI settings - MIDI-inställningar - - - MIDI INTERFACE - - - - OK - OK - - - Cancel - Avbryt - - - Restart LMMS - Starta om LMMS - - - Please note that most changes won't take effect until you restart LMMS! - Många av ändringarna kommer inte gälla förrän LMMS startats om! - - - 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 - Välj arbetskatalog för LMMS - - - Choose your VST-plugin directory - Välj katalog för dina VST-plugin - - - Choose artwork-theme directory - Välj katalog för gränssnitts-tema - - - Choose LADSPA plugin directory - Välj katalog för LADSPA-plugin - - - Choose STK rawwave directory - Välj katalog för STK-råfiler - - - Choose default SoundFont - Välj standard-SoundFont - - - Choose background artwork - Välj bakgrunds-grafik - - - 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. - - - - Reopen last project on start - - - + Directories Kataloger + + LMMS working directory + LMMS-arbetsmapp + + + Themes directory - Katalog för teman + Mapp för teman + + Background artwork + Bakgrund konstverk + + + + VST-plugin directory + Mapp för VST-insticksmoduler + + + GIG directory - Katalog för GIG-filer + Mapp för GIG-filer + SF2 directory - Katalog för SF2-filer + Mapp för SF2-filer + LADSPA plugin directories - Katalog för LADSPA-plugins + Katalog för LADSPA-insticksmoduler + + STK rawwave directory + Mapp för STK rå-vågform + + + + Default Soundfont File + Standard Soundfont-fil + + + + + Performance settings + Prestandainställningar + + + Auto save - Autospara + Spara automatiskt + + Enable auto-save + Aktivera automatisk sparande + + + + Allow auto-save while playing + Tillåt automatisk sparande när du spelar + + + + UI effects vs. performance + UI-effekter vs. prestanda + + + + Smooth scroll in Song Editor + Mjuk rullning i Låtredigeraren + + + + Show playback cursor in AudioFileProcessor + Visa uppspelningsmarkören i AudioFileProcessor + + + + + Audio settings + Ljudinställningar + + + + AUDIO INTERFACE + LJUDGRÄNSSNITT + + + + + MIDI settings + MIDI-inställningar + + + + MIDI INTERFACE + MIDIGRÄNSSNITT + + + + OK + OK + + + + Cancel + Avbryt + + + + Restart LMMS + Starta om LMMS + + + + Please note that most changes won't take effect until you restart LMMS! + Många av ändringarna kommer inte gälla förrän LMMS startats om! + + + + Frames: %1 +Latency: %2 ms + Ramar: %1 +Latens: %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. + Här kan du ställa in den interna buffertstorleken som används av LMMS. Mindre värden resulterar i en lägre latens men kan också orsaka oanvändbart ljud eller dålig prestanda, särskilt på äldre datorer eller system med en icke-realtidskernel. + + + + Choose LMMS working directory + Välj LMMS-arbetsmapp + + + Choose your GIG directory - Välj din GIG-katalog + Välj din GIG-mapp + Choose your SF2 directory - Välj din SF2-katalog + Välj din SF2-mapp + + Choose your VST-plugin directory + Välj mapp för dina VST-insticksmoduler + + + + Choose artwork-theme directory + Välj mapp för gränssnitts-tema + + + + Choose LADSPA plugin directory + Välj mapp för LADSPA-insticksmoduler + + + + Choose STK rawwave directory + Välj mapp för STK-rawwave + + + + Choose default SoundFont + Välj standard-SoundFont + + + + Choose background artwork + Välj bakgrunds-grafik + + + minutes minuter + minute minut - Enable auto-save - - - - Allow auto-save while playing - - - + Disabled - + Inaktiverad + Auto-save interval: %1 - + Automatiskt sparande intervall: %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. + + Song + Tempo Tempo + Master volume Huvudvolym + Master pitch - Project saved - Projekt sparat - - - The project %1 is now saved. - Projektet %1 är nu sparat. - - - Project NOT saved. - Projektet är INTE sparat. - - - The project %1 was not saved! - Projektet %1 sparades inte! - - - Import file - Importera fil - - - MIDI sequences - MIDI-sekvenser - - - Hydrogen projects - - - - All file types - Alla filtyper - - - Empty project - Tomt projekt - - - This project is empty so exporting makes no sense. Please put some items into Song Editor first! - Projektet är tomt, export är meningslöst. Skapa något i Sång-editorn innan du exporterar! - - - Select directory for writing exported tracks... - - - - untitled - namnlös - - - Select file for project-export... - - - - The following errors occured while loading: - - - - MIDI File (*.mid) - MIDI-fil (*.mid) - - + LMMS Error report LMMS Felrapport - Save project + + Project saved + Projekt sparat + + + + The project %1 is now saved. + Projektet %1 är nu sparat. + + + + Project NOT saved. + Projektet är INTE sparat. + + + + The project %1 was not saved! + Projektet %1 sparades inte! + + + + Import file + Importera fil + + + + MIDI sequences + MIDI-sekvenser + + + + Hydrogen projects + + + All file types + Alla filtyper + + + + + Empty project + Tomt projekt + + + + + This project is empty so exporting makes no sense. Please put some items into Song Editor first! + Projektet är tomt, export är meningslöst. Skapa något i Låtredigeraren innan du exporterar! + + + + Select directory for writing exported tracks... + Välj mapp för att skriva exporterade spår... + + + + + untitled + namnlös + + + + + Select file for project-export... + Välj fil för projekt-export... + + + + Save project + Spara projekt + + + + MIDI File (*.mid) + MIDI-fil (*.mid) + + + + The following errors occured while loading: + Följande fel inträffade under inläsning: + SongEditor + Could not open file - kunde inte öppna fil + Kunde inte öppna fil + + 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. + Det gick inte att öppna filen %1. Du har förmodligen inga behörigheter att läsa den här filen. + Se till att ha åtminstone läsbehörigheter till filen och försök igen. + + + Could not write file Kunde inte skriva fil - 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. - - - - Error in file - Fil-fel - - - The file %1 seems to contain errors and therefore can't be loaded. - - - - Tempo - Tempo - - - TEMPO/BPM - TEMPO/BPM - - - tempo of song - Sångtempo - - - 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 - - - - Master volume - Huvudvolym - - - master volume - huvudvolym - - - Master pitch - - - - master pitch - - - - Value: %1% - Värde: %1% - - - Value: %1 semitones - Värde: %1 halvtoner - - + 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. - + Det gick inte att öppna %1 för att skriva. Du har förmodligen inte tillåtelse att skriva till den här filen. Se till att du har skrivåtkomst till filen och försök igen. - template - mall + + Error in file + Fel i filen - project - projekt + + The file %1 seems to contain errors and therefore can't be loaded. + Filen %1 verkar innehålla fel och kan därför inte läsas in. + Version difference Versions-skillnad + This %1 was created with LMMS %2. + Detta %1 skapades med LMMS %2. + + + + template + mall + + + + project + projekt + + + + Tempo + Tempo + + + + TEMPO/BPM + TEMPO/BPM + + + + tempo of song + Sångtempo + + + + 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 + Hög kvalitet läge + + + + + Master volume + Huvudvolym + + + + master volume + huvudvolym + + + + + Master pitch + + + + + master pitch + + + + + Value: %1% + Värde: %1% + + + + Value: %1 semitones + Värde: %1 halvtoner + SongEditorWindow + Song-Editor - Sång-Editor + Låtredigerare + Play song (Space) Spela sång (Mellanslag) + Record samples from Audio-device - + Spela in samplingar från ljudenheten + Record samples from Audio-device while playing song or BB track - + Spela in samplingar från ljudenheten medan du spelar låten eller BB-spåret + Stop song (Space) Sluta spela sång (Mellanslag) - Add beat/bassline - Lägg till trummor/bas - - - Add sample-track - Lägg till ljudfils-spår - - - Add automation-track - Lägg till automationsspår - - - Draw mode - Ritläge - - - Edit mode (select and move) - Redigeringsläge (välj och flytta) - - + 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. - + Klicka här, om du vill spela hela din låt. Uppspelningen startas vid sångplaceringsmarkören (grön). Du kan också flytta den medan du spelar. + 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 - + Spåråtgärder + + Add beat/bassline + Lägg till takt/basgång + + + + Add sample-track + Lägg till ljudspår + + + + Add automation-track + Lägg till automationsspår + + + Edit actions Redigera åtgärder + + Draw mode + Ritläge + + + + Edit mode (select and move) + Redigeringsläge (välj och flytta) + + + Timeline controls Tidslinjekontroller + Zoom controls Zoomningskontroller @@ -6483,10 +8360,12 @@ Remember to also save your project manually. You can choose to disable saving wh SpectrumAnalyzerControlDialog + Linear spectrum - + Linjärt spektrum + Linear Y axis Linjär Y-axel @@ -6494,29 +8373,35 @@ Remember to also save your project manually. You can choose to disable saving wh SpectrumAnalyzerControls + Linear spectrum - + Linjärt spektrum + Linear Y axis Linjär Y-axel + Channel mode - + Kanalläge SubWindow + Close Stäng + Maximize Maximera + Restore Återställ @@ -6524,6 +8409,8 @@ Remember to also save your project manually. You can choose to disable saving wh TabWidget + + Settings for %1 Inställningar för %1 @@ -6531,105 +8418,131 @@ Remember to also save your project manually. You can choose to disable saving wh TempoSyncKnob + + Tempo Sync - + Temposynkronisering + No Sync - + Ingen synkronisering + Eight beats Åtta takter + Whole note Hel-not + Half note Halvnot + Quarter note - + Fjärdedelsnot + 8th note - + 8:e noten + 16th note - + 16:e noten + 32nd note - + 32:e noten + Custom... - + Anpassad... + Custom - + Anpassad + Synced to Eight Beats - + Synkroniserad till Åtta Takter + Synced to Whole Note - + Synkroniserad till helnoten + Synced to Half Note - + Synkroniserad till halvnoten + Synced to Quarter Note - + Synkroniserad till fjärdedelsnoten + Synced to 8th Note - + Synkroniserad till 8:e noten + Synced to 16th Note - + Synkroniserad till 16:e noten + Synced to 32nd Note - + Synkroniserad till 32:e noten TimeDisplayWidget + click to change time units Klicka för att ändra tidsenheter + MIN MIN + SEC SEK + MSEC MSEK + BAR + BEAT TAKT + TICK TICK @@ -6637,45 +8550,56 @@ Remember to also save your project manually. You can choose to disable saving wh TimeLineWidget + Enable/disable auto-scrolling - + Aktivera/inaktivera automatisk rullning + Enable/disable loop-points - + Aktivera/inaktivera loop-punkter + After stopping go back to begin - + Efter att ha stoppat gå tillbaka till början + After stopping go back to position at which playing was started - + Efter att ha stoppat gå tillbaka till position där spelningen startades + After stopping keep position - + Efter stopp behåll positionen + + Hint Ledtråd + Press <%1> to disable magnetic loop points. - + Tryck på <%1> för att inaktivera magnetiska slingpunkter. + Hold <Shift> to move the begin loop point; Press <%1> to disable magnetic loop points. - + Håll nedtryckt för att flytta startlooppunkten; tryck på <%1> för att inaktivera magnetiska slingpunkter. Track + Mute Tysta + Solo Solo @@ -6683,38 +8607,63 @@ Remember to also save your project manually. You can choose to disable saving wh TrackContainer + Couldn't import file Kunde inte importera filen + Couldn't find a filter for importing file %1. You should convert this file into a format supported by LMMS using another software. Kunde inte hitta ett filter för att importera filen %1. -Du bör konvertera filen till ett format som stöd av LMMS genom att använda ett annat program. +Du bör konvertera filen till ett format som stöds av LMMS genom att använda ett annat program. + Couldn't open file Kunde inte öppna filen + 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! Kunde inte öppna filen %1 för läsning. -Se till att du har läsrättigheter för filen och katalogen som innehåller filen och försök igen! +Se till att du har läsrättigheter för filen och mappen som innehåller filen och försök igen! + Loading project... Läser in projekt... + + Cancel Avbryt + + Please wait... Vänligen vänta... + + Loading cancelled + Inläsningen avbruten + + + + Project loading was cancelled. + Projektinläsningen avbröts. + + + + Loading Track %1 (%2/Total %3) + Läser in spår %1 (%2/Totalt %3) + + + Importing MIDI-file... Importerar MIDI-fil... @@ -6722,6 +8671,7 @@ Se till att du har läsrättigheter för filen och katalogen som innehåller fil TrackContentObject + Mute Tysta @@ -6729,346 +8679,435 @@ Se till att du har läsrättigheter för filen och katalogen som innehåller fil TrackContentObjectView + Current position Aktuell position + + Hint Ledtråd + Press <%1> and drag to make a copy. Håll nere <%1> och dra för att kopiera. + Current length Aktuell längd + Press <%1> for free resizing. + + %1:%2 (%3:%4 to %5:%6) %1:%2 (%3:%4 till %5:%6) + Delete (middle mousebutton) Ta bort (musens mitt-knapp) + Cut Klipp ut + Copy Kopiera + Paste Klistra in + Mute/unmute (<%1> + middle click) - + Tysta/avtysta (<%1> + mittenklick) TrackOperationsWidget + Press <%1> while clicking on move-grip to begin a new drag'n'drop-action. + Actions for this track - + Åtgärder för detta spår + Mute Tysta + + Solo Solo + Mute this track Tysta detta spår + Clone this track Klona detta spår + Remove this track Ta bort detta spår + Clear this track Rensa detta spår + FX %1: %2 FX %1: %2 - Turn all recording on - - - - Turn all recording off - - - + Assign to new FX Channel Koppla till ny FX-kanal + + + Turn all recording on + Slå på all inspelning + + + + Turn all recording off + Slå av all inspelning + 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 + Synchronize oscillator 1 with oscillator 2 - + Synkronisera oscillatorn 1 med oscillatorn 2 + Use frequency modulation for modulating oscillator 1 with oscillator 2 - + Använd frekvensmodulering för modulerande oscillator 1 med oscillator 2 + Use phase modulation for modulating oscillator 2 with oscillator 3 + Use amplitude modulation for modulating oscillator 2 with oscillator 3 - + Använd amplitudmodulering för modulerande oscillator 2 med oscillator 3 + Mix output of oscillator 2 & 3 + Synchronize oscillator 2 with oscillator 3 - + Synkronisera oscillatorn 2 med oscillatorn 3 + Use frequency modulation for modulating oscillator 2 with oscillator 3 + Osc %1 volume: - + Osc %1 volym: + 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. - + Med denna knapp kan du ställa in volymen av oscillator %1. När du ställer in ett värde på 0 stängs oscillatorn av. Annars kan du höra oscillatorn så hög som du ställer in den här. + Osc %1 panning: - + Osc %1 panorering: + 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 halvtoner + 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 + 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 grader + 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. + Use a triangle-wave for current oscillator. + Use a saw-wave for current oscillator. + Use a square-wave for current oscillator. + Use a moog-like saw-wave for current oscillator. + Use an exponential wave for current oscillator. - + Använd en exponentiell våg för aktuell oscillator. + Use white-noise for current oscillator. + Use a user-defined waveform for current oscillator. - + Använd en användardefinierad vågform för nuvarande oscillator. VersionedSaveDialog + Increment version number + Decrement version number + already exists. Do you want to replace it? - + finns redan. Vill du ersätta den? 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. - Show/hide GUI - Visa/dölj användargränssnitt - - - Click here to show or hide the graphical user interface (GUI) of your VST-plugin. - - - - Turn off all notes - - - - Open VST-plugin - Öppna VST-plugin - - - DLL-files (*.dll) - DLL-filer (*.dll) - - - EXE-files (*.exe) - EXE-filer (*.exe) - - - No VST-plugin loaded - - - + Control VST-plugin from LMMS host - Kontrollera VST-plugin från LMMS-värd + Kontrollera VST-insticksmodulen från LMMS-värd + Click here, if you want to control VST-plugin from host. - + Klicka här om du vill styra VST-insticksmodulen från värd. + Open VST-plugin preset + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. - + Klicka här om du vill öppna en annan *.fxp, *.FXB VST-insticksmodulsförinställning. + Previous (-) Tidigare (-) + + Click here, if you want to switch to another VST-plugin preset program. - + Klicka här om du vill byta till ett annat VST-insticksmodulsförinställningsprogram. + Save preset Spara förinställning + Click here, if you want to save current VST-plugin preset program. + Next (+) Nästa (+) + Click here to select presets that are currently loaded in VST. + + Show/hide GUI + Visa/dölj användargränssnitt + + + + Click here to show or hide the graphical user interface (GUI) of your VST-plugin. + + + + + Turn off all notes + Stäng av alla noter + + + + Open VST-plugin + Öppna VST-insticksmodul + + + + DLL-files (*.dll) + DLL-filer (*.dll) + + + + EXE-files (*.exe) + EXE-filer (*.exe) + + + + No VST-plugin loaded + Ingen VST-insticksmodul inläst + + + Preset Förinställning + by av + - VST plugin control @@ -7076,10 +9115,12 @@ Se till att du har läsrättigheter för filen och katalogen som innehåller fil VisualizationWidget + click to enable/disable visualization of master-output + Click to enable Klicka för att aktivera @@ -7087,54 +9128,69 @@ Se till att du har läsrättigheter för filen och katalogen som innehåller fil VstEffectControlDialog + Show/hide Visa/dölj + Control VST-plugin from LMMS host Kontrollera VST-plugin från LMMS-värd + Click here, if you want to control VST-plugin from host. - + Klicka här om du vill styra VST-insticksmodulen från värd. + Open VST-plugin preset + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. - + Klicka här om du vill öppna en annan *.fxp, *.fxb VST-insticksmodulsförinställning. + Previous (-) Tidigare (-) + + Click here, if you want to switch to another VST-plugin preset program. - + Klicka här om du vill byta till ett annat VST-insticksmodulsförinställningsprogram. + Next (+) Nästa (+) + Click here to select presets that are currently loaded in VST. + Save preset Spara förinställning + Click here, if you want to save current VST-plugin preset program. + + Effect by: Effekt skapad av: + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> @@ -7142,387 +9198,509 @@ Se till att du har läsrättigheter för filen och katalogen som innehåller fil VstPlugin - Loading plugin - Laddar plugin + + + The VST plugin %1 could not be loaded. + VST-insticksmodulen %1 kunde inte läsas in. + Open Preset Öppna Förinställning + + Vst Plugin Preset (*.fxp *.fxb) + : default : standard + " " + ' ' + Save Preset Spara Förinställning + .fxp .fxp + .FXP .FXP + .FXB .FXB + .fxb .fxb - Please wait while loading VST plugin... - Vänta medan VST-plugin läses in... + + Loading plugin + Läser in insticksmodulen - The VST plugin %1 could not be loaded. - + + Please wait while loading VST plugin... + Vänligen vänta medan VST-instickmodulen läses in... WatsynInstrument + Volume A1 Volym A1 + Volume A2 Volym A2 + Volume B1 Volym B2 + Volume B2 Volym B2 + Panning A1 - + Panorering A1 + Panning A2 - + Panorering A2 + Panning B1 - + Panorering B1 + Panning B2 - + Panorering 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 + Right detune B1 + Right detune B2 + 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 - + A2-A1 modulering + B2-B1 modulation - + B2-B1 modulering + Selected graph - + Vald graf WatsynView - Select oscillator A1 - - - - Select oscillator A2 - - - - Select oscillator B1 - - - - Select oscillator B2 - - - - Mix output of A2 to A1 - - - - Modulate amplitude of A1 with output of A2 - - - - Ring-modulate A1 and A2 - - - - Modulate phase of A1 with output of A2 - - - - Mix output of B2 to B1 - - - - Modulate amplitude of B1 with output of B2 - - - - Ring-modulate B1 and B2 - - - - Modulate phase of B1 with output of B2 - - - - Draw your own waveform here by dragging your mouse on this graph. - - - - Load waveform - Ladda vågform - - - Click to load a waveform from a sample file - Klicka för att ladda in en vågform från en ljudfil - - - Phase left - - - - Click to shift phase by -15 degrees - - - - Phase right - - - - Click to shift phase by +15 degrees - - - - Normalize - Normalisera - - - Click to normalize - Klicka för normalisering - - - Invert - Invertera - - - Click to invert - Klicka för invertering - - - Smooth - Utjämna - - - Click to smooth - Klicka för utjämning - - - Sine wave - Sinusvåg - - - Click for sine wave - Klicka för sinusvåg - - - Triangle wave - Triangelvåg - - - Click for triangle wave - Klicka för triangelvåg - - - Click for saw wave - Klicka för sågtandvåg - - - Square wave - Fyrkantvåg - - - Click for square wave - - - + + + + Volume Volym + + + + Panning Panorering + + + + Freq. multiplier + + + + Left detune + + + + + + + + cents + + + + Right detune + A-B Mix + Mix envelope amount + Mix envelope attack + Mix envelope hold + Mix envelope decay + Crosstalk + + + Select oscillator A1 + Välj oscillator A1 + + + + Select oscillator A2 + Välj oscillator A2 + + + + Select oscillator B1 + Välj oscillator B1 + + + + Select oscillator B2 + Välj oscillator B2 + + + + Mix output of A2 to A1 + + + + + Modulate amplitude of A1 with output of A2 + + + + + Ring-modulate A1 and A2 + + + + + Modulate phase of A1 with output of A2 + + + + + Mix output of B2 to B1 + Blanda utgång B2 till B1 + + + + Modulate amplitude of B1 with output of B2 + + + + + Ring-modulate B1 and B2 + + + + + Modulate phase of B1 with output of B2 + + + + + + + + Draw your own waveform here by dragging your mouse on this graph. + Rita din egen vågform här genom att dra musen på den här grafen. + + + + Load waveform + Ladda vågform + + + + Click to load a waveform from a sample file + Klicka för att ladda in en vågform från en ljudfil + + + + Phase left + Fas vänster + + + + Click to shift phase by -15 degrees + Klicka för att flytta fas med -15 grader + + + + Phase right + Fas höger + + + + Click to shift phase by +15 degrees + + + + + Normalize + Normalisera + + + + Click to normalize + Klicka för normalisering + + + + Invert + Invertera + + + + Click to invert + Klicka för invertering + + + + Smooth + Utjämna + + + + Click to smooth + Klicka för utjämning + + + + Sine wave + Sinusvåg + + + + Click for sine wave + Klicka för sinusvåg + + + + + Triangle wave + Triangelvåg + + + + Click for triangle wave + Klicka för triangelvåg + + + + Click for saw wave + Klicka för sågtandsvåg + + + + Square wave + Fyrkantvåg + + + + Click for square wave + Klicka för fyrkantvåg + ZynAddSubFxInstrument + Portamento + Filter Frequency + Filter Resonance + Bandwidth Bandbredd + FM Gain FM-Förstärkning + Resonance Center Frequency + Resonance Bandwidth - + Resonans Bandbredd + Forward MIDI Control Change Events @@ -7530,121 +9708,150 @@ Se till att du har läsrättigheter för filen och katalogen som innehåller fil ZynAddSubFxView - Show GUI - Visa användargränssnitt - - - Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. - Klicka här för att visa eller dölja användargränssnittet för ZynAddSubFX. - - + Portamento: Portamento: + PORT - + PORT + Filter Frequency: Filter-frekvens: + FREQ FREQ + Filter Resonance: Filter-resonans: + RES + Bandwidth: Bandbredd: + BW + FM Gain: FM-Förstärkning: + FM GAIN + Resonance center frequency: - + Resonanscenterfrekvens: + RES CF + Resonance bandwidth: - + Resonans bandbredd: + RES BW + Forward MIDI Control Changes + + + Show GUI + Visa användargränssnitt + + + + Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. + Klicka här för att visa eller dölja användargränssnittet för ZynAddSubFX. + audioFileProcessor + Amplify Amplifiera + Start of sample Start på ljudfil + End of sample Slut på ljudfil + + Loopback point + Loopback punkt + + + Reverse sample Spela baklänges - Stutter - - - - Loopback point - - - + Loop mode - + Slinga-läge + + Stutter + Stamning + + + Interpolation mode - + Interpoleringsläge + None - + Ingen + Linear Linjär + Sinc + Sample not found: %1 Ljudfil hittades inte: %1 @@ -7652,6 +9859,7 @@ Se till att du har läsrättigheter för filen och katalogen som innehåller fil bitInvader + Samplelength Ljudfilslängd @@ -7659,165 +9867,205 @@ Se till att du har läsrättigheter för filen och katalogen som innehåller fil bitInvaderView + Sample Length Ljudfilens Längd + + Draw your own waveform here by dragging your mouse on this graph. + Rita din egen vågform här genom att dra musen på den här grafen. + + + Sine wave Sinusvåg - Triangle wave - Triangelvåg - - - Saw wave - Sågtandsvåg - - - Square wave - Fyrkantvåg - - - White noise wave - Vitt brus-våg - - - User defined wave - Användardefinierad vågform - - - Smooth - Utjämna - - - Click here to smooth waveform. - - - - Interpolation - Interpolering - - - Normalize - Normalisera - - - Draw your own waveform here by dragging your mouse on this graph. - - - + Click for a sine-wave. Klicka för sinusvåg + + Triangle wave + Triangelvåg + + + Click here for a triangle-wave. Klicka här för triangelvåg. + + Saw wave + Sågtandsvåg + + + Click here for a saw-wave. - Klicka här för sågtandvåg + Klicka här för sågtandsvåg + + Square wave + Fyrkantvåg + + + Click here for a square-wave. - Klicka här för fyrkantvåg + Klicka här för fyrkantvåg. + + White noise wave + Vitt brus-våg + + + Click here for white-noise. Klicka här för vitt brus. + + User defined wave + Användardefinierad vågform + + + Click here for a user-defined shape. Klicka här för en användardefinierad kurva. + + + Smooth + Utjämna + + + + Click here to smooth waveform. + Klicka här för att jämna vågform. + + + + Interpolation + Interpolering + + + + Normalize + Normalisera + dynProcControlDialog + INPUT INGÅNG + Input gain: Ingångsförstärkning: + OUTPUT UTGÅNG + Output gain: Utgångsförstärkning: + ATTACK - + ATTACK + Peak attack time: + RELEASE + Peak release time: + Reset waveform Återställ vågform + Click here to reset the wavegraph back to default + Smooth waveform Mjuk vågform + Click here to apply smoothing to wavegraph + Increase wavegraph amplitude by 1dB + Click here to increase wavegraph amplitude by 1dB - + Klicka här för att öka våggrafamplituden med 1 dB + Decrease wavegraph amplitude by 1dB - + Minska våggrafamplituden med 1dB + Click here to decrease wavegraph amplitude by 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 @@ -7825,22 +10073,27 @@ Se till att du har läsrättigheter för filen och katalogen som innehåller fil dynProcControls + Input gain Ingångsförstärkning + Output gain Utgångsförstärkning + Attack time - + Attacktid + Release time + Stereo mode Stereo-läge @@ -7848,10 +10101,12 @@ Se till att du har läsrättigheter för filen och katalogen som innehåller fil fxLineLcdSpinBox + Assign to: Tilldela till: + New FX Channel Ny FX-Kanal @@ -7859,6 +10114,7 @@ Se till att du har läsrättigheter för filen och katalogen som innehåller fil graphModel + Graph Graf @@ -7866,93 +10122,115 @@ Se till att du har läsrättigheter för filen och katalogen som innehåller fil kickerInstrument + Start frequency Startfrekvens + End frequency Slutfrekvens - Gain - Förstärkning - - + Length Längd + Distortion Start + Distortion End + + Gain + Förstärkning + + + Envelope Slope + Noise Brus + Click Klick + Frequency Slope + Start from note - + Starta från not + End to note - + Sluta på not kickerInstrumentView + Start frequency: - + Startfrekvens: + End frequency: - - - - Gain: - Förstärkning: + Slutfrekvens: + Frequency Slope: + + Gain: + Förstärkning: + + + Envelope Length: + Envelope Slope: + Click: Klick: + Noise: Brus: + Distortion Start: + Distortion End: @@ -7960,26 +10238,37 @@ Se till att du har läsrättigheter för filen och katalogen som innehåller fil ladspaBrowserView + + Available Effects - + Tillgängliga effekter + + Unavailable Effects - + Otillgängliga effekter + + Instruments Instrument + + Analysis Tools Analysverktyg + + Don't know Vet inte + 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. @@ -7996,6 +10285,7 @@ Double clicking any of the plugins will bring up information on the ports. + Type: Typ: @@ -8003,10 +10293,12 @@ Double clicking any of the plugins will bring up information on the ports. ladspaDescription + Plugins - Plugin + Insticksmoduler + Description Beskrivning @@ -8014,66 +10306,83 @@ Double clicking any of the plugins will bring up information on the ports. ladspaPortDialog + Ports Portar + Name Namn + Rate Värdera + Direction Riktning + Type Typ + Min < Default < Max Min < Standard < Max + Logarithmic Logaritmisk + SR Dependent + Audio Ljud + Control Kontroll + Input Ingång + Output Utgång + Toggled - + Växlad + Integer Heltal + Float Flyttal + + Yes Ja @@ -8081,46 +10390,57 @@ Double clicking any of the plugins will bring up information on the ports. lb302Synth + VCF Cutoff Frequency + VCF Resonance + VCF Envelope Mod + VCF Envelope Decay + Distortion - + Förvrängning + Waveform Vågform + Slide Decay + Slide + Accent + Dead + 24dB/oct Filter @@ -8128,122 +10448,153 @@ Double clicking any of the plugins will bring up information on the ports. lb302SynthView + Cutoff Freq: + Resonance: Resonans: + Env Mod: + Decay: Decay: + 303-es-que, 24dB/octave, 3 pole filter + Slide Decay: + DIST: + Saw wave Sågtandsvåg + Click here for a saw-wave. - Klicka här för sågtandvåg + Klicka här för sågtandsvåg + Triangle wave Triangelvåg + Click here for a triangle-wave. Klicka här för triangelvåg. + Square wave Fyrkantvåg + Click here for a square-wave. Klicka här för fyrkantvåg + Rounded square wave + Click here for a square-wave with a rounded end. + Moog wave + Click here for a moog-like wave. + Sine wave Sinusvåg + Click for a sine-wave. Klicka för sinusvåg + + White noise wave Vitt brus-våg + Click here for an exponential wave. + Click here for white-noise. Klicka här för vitt brus. + 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. @@ -8251,268 +10602,334 @@ Double clicking any of the plugins will bring up information on the ports. malletsInstrument + Hardness - + Hårdhet + Position Position + Vibrato Gain + Vibrato Freq + Stick Mix + Modulator - + Modulator + Crossfade - + Överbländning + LFO Speed - + LFO hastighet + LFO Depth + ADSR - + ADSR + Pressure - + Tryck + Motion - + Rörelse + Speed Hastighet + Bowed + Spread + Marimba + Vibraphone + Agogo + Wood1 + Reso + Wood2 + Beats - + Takter + Two Fixed + Clump + Tubular Bells + Uniform Bar + Tuned Bar + Glass + Tibetan Bowl - + Tibetansk skål malletsInstrumentView + Instrument - + Instrument + Spread + Spread: + + Missing files + Saknade filer + + + + Your Stk-installation seems to be incomplete. Please make sure the full Stk-package is installed! + Din Stk-installation verkar vara ofullständig. Se till att hela Stk-paketet är installerat! + + + Hardness - + Hårdhet + Hardness: - + Hårdhet: + Position Position + Position: Position: + Vib Gain + Vib Gain: + Vib Freq + Vib Freq: + Stick Mix + Stick Mix: + Modulator - + Modulator + Modulator: - + Modulator: + Crossfade - + Överbländning + Crossfade: - + Överbländning: + LFO Speed - + LFO hastighet + LFO Speed: + LFO Depth + LFO Depth: + ADSR - + ADSR + ADSR: - + ADSR: + Pressure - + Tryck + Pressure: - + Tryck: + Speed Hastighet + Speed: Hastighet: - - Missing files - - - - Your Stk-installation seems to be incomplete. Please make sure the full Stk-package is installed! - - manageVSTEffectView + - VST parameter control + VST Sync + Click here if you want to synchronize all parameters with VST plugin. + + Automated Automatiserad + Click here if you want to display automated parameters only. - + Klicka här om du bara vill visa automatiska parametrar. + Close Stäng + Close VST effect knob-controller window. @@ -8520,30 +10937,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 Automatiserad + Click here if you want to display automated parameters only. - + Klicka här om du bara vill visa automatiserade parametrar. + Close Stäng + Close VST plugin knob-controller window. @@ -8551,118 +10977,147 @@ Double clicking any of the plugins will bring up information on the ports. opl2instrument + Patch + Op 1 Attack + Op 1 Decay + Op 1 Sustain + Op 1 Release + Op 1 Level + Op 1 Level Scaling + Op 1 Frequency Multiple + Op 1 Feedback + 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 @@ -8670,18 +11125,26 @@ Double clicking any of the plugins will bring up information on the ports. opl2instrumentView + + Attack Attack + + Decay Decay + + Release - Släpp + Release + + Frequency multiplier @@ -8689,10 +11152,12 @@ Double clicking any of the plugins will bring up information on the ports. organicInstrument + Distortion - + Förvrängning + Volume Volym @@ -8700,351 +11165,458 @@ Double clicking any of the plugins will bring up information on the ports. organicInstrumentView + Distortion: - - - - Volume: - Volym: - - - Randomise - Slumpa - - - Osc %1 waveform: - - - - Osc %1 volume: - - - - Osc %1 panning: - - - - cents - + Förvrängning: + The distortion knob adds distortion to the output of the instrument. + + Volume: + Volym: + + + The volume knob controls the volume of the output of the instrument. It is cumulative with the instrument window's volume control. + + Randomise + Slumpa + + + The randomize button randomizes all knobs except the harmonics,main volume and distortion knobs. + Knappen randomisera randomiserar alla rattar utom reglagen övertoner, huvudvolym och distorsion. + + + + + Osc %1 waveform: + + Osc %1 volume: + Osc %1 volym: + + + + Osc %1 panning: + Osc %1 panorering: + + + Osc %1 stereo detuning - Osc %1 harmonic: + + cents + + + Osc %1 harmonic: + Osc %1 harmonisk: + papuInstrument + Sweep time + Sweep direction + Sweep RtShift amount + + Wave Pattern Duty + Channel 1 volume - + Kanal 1 volym + + + Volume sweep direction + + + Length of each step in sweep + Channel 2 volume - + Kanal 2 volym + Channel 3 volume - + Kanal 3 volym + Channel 4 volume + Kanal 4 volym + + + + Shift Register width + Right Output level + Left Output level + Channel 1 to SO2 (Left) - + Kanal 1 till SO2 (vänster) + Channel 2 to SO2 (Left) - + Kanal 2 till SO2 (vänster) + Channel 3 to SO2 (Left) - + Kanal 3 till SO2 (vänster) + Channel 4 to SO2 (Left) - + Kanal 4 till SO2 (Vänster) + Channel 1 to SO1 (Right) - + Kanal 1 till SO1 (Höger) + Channel 2 to SO1 (Right) - + Kanal 2 till SO1 (höger) + Channel 3 to SO1 (Right) - + Kanal 3 till SO1 (höger) + Channel 4 to SO1 (Right) - + Kanal 4 till SO1 (höger) + Treble - + Diskant + Bass Bas - - Shift Register width - - papuInstrumentView + Sweep Time: + Sweep Time + + The amount of increase or decrease in frequency + Mängden ökning eller minskning av frekvensen + + + Sweep RtShift amount: + Sweep RtShift amount - Wave pattern duty: - - - - Wave Pattern Duty - - - - Square Channel 1 Volume: - - - - Length of each step in sweep: - - - - Length of each step in sweep - - - - 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: - Bas: - - - Bass - Bas - - - 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 - - - - The amount of increase or decrease in frequency - - - + 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 - Draw the wave here + + Wave pattern duty + + + Square Channel 2 Volume: + + + + + + Square Channel 2 Volume + + + + + Wave Channel Volume: + + + + + + Wave Channel Volume + Volym för vågkanalen + + + + Noise Channel Volume: + + + + + + Noise Channel Volume + + + + + SO1 Volume (Right): + SO1 volym (höger): + + + + SO1 Volume (Right) + + + + + SO2 Volume (Left): + SO2 volym (vänster): + + + + SO2 Volume (Left) + + + + + Treble: + Diskant: + + + + Treble + Diskant + + + + Bass: + Bas: + + + + Bass + Bas + + + + Sweep Direction + + + + + + + + + Volume Sweep Direction + + + + + Shift Register Width + + + + + Channel1 to SO1 (Right) + + + + + Channel2 to SO1 (Right) + Channel2 till SO1 (höger) + + + + Channel3 to SO1 (Right) + + + + + Channel4 to SO1 (Right) + Channel4 till SO1 (höger) + + + + Channel1 to SO2 (Left) + + + + + Channel2 to SO2 (Left) + Channel2 till SO2 (Vänster) + + + + Channel3 to SO2 (Left) + Channel3 till SO2 (vänster) + + + + Channel4 to SO2 (Left) + + + + + Wave Pattern + Vågmönster + + + + Draw the wave here + Rita vågen här + patchesDialog + Qsynth: Channel Preset - + Qsynth: Kanal förinställd + Bank selector - + Bankväljare + Bank Bank + Program selector - + Programväljare + Patch + Name Namn + OK OK + Cancel Avbryt @@ -9052,238 +11624,301 @@ Double clicking any of the plugins will bring up information on the ports. pluginBrowser + no description ingen beskrivning - Incomplete monophonic imitation tb303 + + A native amplifier plugin + En inbyggd förstärkare-insticksmodul + + + + Simple sampler with various settings for using samples (e.g. drums) in an instrument-track + Enkel sampler med olika inställningar för att använda samplingar (t. ex. trummor) i ett instrumentspår + + + + Boost your bass the fast and simple way + Öka din bas på snabbt och enkelt sätt + + + + Customizable wavetable synthesizer - Plugin for freely manipulating stereo output + + An oversampling bitcrusher - Plugin for controlling knobs with sound peaks + + Carla Patchbay Instrument - Plugin for enhancing stereo separation of a stereo input file + + Carla Rack Instrument + + A 4-band Crossover Equalizer + + + + + A native delay plugin + En inbyggd fördröjning-insticksmodul + + + + A Dual filter plugin + En Dual filter-insticksmodul + + + + plugin for processing dynamics in a flexible way + insticksmodul för dynamisk bearbetning på ett flexibelt sätt + + + + A native eq plugin + En inbyggd eq-insticksmodul + + + + A native flanger plugin + + + + + Player for GIG files + Spelare för GIG-filer + + + + Filter for importing Hydrogen files into LMMS + Filter för att importera Hydrogen-filer till LMMS + + + + Versatile drum synthesizer + Mångsidig trum-synth + + + List installed LADSPA plugins - - - - GUS-compatible patch instrument - - - - Additive Synthesizer for organ-like sounds - - - - Tuneful things to bang on - - - - VST-host for using VST(i)-plugins within LMMS - - - - Vibrating string modeler - + Lista installerade LADSPA-insticksmoduler + plugin for using arbitrary LADSPA-effects inside LMMS. + + Incomplete monophonic imitation tb303 + + + + + Filter for exporting MIDI-files from LMMS + Filter för att exportera MIDI-filer från LMMS + + + Filter for importing MIDI-files into LMMS Filter för att importera MIDI-filer till LMMS + + Monstrous 3-oscillator synth with modulation matrix + + + + + A multitap echo delay plugin + + + + + A NES-like synthesizer + En NES-lik synthesizer + + + + 2-operator FM Synth + + + + + Additive Synthesizer for organ-like sounds + + + + + Emulation of GameBoy (TM) APU + Emulering av GameBoy (TM) APU + + + + GUS-compatible patch instrument + + + + + Plugin for controlling knobs with sound peaks + + + + + Reverb algorithm by Sean Costello + + + + + Player for SoundFont files + Spelare för SoundFont-filer + + + + LMMS port of sfxr + + + + Emulation of the MOS6581 and MOS8580 SID. This chip was used in the Commodore 64 computer. - Player for SoundFont files - Spelare för SoundFont-filer + + Graphical spectrum analyzer plugin + Grafiska spektrumanalysator insticksmodul - Emulation of GameBoy (TM) APU - Emulering av GameBoy (TM) APU + + Plugin for enhancing stereo separation of a stereo input file + Insticksmodul för att förbättra stereoseparation av en stereoingångsfil - Customizable wavetable synthesizer + + Plugin for freely manipulating stereo output - Embedded ZynAddSubFX - - - - 2-operator FM Synth - - - - Filter for importing Hydrogen files into LMMS - Filter för att importera Hydrogen-filer till LMMS - - - LMMS port of sfxr - - - - Monstrous 3-oscillator synth with modulation matrix + + Tuneful things to bang on + Three powerful oscillators you can modulate in several ways - A native amplifier plugin + + VST-host for using VST(i)-plugins within LMMS - Carla Rack Instrument - - - - 4-oscillator modulatable wavetable synth - - - - plugin for waveshaping - - - - Boost your bass the fast and simple way - - - - Versatile drum synthesizer - Mångsidig trum-synth - - - Simple sampler with various settings for using samples (e.g. drums) in an instrument-track - - - - plugin for processing dynamics in a flexible way - - - - Carla Patchbay Instrument + + Vibrating string modeler + plugin for using arbitrary VST effects inside LMMS. - Graphical spectrum analyzer plugin + + 4-oscillator modulatable wavetable synth - A NES-like synthesizer - En NES-lik synthesizer + + plugin for waveshaping + insticksmodul för vågformande - A native delay plugin - - - - Player for GIG files - Spelare för GIG-filer - - - A multitap echo delay plugin - - - - A native flanger plugin - - - - An oversampling bitcrusher - - - - A native eq plugin - - - - A 4-band Crossover Equalizer - - - - A Dual filter plugin - - - - Filter for exporting MIDI-files from LMMS + + Embedded ZynAddSubFX sf2Instrument + Bank Bank + Patch + Gain Förstärkning + Reverb - + Reverb + Reverb Roomsize + Reverb Damping + Reverb Width + Reverb Level + Chorus - + Chorus + Chorus Lines + Chorus Level + Chorus Speed + Chorus Depth + A soundfont %1 could not be loaded. SoundFont %1 kunde inte läsas in. @@ -9291,74 +11926,92 @@ This chip was used in the Commodore 64 computer. sf2InstrumentView + Open other SoundFont file Öppna en annan SoundFont-fil + Click here to open another SF2 file Klicka här för att öppna en annan SF2-fil + Choose the patch + Gain Förstärkning + Apply reverb (if supported) - + Applicera reverb (om det stöds) + This button enables the reverb effect. This is useful for cool effects, but only works on files that support it. - + Denna knapp aktiverar reverb-effekten. Detta är användbart för häftiga effekter, men fungerar bara på filer som stöder den. + Reverb Roomsize: + Reverb Damping: + Reverb Width: + Reverb Level: + Apply chorus (if supported) - + Applicera chorus (om det stöds) + This button enables the chorus effect. This is useful for cool echo effects, but only works on files that support it. - + Denna knapp aktiverar köreffekten. Detta är användbart för coola eko effekter, men fungerar bara på filer som stöder den. + Chorus Lines: + Chorus Level: + Chorus Speed: + Chorus Depth: + Open SoundFont file - + Öppna SoundFont-fil + SoundFont2 Files (*.sf2) SoundFont2-filer (*.sf2) @@ -9366,6 +12019,7 @@ This chip was used in the Commodore 64 computer. sfxrInstrument + Wave Form Vågform @@ -9373,26 +12027,32 @@ This chip was used in the Commodore 64 computer. sidInstrument + Cutoff + Resonance Resonans + Filter type Filtertyp + Voice 3 off - + Röst 3 av + Volume Volym + Chip model @@ -9400,134 +12060,172 @@ This chip was used in the Commodore 64 computer. sidInstrumentView + Volume: Volym: + Resonance: Resonans: + + Cutoff frequency: + High-Pass filter Högpassfilter + Band-Pass filter Bandpassfilter + Low-Pass filter Lågpassfilter + Voice3 Off - + Voice3 Av + 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. - + Attack-hastigheten bestämmer hur snabbt utgången för Voice %1 stiger från noll till toppamplitud. + + 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: Pulsbredd: + 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: Grov: + The Coarse detuning allows to detune Voice %1 one octave up or down. - + Den grova detuningen gör det möjligt att detunera Voice %1 en oktav upp eller ner. + Pulse Wave Pulsvåg + Triangle Wave Triangelvåg + SawTooth Sågtand + Noise Brus + Sync - + Synkronisera + 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 Filtrerad + 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 Testa + Test, when set, resets and locks Oscillator %1 at zero until Test is turned off. @@ -9535,10 +12233,12 @@ This chip was used in the Commodore 64 computer. stereoEnhancerControlDialog + WIDE + Width: Bredd: @@ -9546,6 +12246,7 @@ This chip was used in the Commodore 64 computer. stereoEnhancerControls + Width Bredd @@ -9553,91 +12254,111 @@ This chip was used in the Commodore 64 computer. stereoMatrixControlDialog + Left to Left Vol: Vänster till Vänster Vol.: + Left to Right Vol: Vänster till Höger Vol.: + Right to Left Vol: Höger till Vänster Vol.: + Right to Right Vol: - + Höger till Höger vol.: stereoMatrixControls + Left to Left - Vänster till vänster + Vänster till Vänster + Left to Right - Vänster till höger + Vänster till Höger + Right to Left - Höger till vänster + Höger till Vänster + Right to Right - Höger till höger + Höger till Höger vestigeInstrument + Loading plugin - Laddar plugin + Läser in plugin + Please wait while loading VST-plugin... - Vänta medans VST-plugin läses in... + Vänta medans VST-insticksmodulen läses in... vibed + String %1 volume - + Sträng %1 volym + String %1 stiffness - + Sträng %1 styvhet + Pick %1 position - + Välj %1 position + Pickup %1 position + Pan %1 + Detune %1 + Fuzziness %1 - + Oskärpa %1  + Length %1 Längd %1 + Impulse %1 Impuls %1 + Octave %1 Oktav %1 @@ -9645,90 +12366,112 @@ This chip was used in the Commodore 64 computer. vibedView + Volume: Volym: + The 'V' knob sets the volume of the selected string. + String stiffness: - + Strängstyvhet: + 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: + 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. - + "P" - ratten ställer in den position där den valda strängen kommer att "plockas". Ju lägre inställningen desto närmare plockningen är till bridgen. + Pickup position: + 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: + The Pan knob determines the location of the selected string in the stereo field. + 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: - + Oskärpa: + 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: Längd: + 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 Oktav + 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 + 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. @@ -9739,6 +12482,7 @@ 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. @@ -9753,188 +12497,233 @@ The LED in the lower right corner of the waveform editor determines whether the + Enable waveform - + Aktivera vågform + Click here to enable/disable waveform. - + Klicka här för att aktivera/inaktivera vågform. + String Sträng + 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 Sinusvåg - Triangle wave - Triangelvåg - - - Saw wave - Sågtandsvåg - - - Square wave - Fyrkantvåg - - - White noise wave - Vitt brus-våg - - - User defined wave - Användardefinierad vågform - - - Smooth - Utjämna - - - Click here to smooth waveform. - - - - Normalize - Normalisera - - - Click here to normalize waveform. - - - + Use a sine-wave for current oscillator. + + Triangle wave + Triangelvåg + + + Use a triangle-wave for current oscillator. + + Saw wave + Sågtandsvåg + + + Use a saw-wave for current oscillator. + + Square wave + Fyrkantvåg + + + Use a square-wave for current oscillator. + + White noise wave + Vitt brus-våg + + + Use white-noise for current oscillator. + + User defined wave + Användardefinierad vågform + + + Use a user-defined waveform for current oscillator. - + Använd en användardefinierad vågform för aktuell oscillator. + + + + Smooth + Utjämna + + + + Click here to smooth waveform. + Klicka här för att jämna vågform. + + + + Normalize + Normalisera + + + + Click here to normalize waveform. + Klicka här för att normalisera vågformen. voiceObject + Voice %1 pulse width - + Röst %1 pulsbredd + Voice %1 attack - + Röst %1 attack + Voice %1 decay + Voice %1 sustain + Voice %1 release + Voice %1 coarse detuning + Voice %1 wave shape + Voice %1 sync + Voice %1 ring modulate + Voice %1 filtered - + Röst %1 filtrerad + Voice %1 test - + Röst %1 test waveShaperControlDialog + INPUT INGÅNG + Input gain: Ingångsförstärkning: + OUTPUT UTGÅNG + Output gain: Utgångsförstärkning: + Reset waveform Återställ vågform + Click here to reset the wavegraph back to default + Smooth waveform Mjuk vågform + Click here to apply smoothing to wavegraph + Increase graph amplitude by 1dB - + Öka grafamplituden med 1dB + Click here to increase wavegraph amplitude by 1dB - + Klicka här för att öka våggrafamplituden med 1dB + Decrease graph amplitude by 1dB - + Minska grafamplituden med 1dB + Click here to decrease wavegraph amplitude by 1dB + Clip input + Clip input signal to 0dB @@ -9942,12 +12731,14 @@ The LED in the lower right corner of the waveform editor determines whether the waveShaperControls + Input gain Ingångsförstärkning + Output gain Utgångsförstärkning - + \ No newline at end of file diff --git a/data/locale/uk.ts b/data/locale/uk.ts index 2af7e6738..39403714f 100644 --- a/data/locale/uk.ts +++ b/data/locale/uk.ts @@ -2,30 +2,62 @@ AboutDialog + About LMMS Про програму LMMS + + LMMS + LMMS + + + Version %1 (%2/%3, Qt %4, %5) Версія %1 (%2/%3, Qt %4, %5) + About Про програму + LMMS - easy music production for everyone LMMS - легке створення музики для всіх + + Copyright © %1 + Авторське право © %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 Автори + + Involved + Учасники + + + + Contributors ordered by number of commits: + Розробники відсортовані за кількістю коммітов: + + + Translation Переклад + 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! @@ -35,61 +67,50 @@ If you're interested in translating LMMS in another language or want to imp Якщо Ви зацікавлені в перекладі LMMS на іншу мову або хочете поліпшити існуючий переклад, ми будемо раді будь-якій допомогі! Просто зв'яжіться з розробниками! + License Ліцензія - - LMMS - LMMS - - - Involved - Учасники - - - Contributors ordered by number of commits: - Розробники відсортовані за кількістю коммітов: - - - Copyright © %1 - Авторське право © %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> - - AmplifierControlDialog + VOL ГУЧН + Volume: Гучність: + PAN БАЛ + Panning: Баланс: + LEFT ЛІВЕ + Left gain: Ліве підсилення: + RIGHT ПРАВЕ + Right gain: Праве підсилення: @@ -97,18 +118,22 @@ If you're interested in translating LMMS in another language or want to imp AmplifierControls + Volume Гучність + Panning Баланс + Left gain Ліве підсилення + Right gain Праве підсилення @@ -116,10 +141,12 @@ If you're interested in translating LMMS in another language or want to imp AudioAlsaSetupWidget + DEVICE ПРИСТРІЙ + CHANNELS КАНАЛИ @@ -127,78 +154,98 @@ If you're interested in translating LMMS in another language or want to imp AudioFileProcessorView + Open other sample Відкрити інший запис + 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. Натисніть тут, щоб відкрити інший звуковий файл. У новому вікні діалогу ви зможете вибрати потрібний файл. Такі налаштування, як режим повтору, точки початку/кінця, підсилення та інші не скинуться, тому звучання може відрізнятися від оригіналу. + Reverse sample Реверс запису + If you enable this button, the whole sample is reversed. This is useful for cool effects, e.g. a reversed crash. Якщо включити цю кнопку, весь запис піде у зворотний бік, це зручно для крутих ефектів, наприклад зворотного гуркоту. - Amplify: - Підсилення: - - - 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!) - Ця ручка задає коефіцієнт підсилення. При значенні 100% вихідний звук не змінюється, в іншому випадку - він буде ослаблений або підсилений. (Зверніть увагу, що вихідний запис при цьому залишиться недоторканим.) - - - Startpoint: - Початок: - - - Endpoint: - Кінець: - - - Continue sample playback across notes - Продовжити відтворення запису по нотах - - - 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) - Включення цієї опції продовжить відтворення запису за різними нотами - якщо змінити прискорення або тривалість ноти зупиниться до кінця запису, то з наступної ноти запис продовжиться там, де зупинився, щоб скинути відтворення на початок запису, вставте ноту внизу у клавіш (<20 Гц) - - + Disable loop Відключити повторення + This button disables looping. The sample plays only once from start to end. Ця кнопка відключає повтор. Запис програється тільки один раз від початку до кінця. + + Enable loop Включити повторення + This button enables forwards-looping. The sample loops between the end point and the loop point. Ця кнопка включає передній повтор. Запис повторюється між кінцевою точкою і точкою повтору. + This button enables ping-pong-looping. The sample loops backwards and forwards between the end point and the loop point. Ця кнопка включає пінг-понг петлю. Запис повторюється назад і вперед між кінцевою точкою і точкою повтору. + + Continue sample playback across notes + Продовжити відтворення запису по нотах + + + + 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) + Включення цієї опції продовжить відтворення запису за різними нотами - якщо змінити прискорення або тривалість ноти зупиниться до кінця запису, то з наступної ноти запис продовжиться там, де зупинився, щоб скинути відтворення на початок запису, вставте ноту внизу у клавіш (<20 Гц) + + + + Amplify: + Підсилення: + + + + 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!) + Ця ручка задає коефіцієнт підсилення. При значенні 100% вихідний звук не змінюється, в іншому випадку - він буде ослаблений або підсилений. (Зверніть увагу, що вихідний запис при цьому залишиться недоторканим.) + + + + Startpoint: + Початок: + + + With this knob you can set the point where AudioFileProcessor should begin playing your sample. Цим регулятором можна встановити мітку з якої АудіоФайлПроцессор повинен почати відтворення запису. + + Endpoint: + Кінець: + + + With this knob you can set the point where AudioFileProcessor should stop playing your sample. Цей регулятор встановлює мітку в якій АудіоФайлПроцессор повинен перестати програвати запис. + Loopback point: Точка повернення з повтору: + With this knob you can set the point where the loop starts. Цей регулятор ставить мітку початку повторення. @@ -206,6 +253,7 @@ If you're interested in translating LMMS in another language or want to imp AudioFileProcessorWaveView + Sample length: Довжина запису: @@ -213,26 +261,32 @@ If you're interested in translating LMMS in another language or want to imp AudioJack + JACK client restarted JACK-клієнт перезапущений + 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 не був підключений до JACK з якоїсь причини, тому LMMS підключення до JACK було перезапущено. Вам доведеться заново вручну створити з'єднання. + JACK server down JACK-сервер не доступний + 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. Можливо JACK-сервер був вимкнений і запуск нового процесу не вдався, тому LMMS не може продовжити роботу. Вам слід зберегти проект і перезапустити JACK і LMMS. + CLIENT-NAME ІМ'Я КЛІЄНТА + CHANNELS КАНАЛИ @@ -240,10 +294,12 @@ If you're interested in translating LMMS in another language or want to imp AudioOss::setupWidget + DEVICE ПРИСТРІЙ + CHANNELS КАНАЛИ @@ -251,10 +307,12 @@ If you're interested in translating LMMS in another language or want to imp AudioPortAudio::setupWidget + BACKEND УПРАВЛІННЯ + DEVICE ПРИСТРІЙ @@ -262,10 +320,12 @@ If you're interested in translating LMMS in another language or want to imp AudioPulseAudio::setupWidget + DEVICE ПРИСТРІЙ + CHANNELS КАНАЛИ @@ -273,6 +333,7 @@ If you're interested in translating LMMS in another language or want to imp AudioSdl::setupWidget + DEVICE ПРИСТРІЙ @@ -280,10 +341,12 @@ If you're interested in translating LMMS in another language or want to imp AudioSndio::setupWidget + DEVICE ПРИСТРІЙ + CHANNELS КАНАЛИ @@ -291,10 +354,12 @@ If you're interested in translating LMMS in another language or want to imp AudioSoundIo::setupWidget + BACKEND УПРАВЛІННЯ + DEVICE ПРИСТРІЙ @@ -302,61 +367,75 @@ If you're interested in translating LMMS in another language or want to imp AutomatableModel + &Reset (%1%2) &R Скинути (%1%2) + &Copy value (%1%2) &C Копіювати значення (%1%2) + &Paste value (%1%2) &P Вставити значення (%1%2) + Edit song-global automation Змінити глоабльную автоматизацію композиції - Connected to %1 - Приєднано до %1 - - - Connected to controller - Приєднано до контролера - - - Edit connection... - Налаштувати з'єднання... - - - Remove connection - Видалити з'єднання - - - Connect to controller... - З'єднати з контролером ... - - + Remove song-global automation Прибрати глобальну автоматизацію композиції + Remove all linked controls Прибрати все приєднане управління + + + Connected to %1 + Приєднано до %1 + + + + Connected to controller + Приєднано до контролера + + + + Edit connection... + Налаштувати з'єднання... + + + + Remove connection + Видалити з'єднання + + + + Connect to controller... + З'єднати з контролером ... + AutomationEditor + Please open an automation pattern with the context menu of a control! Відкрийте редатор автоматизації через контекстне меню регулятора! + Values copied Значення скопійовані + All selected values were copied to the clipboard. Всі вибрані значення скопійовані до буферу обміну. @@ -364,144 +443,186 @@ 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) Режим малювання (Shift + D) + Erase mode (Shift+E) Режим стирання (Shift+E) + Flip vertically Перевернути вертикально + Flip horizontally Перевернути горизонтально + Click here and the pattern will be inverted.The points are flipped in the y direction. Натисніть тут і мелодія перевернеться. Точки перевертаються в Y напрямку. + Click here and the pattern will be reversed. The points are flipped in the x direction. Натисніть тут і мелодія перевернеться в напрямку 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. При натиснені цієї кнопки активується режим малювання нот, в ньому ви можете додавати/переміщати і змінювати тривалість одиночних нот. Це основний режим і використовується більшу частину часу. Для увімкнення цього режиму можна скористатися комбінацію клавіш Shift+D. + 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. При натиснені цієї кнопки активується режим стирання. У цьому режимі ви можете видаляти ноти по одній. Для увімкнення цього режиму можна скористатися комбінацію клавіш Shift+E. - 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. - Кубічна Ермітова прогресія для цього шаблону автоматизації. Кількість приєднаних об'єктів зміниться по згладженій кривій і пом'якшиться на піках і спадах. - - - Cut selected values (%1+X) - Вирізати вибрані ноти (%1+X) - - - Copy selected values (%1+C) - Копіювати вибрані ноти до буферу (%1+C) - - - Paste values from clipboard (%1+V) - Вставити значення з буферу (%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. - При натиснені цієї кнопки ноти з буферу будуть вставлені в перший видимий такт. - - - Tension: - Напруженість: - - - Automation Editor - no pattern - Редактор автоматизації - немає шаблону - - - Automation Editor - %1 - Редактор автоматизації - %1 - - - Edit actions - Зміна - - + Interpolation controls Управління інтерполяцією - Timeline 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) + Вирізати вибрані ноти (%1+X) + + + + Copy selected values (%1+C) + Копіювати вибрані ноти до буферу (%1+C) + + + + Paste values from clipboard (%1+V) + Вставити значення з буферу (%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. + Квантування. Встановлює найменший розмір кроку для точки автоматизації. За замовчуванням це також задає довжину, очищаючи інші точки діапазону. Натисніть <Ctrl>, щоб змінити цю поведінку. + + + + + Automation Editor - no pattern + Редактор автоматизації - немає шаблону + + + + + Automation Editor - %1 + Редактор автоматизації - %1 + + + Model is already connected to this pattern. Модель вже підключена до цього шаблону. @@ -509,6 +630,7 @@ If you're interested in translating LMMS in another language or want to imp AutomationPattern + Drag a control while pressing <%1> Тягніть контроль утримуючи <%1> @@ -516,46 +638,57 @@ If you're interested in translating LMMS in another language or want to imp AutomationPatternView + double-click to open this pattern in automation editor Двічі клацніть мишею щоб налаштувати автоматизацію для цього шаблону + Open in Automation editor Відкрити в редакторі автоматизації + Clear Очистити + Reset name Скинути назву + Change name Перейменувати - %1 Connections - З'єднання %1 - - - Disconnect "%1" - Від'єднати «%1» - - + Set/clear record Встановити/очистити запис + Flip Vertically (Visible) Перевернути вертикально (Видиме) + Flip Horizontally (Visible) Перевернути горизонтально (Видиме) + + %1 Connections + З'єднання %1 + + + + Disconnect "%1" + Від'єднати «%1» + + + Model is already connected to this pattern. Модель вже підключена до цього шаблону. @@ -563,6 +696,7 @@ If you're interested in translating LMMS in another language or want to imp AutomationTrack + Automation track Доріжка автоматизації @@ -570,77 +704,95 @@ If you're interested in translating LMMS in another language or want to imp BBEditor + Beat+Bassline Editor Ритм Бас Редактор + Play/pause current beat/bassline (Space) Грати/пауза поточної лінії ритму/басу (Пробіл) + Stop playback of current beat/bassline (Space) Зупинити відтворення поточної лінії ритм-басу (Пробіл) + Click here to play the current beat/bassline. The beat/bassline is automatically looped when its end is reached. Натисніть щоб програти поточну лінію ритм-басу. Вона буде повторена при досягненні кінця. + Click here to stop playing of current beat/bassline. Зупинити відтворення (Пробіл). - Add beat/bassline - Додати ритм/бас - - - Add automation-track - Додати доріжку автоматизації - - - Remove steps - Видалити такти - - - Add steps - Додати такти - - + Beat selector Вибір ударних + Track and step actions Дії для доріжки чи її частини - Clone Steps - Клонувати такти + + Add beat/bassline + Додати ритм/бас + Add sample-track Додати доріжку запису + + + Add automation-track + Додати доріжку автоматизації + + + + Remove steps + Видалити такти + + + + Add steps + Додати такти + + + + Clone Steps + Клонувати такти + BBTCOView + Open in Beat+Bassline-Editor Відкрити в редакторі ритму і басу + Reset name Скинути назву + Change name Перейменувати + Change color Змінити колір + Reset color to default Відновити колір за замовчуванням @@ -648,10 +800,12 @@ If you're interested in translating LMMS in another language or want to imp BBTrack + Beat/Bassline %1 Ритм/Бас лінія %1 + Clone of %1 Копія %1 @@ -659,26 +813,32 @@ If you're interested in translating LMMS in another language or want to imp BassBoosterControlDialog + FREQ ЧАСТ + Frequency: Частота: + GAIN ПІДС + Gain: Підсилення: + RATIO ВІДН + Ratio: Відношення: @@ -686,14 +846,17 @@ If you're interested in translating LMMS in another language or want to imp BassBoosterControls + Frequency Частота + Gain Підсилення + Ratio Відношення @@ -701,82 +864,98 @@ If you're interested in translating LMMS in another language or want to imp BitcrushControlDialog + IN ВХД + OUT ВИХ + + GAIN ПІДС + Input Gain: Вхідне підсилення: - NOIS + + NOISE ШУМ + Input Noise: Вхідний шум: + Output Gain: Вихідне підсилення: + CLIP ЗРІЗ + Output Clip: Вихідне відсічення: - Rate - Частота вибірки - - + Rate Enabled Частоту вибірки увімкнено + Enable samplerate-crushing Включити дроблення частоти дискретизації - Depth - Глибина - - + Depth Enabled Глибина включена + Enable bitdepth-crushing Включити ​​дроблення глибини кольору + + FREQ + ЧАСТ + + + Sample rate: Частота дискретизації: - STD - STD + + STEREO + СТЕРЕО + Stereo difference: Стерео різниця: - Levels - Рівні + + QUANT + КВАНТ + Levels: Рівні: @@ -784,10 +963,12 @@ If you're interested in translating LMMS in another language or want to imp CaptionMenu + &Help &H Довідка + Help (not available) Допомога (не доступно) @@ -795,10 +976,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. Натисніть сюди щоб сховати чи показати графічний інтерфейс Carla. @@ -806,6 +989,7 @@ If you're interested in translating LMMS in another language or want to imp Controller + Controller %1 Контролер %1 @@ -813,58 +997,73 @@ If you're interested in translating LMMS in another language or want to imp ControllerConnectionDialog + Connection Settings Параметры соединения + MIDI CONTROLLER MIDI-КОНТРОЛЕР + Input channel Канал введення + CHANNEL КАНАЛ + Input controller Контролер введення + CONTROLLER КОНТРОЛЕР + + Auto Detect Автовизначення + MIDI-devices to receive MIDI-events from Пристрої MiDi для прийому подій + USER CONTROLLER КОРИСТ. КОНТРОЛЕР + MAPPING FUNCTION ПЕРЕВИЗНАЧЕННЯ + OK ОК + Cancel Відміна + LMMS ЛММС + Cycle Detected. Виявлено цикл. @@ -872,18 +1071,22 @@ If you're interested in translating LMMS in another language or want to imp ControllerRackView + Controller Rack Стійка контролерів + Add Додати + Confirm Delete Підтвердити видалення + Confirm delete? There are existing connection(s) associated with this controller. There is no way to undo. Чи підтверджуєте видалення? Є можливі зв'язки з цим контролером, потім їх не можна буде повернути.. @@ -891,93 +1094,115 @@ If you're interested in translating LMMS in another language or want to imp ControllerView + Controls Управління + Controllers are able to automate the value of a knob, slider, and other controls. Контролери можуть автоматизувати зміни значень регуляторів, повзунків та іншого управління. + Rename controller Перейменувати контролер + Enter the new name for this controller Введіть нову назву контролера + + LFO + LFO + + + &Remove this controller &R Видалити цей контролер + Re&name this controller &N Перейменувати цей контролер - - LFO - LFO - CrossoverEQControlDialog + Band 1/2 Crossover: Смуга 1/2 кросовер: + Band 2/3 Crossover: Смуга 2/3 кросовер: + Band 3/4 Crossover: Смуга 3/4 кросовер: + Band 1 Gain: Смуга 1 підсилення: + Band 2 Gain: Смуга 2 підсилення: + Band 3 Gain: Смуга 3 підсилення: + Band 4 Gain: Смуга 4 підсилення: + Band 1 Mute Смуга 1 відключена + Mute Band 1 Відключити смугу 1 + Band 2 Mute Смуга 2 відключена + Mute Band 2 Відключити смугу 2 + Band 3 Mute Смуга 3 відключена + Mute Band 3 Відключити смугу 3 + Band 4 Mute Смуга 4 відключена + Mute Band 4 Відключити смугу 4 @@ -985,22 +1210,27 @@ If you're interested in translating LMMS in another language or want to imp DelayControls + Delay Samples Затримка семплів + Feedback Повернення + Lfo Frequency Частота LFO + Lfo Amount Величина LFO + Output gain Вихідне підсилення @@ -1008,228 +1238,311 @@ If you're interested in translating LMMS in another language or want to imp DelayControlsDialog - Lfo Amt - Вел LFO + + DELAY + ЗАТРИМ + Delay Time Час затримки + + FDBK + FDBK + + + Feedback Amount Величина повернення + + RATE + ЧАСТ + + + Lfo LFO + + AMNT + ГЛИБ + + + + Lfo Amt + Вел LFO + + + Out Gain Вих підсилення + Gain Підсилення - - DELAY - - - - FDBK - - - - RATE - - - - AMNT - ГЛИБ - DualFilterControlDialog - Filter 1 enabled - Фільтр 1 включено - - - Filter 2 enabled - Фільтр 2 включено - - - Click to enable/disable Filter 1 - Натиснути для включення/виключення Фільтру 1 - - - Click to enable/disable Filter 2 - Натиснути для включення/виключення Фільтру 2 - - + + FREQ ЧАСТ + + Cutoff frequency Зріз частоти + + RESO РЕЗО + + Resonance Резонанс + + GAIN ПІДС + + Gain Підсилення + MIX МІКС + Mix Мікс + + + Filter 1 enabled + Фільтр 1 включено + + + + Filter 2 enabled + Фільтр 2 включено + + + + Click to enable/disable Filter 1 + Натиснути для включення/виключення Фільтру 1 + + + + Click to enable/disable Filter 2 + Натиснути для включення/виключення Фільтру 2 + DualFilterControls + Filter 1 enabled Фільтр 1 включено + Filter 1 type Тип фільтру + Cutoff 1 frequency Зріз 1 частоти + Q/Resonance 1 Кіл./Резонансу 1 + Gain 1 Підсилення 1 + Mix Мікс + Filter 2 enabled Фільтр 2 включено + Filter 2 type Тип фільтру 2 + Cutoff 2 frequency Зріз 2 частоти + Q/Resonance 2 Кіл./Резонансу 2 + Gain 2 Підсилення 2 + + LowPass Низ.ЧФ + + HiPass Вис.ЧФ + + BandPass csg Серед.ЧФ csg + + BandPass czpg Серед.ЧФ czpg + + Notch Смуго-загороджуючий + + Allpass Всі проходять + + Moog Муг + + 2x LowPass 2х Низ.ЧФ + + RC LowPass 12dB RC Низ.ЧФ 12дБ + + RC BandPass 12dB RC Серед.ЧФ 12 дБ + + RC HighPass 12dB RC Вис.ЧФ 12дБ + + RC LowPass 24dB RC Низ.ЧФ 24дБ + + RC BandPass 24dB RC Серед.ЧФ 24дБ + + RC HighPass 24dB RC Вис.ЧФ 24дБ + + Vocal Formant Filter Фільтр Вокальної форманти + + 2x Moog 2x Муг + + SV LowPass SV Низ.ЧФ + + SV BandPass SV Серед.ЧФ + + SV HighPass SV Вис.ЧФ + + SV Notch SV Смуго-заг + + Fast Formant Швидка форманта + + Tripole Тріполі @@ -1237,41 +1550,50 @@ If you're interested in translating LMMS in another language or want to imp Editor + + Transport controls + Управління засобами сполучення + + + Play (Space) Грати (Пробіл) + Stop (Space) Зупинити (Пробіл) + Record Запис + Record while playing Запис під час програвання - - Transport controls - Управління засобами сполучення - Effect + Effect enabled Ефект включений + Wet/Dry mix Насиченість + Gate Шлюз + Decay Згасання @@ -1279,6 +1601,7 @@ If you're interested in translating LMMS in another language or want to imp EffectChain + Effects enabled Ефекти включені @@ -1286,10 +1609,12 @@ If you're interested in translating LMMS in another language or want to imp EffectRackView + EFFECTS CHAIN МЕРЕЖА ЕФЕКТІВ + Add effect Додати ефект @@ -1297,22 +1622,28 @@ If you're interested in translating LMMS in another language or want to imp EffectSelectDialog + Add effect Додати ефект + + Name І'мя + Type Тип + Description Опис + Author Автор @@ -1320,54 +1651,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 - 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. Decay (затихання) управляє кількістю буферів тиші, які повинні пройти до кінця роботи плагіна. Менші величини знижують перевантаження процесора, але виникає ризик появи потріскування або підрізання в хвості на перетримці (delay) або відлуння (reverb) ефектах. + GATE ШЛЮЗ + Gate: Шлюз: + The Gate knob controls the signal level that is considered to be 'silence' while deciding when to stop processing signals. GATE (Шлюз) визначає рівень сигналу, який буде вважатися "тишею" при визначенні зупинки оброблення сигналів. + 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. @@ -1397,14 +1741,17 @@ Right clicking will bring up a context menu where you can change the order in wh Контекстне меню, яке викликається клацанням правою кнопкою миші, дозволяє змінювати порядок проходження фільтрів або видаляти їх разом з іншими. + Move &up &u Перемістити вище + Move &down &d Перемістити нижче + &Remove this plugin &R Видалити цей плагін @@ -1412,58 +1759,72 @@ Right clicking will bring up a context menu where you can change the order in wh EnvelopeAndLfoParameters + Predelay Затримка + Attack Вступ + Hold Утримання + Decay Згасання + Sustain Витримка + Release Зменшення + Modulation Модуляція + LFO Predelay Затримка LFO + LFO Attack Вступ LFO + LFO speed Швидкість LFO + LFO Modulation Модуляція LFO + LFO Wave Shape Форма сигналу LFO + Freq x 100 ЧАСТ x 100 + Modulate Env-Amount Модулювати обвідну @@ -1471,349 +1832,439 @@ Right clicking will bring up a context menu where you can change the order in wh EnvelopeAndLfoView + + DEL DEL + Predelay: Предзатримка: + 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: Вступ: + 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: Утримання: + 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: Згасання: + 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: Витримка: + 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: Зменшення: + 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 AMT + + Modulation amount: Глибина модуляції: + 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: Предзатримка 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 (LFO - низькочастотний осциллятор (генератор)). Чим більша величина, тим більше часу до того як LFO почне працювати. + LFO- 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. Використовуйте цю ручку для встановлення часу вступу цього LFO. Чим більше значення, тим довше LFO потребує збільшення своєї амплітуди до максимуму. + SPD SPD + LFO speed: Швидкість 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. Ця ручка встановлює швидкість поточного LFO. Чим більше значення, тим швидше LFO коливається і швидше виробляється ефект. + 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. Ця ручка встановлює глибину модуляції для поточного LFO. Чим більше значення, тим більшою мірою обрана характеристика (н-д, гучність або частота зрізу) залежатиме від цього LFO. + Click here for a sine-wave. - Генерувати гармонійний (синусоїдальний) сигнал. + Синусоїда. + Click here for a triangle-wave. Згенерувати трикутний сигнал. + Click here for a saw-wave for current. Згенерувати зигзагоподібний сигнал. + Click here for a square-wave. Згенерувати квадратний сигнал. + Click here for a user-defined wave. Afterwards, drag an according sample-file onto the LFO graph. Задати свою форму сигналу. Згодом, перетягнути відповідний файл із записом в граф LFO. + + Click here for random wave. + Натисніть сюди для випадкової хвилі. + + + FREQ x 100 ЧАСТОТА x 100 + Click here if the frequency of this LFO should be multiplied by 100. Натисніть, щоб помножити частоту цього LFO на 100. + multiply LFO-frequency by 100 Помножити частоту LFO на 100 + MODULATE ENV-AMOUNT МОДЕЛЮВ ОБВІДНУ + Click here to make the envelope-amount controlled by this LFO. Натисніть сюди, щоб глибина модуляції обвідної задавалася цим LFO. + control envelope-amount by this LFO Дозволити цьому LFO задавати значення обвідної + ms/LFO: мс/LFO: + Hint Підказка + Drag a sample from somewhere and drop it in this window. Перетягніть в це вікно який-небудь запис. - - Click here for random wave. - Натисніть сюди для випадкової хвилі. - EqControls + Input gain Вхідне підсилення + Output gain Вихідне підсилення + Low shelf gain Мала ступінь підсилення + Peak 1 gain Пік 1 підсилення + Peak 2 gain Пік 2 підсилення + Peak 3 gain Пік 3 підсилення + Peak 4 gain Пік 4 підсилення + High Shelf gain Висока ступінь підсилення + HP res ВЧ резон + Low Shelf res Мала ступінь резон + Peak 1 BW Пік 1 BW + Peak 2 BW Пік 2 BW + Peak 3 BW Пік 3 BW + Peak 4 BW Пік 4 BW + High Shelf res Висока ступінь резон + LP res НЧ резон + HP freq НЧ част + Low Shelf freq Низька ступінь част + Peak 1 freq Пік 1 част + Peak 2 freq Пік 2 част + Peak 3 freq Пік 3 част + Peak 4 freq Пік 4 част + High shelf freq Висока ступінь част + LP freq НЧ част + HP active ВЧ активна + Low shelf active Мала ступінь активна + Peak 1 active Пік 1 активний + Peak 2 active Пік 2 активний + Peak 3 active Пік 3 активний + Peak 4 active Пік 4 активний + High shelf active Висока ступінь активна + LP active НЧ активна + LP 12 НЧ 12 + LP 24 НЧ 24 + LP 48 НЧ 48 + HP 12 ВЧ 12 + HP 24 ВЧ 24 + HP 48 ВЧ 48 + low pass type Тип низької частоти + high pass type Тип високої частоти + Analyse IN Аналізувати ВХІД + Analyse OUT Аналізувати ВИХІД @@ -1821,85 +2272,108 @@ Right clicking will bring up a context menu where you can change the order in wh EqControlsDialog + HP ВЧ + Low Shelf Мала ступінь + Peak 1 Пік 1 + Peak 2 Пік 2 + Peak 3 Пік 3 + Peak 4 Пік 4 + High Shelf Висока ступінь + LP НЧ + In Gain Вхід підсилення + + + Gain Підсилення + Out Gain Вих підсилення + Bandwidth: Ширина смуги: + + Octave + Октава + + + Resonance : Резонанс: + Frequency: Частота: + lp grp нч grp + hp grp вч grp - - Octave - Октава - EqHandle + Reso: Резон: + BW: ШС: + + Freq: Част: @@ -1907,174 +2381,243 @@ Right clicking will bring up a context menu where you can change the order in wh ExportProjectDialog + Export project Експорт проекту + Output Вивід + File format: Формат файла: + Samplerate: Частота дискретизації: + 44100 Hz 44.1 КГц + 48000 Hz 48 КГц + 88200 Hz 88.2 КГц + 96000 Hz 96 КГц + 192000 Hz 192 КГц - Bitrate: - Бітрейт: - - - 64 KBit/s - 64 КБіт/с - - - 128 KBit/s - 128 КБіт/с - - - 160 KBit/s - 160 КБіт/с - - - 192 KBit/s - 192 КБіт/с - - - 256 KBit/s - 256 КБіт/с - - - 320 KBit/s - 320 КБіт/с - - + Depth: Глибина: + 16 Bit Integer 16 Біт ціле + + 24 Bit Integer + 24 Біт ціле + + + 32 Bit Float 32 Біт плаваюча - Please note that not all of the parameters above apply for all file formats. - Зауважте, що не всі параметри нижче будуть застосовані для всіх форматів файлів. + + Stereo mode: + Стерео режим: + + Stereo + Стерео + + + + Joint Stereo + Об'єднане стерео + + + + Mono + Моно + + + + Bitrate: + Бітрейт: + + + + 64 KBit/s + 64 КБіт/с + + + + 128 KBit/s + 128 КБіт/с + + + + 160 KBit/s + 160 КБіт/с + + + + 192 KBit/s + 192 КБіт/с + + + + 256 KBit/s + 256 КБіт/с + + + + 320 KBit/s + 320 КБіт/с + + + + Use variable bitrate + Використовувати змінний бітрейт + + + Quality settings Налаштування якості + Interpolation: Інтерполяція: + Zero Order Hold Нульова затримка + Sinc Fastest Синхр. Швидка + Sinc Medium (recommended) Синхр. Середня (рекомендовано) + Sinc Best (very slow!) Синхр. краща (дуже повільно!) + Oversampling (use with care!): Передискретизація (використовувати обережно!): + 1x (None) 1х (Ні) + 2x + 4x + 8x - Start - Почати - - - Cancel - Відміна - - + Export as loop (remove end silence) Експортувати як петлю (прибрати тишу в кінці) + Export between loop markers Експорт між маркерами циклу + + Start + Почати + + + + Cancel + Відміна + + + 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! + Не вдалось відкрити файл %1 для запису. +Перевірте, чи маєте ви права на запис файлу і каталог що його містить і спробуйте знову! + + + Export project to %1 Експорт проекту в %1 + Error Помилка + Error while determining file-encoder device. Please try to choose a different output format. Помилка при визначенні кодека файлу. Спробуйте вибрати інший формат виводу. + Rendering: %1% Обробка: %1% - - 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! - - Fader + + Please enter a new value between %1 and %2: Введіть нове значення від %1 до %2: @@ -2082,6 +2625,7 @@ Please make sure you have write permission to the file and the directory contain FileBrowser + Browser Оглядач файлів @@ -2089,65 +2633,80 @@ Please make sure you have write permission to the file and the directory contain FileBrowserTreeWidget + Send to active instrument-track З'єднати з активним інструментом-доріжкою - Open in new instrument-track/B+B Editor - Відкрити в новій інструментальній доріжці/Біт + Бас редакторі - - - Loading sample - Завантаження запису - - - Please wait, loading sample for preview... - Будь-ласка почекайте, запис завантажується для перегляду ... - - - --- Factory files --- - --- Заводські файли --- - - + Open in new instrument-track/Song Editor Відкрити в новій інструментальній доріжці/Музичному редакторі + + Open in new instrument-track/B+B Editor + Відкрити в новій інструментальній доріжці/Біт + Бас редакторі + + + + Loading sample + Завантаження запису + + + + Please wait, loading sample for preview... + Будь-ласка почекайте, запис завантажується для перегляду ... + + + Error Помилка + does not appear to be a valid не являється дійсним + file файл + + + --- Factory files --- + --- Заводські файли --- + FlangerControls + Delay Samples Затримка семплів + Lfo Frequency Частота LFO + Seconds Секунд + Regen Перегенерувати + Noise Шум + Invert Інвертувати @@ -2155,46 +2714,57 @@ Please make sure you have write permission to the file and the directory contain FlangerControlsDialog + + DELAY + ЗАТРИМ + + + Delay Time: Час затримки: - Feedback Amount: - Величина повернення: - - - White Noise Amount: - Об'єм білого шуму: - - - DELAY - - - + RATE - + ЧАСТ - Rate: - + + Period: + Період: + AMNT ГЛИБ + Amount: - + Величина: + FDBK - + FDBK + + Feedback Amount: + Величина повернення: + + + NOISE - + ШУМ + + White Noise Amount: + Об'єм білого шуму: + + + Invert Інвертувати @@ -2202,10 +2772,12 @@ Please make sure you have write permission to the file and the directory contain FxLine + Channel send amount Величина відправки каналу + 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. @@ -2219,22 +2791,27 @@ You can remove and move FX channels in the context menu, which is accessed by ri Можна прибирати і рухати канали ефектів через контекстне меню, якщо натиснути правою кнопкою миші по каналу ефектів. + Move &left Рухати вліво &L + Move &right Рухати вправо &R + Rename &channel Перейменувати канал &C + R&emove channel Видалити канал &e + Remove &unused channels Видалити канали які &не використовуються @@ -2242,37 +2819,62 @@ You can remove and move FX channels in the context menu, which is accessed by ri FxMixer + Master Головний + + + FX %1 Ефект %1 + + + Volume + Гучність + + + + Mute + Тиша + + + + Solo + Соло + FxMixerView + FX-Mixer Мікшер Ефектів + FX Fader %1 Повзунок Ефекту %1 + Mute Тиша + Mute this FX channel Тиша на цьому каналі Ефекту + Solo Соло + Solo FX channel Соло каналу ЕФ @@ -2280,6 +2882,8 @@ You can remove and move FX channels in the context menu, which is accessed by ri FxRoute + + Amount to send from channel %1 to channel %2 Величина відправки з каналу %1 на канал %2 @@ -2287,14 +2891,17 @@ You can remove and move FX channels in the context menu, which is accessed by ri GigInstrument + Bank Банк + Patch Патч + Gain Підсилення @@ -2302,46 +2909,58 @@ You can remove and move FX channels in the context menu, which is accessed by ri GigInstrumentView + Open other GIG file Відкрити інший GIG файл + Click here to open another GIG file Натисніть, щоб відкрити інший GIG файл + Choose the patch Вибрати патч + Click here to change which patch of the GIG file to use Натисніть для зміни використовуваного патчу GIG файлу + + Change which instrument of the GIG file is being played Змінити інструмент, який відтворює GIG файл + Which GIG file is currently being used Який GIG файл зараз використовується + Which patch of the GIG file is currently being used Який патч GIG файлу зараз використовується + Gain Підсилення + Factor to multiply samples by Фактор множення семплів + Open GIG file Відкрити GIG файл + GIG Files (*.gig) GIG Файли (*.gig) @@ -2349,42 +2968,52 @@ You can remove and move FX channels in the context menu, which is accessed by ri GuiApplication + Working directory Робочий каталог LMMS + The LMMS working directory %1 does not exist. Create it now? You can change the directory later via Edit -> Settings. Робочий каталог LMMS (%1) не існує. Створити його? Пізніше ви зможете змінити його через Правку -> Параметри. + Preparing UI Підготовка користувацького інтерфейсу + Preparing song editor Підготовка музичного редактора + Preparing mixer Підготовка міксера + Preparing controller rack Підготовка стійки контролерів + Preparing project notes Підготовка заміток проекту + Preparing beat/bassline editor Підготовка ритм/бас редактора + Preparing piano roll Підготовка нотного редактора + Preparing automation editor Підготовка редактора автоматизації @@ -2392,650 +3021,814 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentFunctionArpeggio + Arpeggio Арпеджіо + Arpeggio type Тип арпеджіо + Arpeggio range Діапазон арпеджіо + + Cycle steps + Зациклити такти + + + + Skip rate + Частота пропуску + + + + Miss rate + Частота пропуску + + + Arpeggio time Період арпеджіо + Arpeggio gate Шлюз арпеджіо + Arpeggio direction Напрямок арпеджіо + Arpeggio mode Режим арпеджіо + Up Вгору + Down Вниз + Up and down Вгору та вниз - Random - Випадково - - - Free - Вільно - - - Sort - Сортувати - - - Sync - Синхронізувати - - + Down and up Вниз та вгору - Skip rate - + + Random + Випадково - Miss rate - + + Free + Вільно - Cycle steps - + + Sort + Сортувати + + + + Sync + Синхронізувати 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 RANGE + Arpeggio range: Діапазон арпеджіо: + octave(s) Октав(а/и) + Use this knob for setting the arpeggio range in octaves. The selected arpeggio will be played within specified number of octaves. Використовуйте цю ручку, щоб встановити діапазон арпеджіо (в октавах). Обраний тип арпеджіо охоплюватиме вказану кількість октав. - TIME - TIME + + CYCLE + ЦИКЛ - Arpeggio time: - Період арпеджіо: + + Cycle notes: + Зациклити ноти: - ms - мс + + note(s) + нота(и) - Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. - Регулювання періоду арпеджіо - час (в мілісекундах), який має звучати кожен тон арпеджіо. + + 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. + - GATE - GATE + + SKIP + ПРОПУСК - Arpeggio gate: - Шлюз арпеджіо: + + Skip rate: + Частота пропуску: + + + % % - 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: - Акорд: - - - Direction: - Напрямок: - - - Mode: - Режим: - - - SKIP - - - - Skip rate: - - - + 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. - + Функція пропуску змусить арпеджіатор пропустити бажану ноту. - CYCLE - + + TIME + TIME - Cycle notes: - + + Arpeggio time: + Період арпеджіо: - note(s) - + + ms + мс - 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. - + + Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. + Регулювання періоду арпеджіо - час (в мілісекундах), який має звучати кожен тон арпеджіо. + + + + GATE + GATE + + + + 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: + Акорд: + + + + Direction: + Напрямок: + + + + Mode: + Режим: InstrumentFunctionNoteStacking + octave Октава + + Major Мажорний + Majb5 Majb5 + 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 Maj7 + Maj7b5 Maj7b5 + Maj7#5 Maj7#5 + Maj7#11 Maj7#11 + Maj7add13 Maj7add13 + m7 m7 + m7b5 m7b5 + m7b9 m7b9 + m7add11 m7add11 + m7add13 m7add13 + m-Maj7 m-Maj7 + m-Maj7add11 m-Maj7add11 + m-Maj7add13 m-Maj7add13 + 9 9 + 9sus4 9sus4 + add9 add9 + 9#5 9#5 + 9b5 9b5 + 9#11 9#11 + 9b13 9b13 + Maj9 Maj9 + Maj9sus4 Maj9sus4 + Maj9#5 Maj9#5 + Maj9#11 Maj9#11 + m9 m9 + madd9 madd9 + m9b5 m9b5 + m9-Maj7 m9-Maj7 + 11 11 + 11b9 11b9 + Maj11 Maj11 + m11 m11 + m-Maj11 m-Maj11 + 13 13 + 13#9 13#9 + 13b9 13b9 + 13b5b9 13b5b9 + Maj13 Maj13 + m13 m13 + m-Maj13 m-Maj13 + Harmonic minor Гармонійний мінор + Melodic minor Мелодійний мінор + Whole tone Цілий тон + Diminished Понижений + Major pentatonic Пентатонік major + Minor pentatonic Пентатонік major + Jap in sen Япон in sen + Major bebop Major Бібоп + Dominant bebop Домінтний бібоп + Blues Блюз + Arabic Арабська + Enigmatic Загадкова + Neopolitan Неаполітанська + Neopolitan minor Неаполітанський мінор + Hungarian minor Угорський мінор + Dorian Дорійська - Phrygolydian - Фруголідійська + + Phrygian + Фрігійський + Lydian Лідійська + Mixolydian Міксолідійська + Aeolian Еолійська + Locrian Локріанська - Chords - Акорди - - - Chord type - Тип акорду - - - Chord range - Діапазон акорду - - + Minor Мінор + Chromatic Хроматична + Half-Whole Diminished Напів-зниження + 5 5 + Phrygian dominant - + Фрігійська домінанта + Persian - + Перська + + + + Chords + Акорди + + + + Chord type + Тип акорду + + + + Chord range + Діапазон акорду InstrumentFunctionNoteStackingView - RANGE - ДІАПАЗОН - - - Chord range: - Діапазон акорду: - - - octave(s) - Октав[а/и] - - - Use this knob for setting the chord range in octaves. The selected chord will be played within specified number of octaves. - Ця ручка змінює діапазон акорду, який буде містити вказане число октав. - - + STACKING Стиковка + Chord: Акорд: + + + RANGE + ДІАПАЗОН + + + + Chord range: + Діапазон акорду: + + + + octave(s) + Октав[а/и] + + + + 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 УВІМК MIDI ВХІД + + CHANNEL CHANNEL + + VELOCITY VELOCITY + ENABLE MIDI OUTPUT УВІМК MIDI ВИВІД + PROGRAM PROGRAM - MIDI devices to receive MIDI events from - MiDi пристрої-джерела подій - - - MIDI devices to send MIDI events to - MiDi пристрої для відправки подій на них - - + NOTE NOTE + + MIDI devices to receive MIDI events from + MiDi пристрої-джерела подій + + + + MIDI devices to send MIDI events to + MiDi пристрої для відправки подій на них + + + CUSTOM BASE VELOCITY СВОЯ БАЗОВА ШВИДКІСТЬ + Specify the velocity normalization base for MIDI-based instruments at 100% note velocity Визначає базову швидкість нормальізаціі для MiDi інструментів при гучності ноти 100% + BASE VELOCITY БАЗОВА ШВИДКІСТЬ @@ -3043,10 +3836,12 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentMiscView + MASTER PITCH ОСНОВНА ТОНАЛЬНІСТЬ + Enables the use of Master Pitch Включає використання основної тональності @@ -3054,126 +3849,158 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentSoundShaping + VOLUME VOLUME + Volume Гучність + CUTOFF CUTOFF + + Cutoff frequency Зріз частоти + RESO RESO + Resonance Резонанс + Envelopes/LFOs - Огибание/LFO + Обвідні/LFO + Filter type Тип фільтру + Q/Resonance Кіл./Резонансу + LowPass Низ.ЧФ + HiPass Вис.ЧФ + BandPass csg Серед.ЧФ csg + BandPass czpg Серед.ЧФ czpg + Notch Смуго-загороджуючий + Allpass Всі проходять + Moog Муг + 2x LowPass 2х Низ.ЧФ + RC LowPass 12dB RC Низ.ЧФ 12дБ + RC BandPass 12dB RC Серед.ЧФ 12 дБ + RC HighPass 12dB RC Вис.ЧФ 12дБ + RC LowPass 24dB RC Низ.ЧФ 24дБ + RC BandPass 24dB RC Серед.ЧФ 24дБ + RC HighPass 24dB RC Вис.ЧФ 24дБ + Vocal Formant Filter Фільтр Вокальної форманти + 2x Moog 2x Муг + SV LowPass SV Низ.ЧФ + SV BandPass SV Серед.ЧФ + SV HighPass SV Вис.ЧФ + SV Notch SV Смуго-заг + Fast Formant Швидка форманта + Tripole Тріполі @@ -3181,51 +4008,63 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentSoundShapingView + TARGET ЦЕЛЬ + 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...! Ця вкладка дозволяє вам налаштувати обвідні. Вони дуже важливі для налаштування звучання. Наприклад, за допомогою обвідної гучності ви можете задати залежність гучності звучання від часу. Якщо вам знадобиться емулювати м'які струнні, просто задайте більше часу наростання і зникнення звуку. За допомогою обвідних і низькочастотного осциллятора (LFO) ви в кілька кліків миші зможете створити просто неймовірні звуки! + 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. Здесь вы можете выбрать фильтр для дорожки этого инструмента. Фильтры могут довольно сильно менять звучание. - 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 - РЕЗО - - - Resonance: - Резонанс: - - - 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. - Эта ручка задаёт количество резонанса для фильтра, этим определяется насколько нужно усилить ближайшие к отрезанным частоты. - - + FREQ ЧАСТ + cutoff frequency: Срез частот: + + 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 + РЕЗО + + + + Resonance: + Підсилення: + + + + 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. Обвідні, LFO і фільтри не підтримуються цим інструментом. @@ -3233,85 +4072,107 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentTrack - unnamed_track - безіменна_доріжка - - - Volume - Гучність - - - Panning - Стерео - - - Pitch - Тональність - - - FX channel - Канал ЕФ - - - Default preset - Основна предустановка - - + With this knob you can set the volume of the opened channel. Регулювання гучності поточного каналу. + + + unnamed_track + безіменна_доріжка + + + Base note Опорна нота + + Volume + Гучність + + + + Panning + Стерео + + + + Pitch + Тональність + + + Pitch range Діапазон тональності + + FX channel + Канал ЕФ + + + Master Pitch Основна тональність + + + + Default preset + Основна предустановка + InstrumentTrackView + Volume Гучність + Volume: Гучність: + VOL ГУЧН + Panning Баланс + Panning: Баланс: + PAN БАЛ + MIDI MIDI + Input Вхід + Output Вихід + FX %1: %2 ЕФ %1: %2 @@ -3319,125 +4180,160 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentTrackWindow + GENERAL SETTINGS ОСНОВНІ НАЛАШТУВАННЯ - Instrument volume - Гучність інструменту - - - Volume: - Гучність: - - - VOL - ГУЧН - - - Panning - Баланс - - - Panning: - Стереобаланс: - - - PAN - БАЛ - - - Pitch - Тональність - - - Pitch: - Тональність: - - - cents - відсотків - - - PITCH - ТОН - - - FX channel - Канал ЕФ - - - ENV/LFO - ОБВ/LFO - - - FUNC - ФУНКЦ - - - FX - ЕФ - - - MIDI - MIDI - - - Save preset - Зберегти передустановку - - - XML preset file (*.xpf) - XML файл налаштувань (*.xpf) - - - PLUGIN - ПЛАГІН - - - Pitch range (semitones) - Діапазон тональності (півтону) - - - RANGE - ДІАПАЗОН - - - 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. - Нитисніть тут, щоб зберегти налаштування поточної інстр. доріжки в файл предустановок. Пізніше можна завантажити цю передустановку подвійним кліком в браузері предустановок. - - - MISC - РІЗНЕ - - + 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 + Обвідна, фільтр & LFO + + + + Chord stacking & arpeggio + Укладання акордів & арпеджіо + + + + Effects + Ефекти + + + + MIDI settings + Параметри MIDI + + + + Miscellaneous + Різне + + + + Save preset + Зберегти передустановку + + + + XML preset file (*.xpf) + XML файл налаштувань (*.xpf) + + + + Plugin + Модуль + Knob + Set linear Встановити лінійний + Set logarithmic Встановити логарифмічний + Please enter a new value between -96.0 dBFS and 6.0 dBFS: Введіть нове значення від -96,0 дБFS до 6,0 дБFS: + Please enter a new value between %1 and %2: Введіть нове значення від %1 до %2: @@ -3445,6 +4341,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaControl + Link channels Зв'язати канали @@ -3452,10 +4349,12 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaControlDialog + Link Channels Зв'язати канали + Channel Канал @@ -3463,14 +4362,17 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaControlView + Link channels Зв'язати канали + Value: Значення: + Sorry, no help available. Вибачте, довідки немає. @@ -3478,6 +4380,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaEffect + Unknown LADSPA plugin %1 requested. Запитаний невідомий модуль LADSPA «%1». @@ -3485,6 +4388,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri LcdSpinBox + Please enter a new value between %1 and %2: Введіть нове значення від %1 до %2: @@ -3492,18 +4396,26 @@ You can remove and move FX channels in the context menu, which is accessed by ri LeftRightNav + + + Previous Попередній + + + Next Наступний + Previous (%1) Попередній (%1) + Next (%1) Наступний (%1) @@ -3511,30 +4423,37 @@ You can remove and move FX channels in the context menu, which is accessed by ri LfoController + LFO Controller Контролер LFO + Base value Основне значення + Oscillator speed Швидкість хвилі + Oscillator amount Розмір хвилі + Oscillator phase Фаза хвилі + Oscillator waveform Форма хвилі + Frequency Multiplier Множник частоти @@ -3542,115 +4461,142 @@ You can remove and move FX channels in the context menu, which is accessed by ri LfoControllerDialog + LFO LFO + LFO Controller Контролер LFO + BASE БАЗА + Base amount: - Кіл-ть бази: + Базове значення: + todo доробити + SPD ШВИД + LFO-speed: Швидкість LFO: + Use this knob for setting speed of the LFO. The bigger this value the faster the LFO oscillates and the faster the effect. Ця ручка встановлює швидкість LFO. Чим більше значення, тим більша частота осциллятора. + + AMNT + ГЛИБ + + + Modulation amount: Кількість модуляції: + 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. Ця ручка встановлює глибину модуляції для LFO. Чим більше значення, тим більшою мірою обрана характеристика (н-д, гучність або частота зрізу) буде залежати від ГНЧ (LFO). + PHS ФАЗА + Phase offset: Зсув фази: + degrees градуси + 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. Ця ручка встановлює початкову фазу НизькоЧастотного Осциллятора (LFO), т. б. Точку, з якої осциллятор починає виробляти сигнал. Наприклад, якщо ви задали синусоїдальну форму сигналу і початкову фазу 180º, хвиля спочатку піде вниз, а не вгору, так само як і для квадратної хвилі. + Click here for a sine-wave. Синусоїда. + Click here for a triangle-wave. - Трикутник. + Згенерувати трикутний сигнал. + Click here for a saw-wave. - Зигзаг. + Згенерувати зигзаг. + Click here for a square-wave. - Квадрат. + Згенерувати квадратний сигнал. + + Click here for a moog saw-wave. + Натисніть для зигзагоподібної муг-хвилі. + + + Click here for an exponential wave. - Експонента. + Генерувати експонентний сигнал. + Click here for white-noise. - Білий шум. + Згенерувати білий шум. + Click here for a user-defined shape. Double click to pick a file. Натисніть тут для визначення своєї форми. Подвійне натискання для вибору файлу. - - Click here for a moog saw-wave. - Натисніть для зигзагоподібної муг-хвилі. - - - AMNT - ГЛИБ - LmmsCore + Generating wavetables Генерування синтезатора звукозаписів + Initializing data structures Ініціалізація структур даних + Opening audio and midi devices Відкриття аудіо та міді пристроїв + Launching mixer threads Запуск потоків міксера @@ -3658,406 +4604,501 @@ Double click to pick a file. MainWindow - Could not save config-file - Не можу зберегти налаштування + + Configuration file + Файл налаштувань - Could not save configuration file %1. You're probably not permitted to write to this file. -Please make sure you have write-access to the file and try again. - Не можу записати налаштування в файл %1. Можливо, ви не володієте правами на запис в нього. -Будь ласка, перевірте свої права і спробуйте знову. + + Error while parsing configuration file at line %1:%2: %3 + Помилка під час обробки файлу налаштувань в рядку %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! + Не вдалось відкрити файл %1 для запису. +Перевірте, чи маєте ви права на запис файлу і каталог що його містить і спробуйте знову! + + + + 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? + Присутній файл відновлення. Схоже, остання сесія не закінчилася належним чином або інший екземпляр LMMS вже запущений. Ви хочете, відновити проект цієї сесії? + + + + + + Recover + Відновлення + + + + Recover the file. Please don't run multiple instances of LMMS when you do this. + Відновлення файлу. Будь ласка, не запускайте кілька копій LMMS під час цієї операції. + + + + + + Discard + Відкинути + + + + Launch a default session and delete the restored files. This is not reversible. + Запуск за замовчуванням з видаленням файла відновлення. Ця дія не відворотня. + + + + Version %1 + Версія %1 + + + + Preparing plugin browser + Підготовка браузера плагінів + + + + Preparing file browsers + Підготовка переглядача файлів + + + + My Projects + Мої проекти + + + + My Samples + Мої записи + + + + My Presets + Мої передустановки + + + + My Home + Моя домашня тека + + + + Root directory + Кореневий каталог + + + + Volumes + Гучності + + + + My Computer + Мій комп'ютер + + + + Loading background artwork + Завантаження фонового зображення + + + + &File + &Файл + + + &New &N Новий + + New from template + Новий проект по шаблону + + + &Open... &O Відкрити... + + &Recently Opened Projects + &Нещодавно відкриті проекти + + + &Save &S Зберегти + Save &As... &A Зберегти як... + + Save as New &Version + Зберегти як нову &Версію + + + + Save as default template + Зберегти як шаблон за замовчуванням + + + Import... Імпорт... + E&xport... &X Експорт ... + + E&xport Tracks... + &Експортувати треки ... + + + + Export &MIDI... + Експорт в &MIDI ... + + + &Quit &Q Вийти + &Edit &E Редагування + + Undo + Скасувати + + + + Redo + Повторити + + + Settings Параметри + + &View + &V Перегляд + + + &Tools &T Сервіс + &Help &H Довідка + + Online Help + Онлайн Допомога + + + Help Довідка - What's this? + + What's This? Що це? + About Про програму + Create new project Створити новий проект + Create new project from template Створити новий проект по шаблону + Open existing project Відкрити існуючий проект + Recently opened projects Нещодавні проекти + Save current project Зберегти поточний проект + Export current project Експорт проекту - Song Editor - Музичний редактор + + What's this? + Що це? + + Toggle metronome + Переключити метроном + + + + Show/hide Song-Editor + Показати/сховати музичний редактор + + + 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. Показати чи сховати музичний редактор. З його допомогою ви можете редагувати композицію і задавати час відтворення кожної доріжки. Також ви можете вставляти і пересувати записи прямо у списку відтворення. - Beat+Bassline Editor - Редактор шаблонів + + Show/hide Beat+Bassline Editor + Показати/сховати ритм-бас редактор + 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. Показати чи сховати ритм-бас редактор. Він необхідний для установки ритму, відкриття, додавання і видалення каналів, а також вирізання, копіювання і вставки ритм-бас шаблонів і схожих речей. - Piano Roll - Нотний редактор + + Show/hide Piano-Roll + Показати/сховати нотний редактор + Click here to show or hide the Piano-Roll. With the help of the Piano-Roll you can edit melodies in an easy way. Запуск редатора нот. З його допомогою ви можете легко редагувати мелодії. - Automation Editor - Редактор автоматизації + + Show/hide Automation Editor + Показати/сховати редактор автоматизації + 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. Показати / сховати вікно редактора автоматизації. З його допомогою ви можете легко редагувати динаміку обраних величин. - FX Mixer - Мікшер Ефектів + + Show/hide 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. Сховати / показати мікшер ефектів. Він є потужним інструментом для управління ефектами. Ви можете вставляти ефекти в різні канали. - Project Notes - Примітки проекту + + Show/hide project notes + Показати/сховати замітки до проекту + Click here to show or hide the project notes window. In this window you can put down your project notes. Ця кнопка показує / ховає вікно з нотатками. У цьому вікні ви можете поміщати будь-які коментарі до своєї композиції. - Controller Rack - Стійка контролерів + + Show/hide controller rack + Показати/сховати керування контролерами + Untitled Без назви + + Recover session. Please save your work! + Відновлення сесії. Будь ласка, збережіть свою роботу! + + + LMMS %1 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) + LMMS (*.mmp *.mmpz) + + + + Save Project + Зберегти проект + + + + LMMS Project + LMMS проект + + + + LMMS Project Template + Шаблон LMMS проекту + + + + 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. Поки що довідка для LMMS не написана. Ймовірно, Ви зможете знайти потрібні матеріали на http://lmms.sf.net/wiki. - LMMS (*.mmp *.mmpz) - LMMS (*.mmp *.mmpz) + + Song Editor + Музичний редактор - Version %1 - Версія %1 + + Beat+Bassline Editor + Редактор шаблонів - Configuration file - Файл налаштувань + + Piano Roll + Нотний редактор - Error while parsing configuration file at line %1:%2: %3 - Помилка під час обробки файлу налаштувань в рядку %1:%2:%3 + + Automation Editor + Редактор автоматизації - Volumes - Гучності + + FX Mixer + Мікшер Ефектів - Undo - Скасувати + + Project Notes + Примітки проекту - Redo - Повторити - - - My Projects - Мої проекти - - - My Samples - Мої записи - - - My Presets - Мої передустановки - - - My Home - Моя домашня тека - - - My Computer - Мій комп'ютер - - - &File - &Файл - - - &Recently Opened Projects - &Нещодавно відкриті проекти - - - Save as New &Version - Зберегти як нову &Версію - - - E&xport Tracks... - &Експортувати треки ... - - - Online Help - Онлайн Допомога - - - What's This? - Що це? - - - Open Project - Відкрити проект - - - Save Project - Зберегти проект - - - 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? - Присутній файл відновлення. Схоже, остання сесія не закінчилася належним чином або інший екземпляр LMMS вже запущений. Ви хочете, відновити проект цієї сесії? - - - Recover - Відновлення - - - Recover the file. Please don't run multiple instances of LMMS when you do this. - Відновлення файлу. Будь ласка, не запускайте кілька копій LMMS під час цієї операції. - - - Ignore - Ігнорувати - - - Launch LMMS as usual but with automatic backup disabled to prevent the present recover file from being overwritten. - Запуск LMMS як зазвичай, але з відключеним автоматичним резервуванням, щоб запобігти перезапису файлу відновлення. - - - Discard - Відкинути - - - Launch a default session and delete the restored files. This is not reversible. - Запуск за замовчуванням з видаленням файла відновлення. Ця дія не відворотня. - - - Preparing plugin browser - Підготовка браузера плагінів - - - Preparing file browsers - Підготовка переглядача файлів - - - Root directory - Кореневий каталог - - - Loading background artwork - Завантаження фонового зображення - - - New from template - Новий проект по шаблону - - - Save as default template - Зберегти як шаблон за замовчуванням - - - &View - &V Перегляд - - - Toggle metronome - Переключити метроном - - - Show/hide Song-Editor - Показати/сховати музичний редактор - - - Show/hide Beat+Bassline Editor - Показати/сховати ритм-бас редактор - - - Show/hide Piano-Roll - Показати/сховати нотний редактор - - - Show/hide Automation Editor - Показати/сховати редактор автоматизації - - - Show/hide FX Mixer - Показати/сховати мікшер ЕФ - - - Show/hide project notes - Показати/сховати замітки до проекту - - - Show/hide controller rack - Показати/сховати керування контролерами - - - Recover session. Please save your work! - Відновлення сесії. Будь ласка, збережіть свою роботу! - - - Automatic backup disabled. Remember to save your work! - Автоматичне резервне копіювання відключено. Не забудьте зберегти вашу роботу! - - - 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? - Цей проект буво відновлено з попередньої сесії. В даний час він не збережений і буде втрачений, якщо ви його не збережете. Ви хочете, зберегти його зараз? - - - LMMS Project - LMMS проект - - - LMMS Project Template - Шаблон LMMS проекту - - - Overwrite default template? - Переписати шаблон за замовчуванням? - - - This will overwrite your current default template. - Це перезапише поточний шаблон за замовчуванням. + + Controller Rack + Стійка контролерів + Volume as dBFS Відображати гучність в децибелах + Smooth scroll Плавне прокручування + Enable note labels in piano roll Включити позначення нот у музичному редакторі - - Save project template - - MeterDialog + + Meter Numerator Шкала чисел + + Meter Denominator Шкала поділів + TIME SIG ПЕРІОД @@ -4065,10 +5106,12 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MeterModel + Numerator Чисельник + Denominator Знаменник @@ -4076,10 +5119,12 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MidiController + MIDI Controller Контролер MIDI + unnamed_midi_controller нерозпізнаний міді контролер @@ -4087,19 +5132,24 @@ 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. Ви не встановили SoundFont за замовчуванням в налаштуваннях (Правка-> Налаштування), тому після імпорту міді файлу звук відтворюватися не буде. Вам слід завантажити основний MiDi SoundFont, вказати його в налаштуваннях і спробувати знову. + 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. Ви не увімкнули підтримку програвача SoundFont2 при компіляції LMMS, він використовується для додавання основного звуку в імпортовані Міді файли, тому після імпорту цього міді файлу звуку не буде. + Track Трек @@ -4107,66 +5157,80 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MidiJack + JACK server down When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (title) JACK-сервер не доступний + The JACK server seems to be shuted down. When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (dialog message) - + Здається, сервер JACK відключений. MidiPort + Input channel Вхід + Output channel Вихід + Input controller Контролер входу + Output controller Контролер виходу + Fixed input velocity Постійна швидкість введення + Fixed output velocity Постійна швидкість виведення - Output MIDI program - Програма для виведення MiDi - - - Receive MIDI-events - Приймати події MIDI - - - Send MIDI-events - Відправляти події MIDI - - + Fixed output note Постійний вихід нот + + Output MIDI program + Програма для виведення MiDi + + + Base velocity Базова швидкість + + + Receive MIDI-events + Приймати події MIDI + + + + Send MIDI-events + Відправляти події MIDI + MidiSetupWidget + DEVICE ПРИСТРІЙ @@ -4174,474 +5238,595 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MonstroInstrument + Osc 1 Volume Гучність осциллятора 1 + Osc 1 Panning Баланс осциллятора 1 + Osc 1 Coarse detune Грубе підстроювання осциллятора 1 + Osc 1 Fine detune left Точне підстроювання лівого каналу осциллятора 1 + Osc 1 Fine detune right Точне підстроювання правого каналу осциллятора 1 + Osc 1 Stereo phase offset Зміщення стерео-фази осциллятора 1 + Osc 1 Pulse width Довжина імпульсу осциллятора 1 + Osc 1 Sync send on rise Синхронізація підйому осциллятора 1 + Osc 1 Sync send on fall Синхронізація падіння осциллятора 1 + Osc 2 Volume Гучність осциллятора 2 + Osc 2 Panning Баланс осциллятора 2 + Osc 2 Coarse detune Грубе підстроювання осциллятора 2 + Osc 2 Fine detune left Точне підстроювання лівого каналу осциллятора 2 + Osc 2 Fine detune right Точне підстроювання правого каналу осциллятора 2 + Osc 2 Stereo phase offset Зміщення стерео-фази осциллятора 2 + Osc 2 Waveform Форма сигналу осциллятора 2 + Osc 2 Sync Hard Жорстка синхронізація осциллятора 2 + Osc 2 Sync Reverse Верерс синхронізація осциллятора 2 + Osc 3 Volume Гучність осциллятора 3 + Osc 3 Panning Баланс осциллятора 3 + Osc 3 Coarse detune Грубе підстроювання осциллятора 3 + Osc 3 Stereo phase offset Зміщення стерео-фази осциллятора 3 + Osc 3 Sub-oscillator mix Змішення суб-генератора осциллятора 3 + Osc 3 Waveform 1 Форма 1 сигналу осциллятора 3 + Osc 3 Waveform 2 Форма 2 сигналу осциллятора 3 + Osc 3 Sync Hard Жорстка синхронізація осциллятора 3 + Osc 3 Sync Reverse Верерс синхронізація осциллятора 3 + LFO 1 Waveform Форма сигналу LFO 1 + LFO 1 Attack Вступ LFO 1 + LFO 1 Rate Темп LFO 1 + LFO 1 Phase Фаза LFO 1 + LFO 2 Waveform Форма сигналу LFO 2 + LFO 2 Attack Вступ LFO 2 + LFO 2 Rate Темп LFO 2 + LFO 2 Phase Фаза LFO 2 + Env 1 Pre-delay Затримка обвідної 1 + Env 1 Attack Вступ обвідної 1 + Env 1 Hold Утримання обвідної 1 + Env 1 Decay Згасання обвідної 1 + Env 1 Sustain Витримка обвідної 1 + Env 1 Release Зменшення обвідної 1 + Env 1 Slope Нахил обвідної 1 + Env 2 Pre-delay Затримка обвідної 2 + Env 2 Attack Вступ обвідної 2 + Env 2 Hold Утримання обвідної 2 + Env 2 Decay Згасання обвідної 2 + Env 2 Sustain Витримка обвідної 2 + Env 2 Release Зменшення обвідної 2 + Env 2 Slope Нахил обвідної 2 + Osc2-3 modulation Модуляція осцилляторів 2-3 + Selected view Перегляд обраного + Vol1-Env1 Гучн1-Обв1 + Vol1-Env2 Гучн1-Обв2 + Vol1-LFO1 Гучн1-LFO1 + Vol1-LFO2 Гучн1-LFO2 + Vol2-Env1 Гучн2-Обв1 + Vol2-Env2 Гучн2-Обв2 + Vol2-LFO1 Гучн2-LFO1 + Vol2-LFO2 Гучн2-LFO2 + Vol3-Env1 Гучн3-Обв1 + Vol3-Env2 Гучн3-Обв2 + Vol3-LFO1 Гучн3-LFO1 + Vol3-LFO2 Гучн3-LFO2 + Phs1-Env1 Фаз1-Обв1 + Phs1-Env2 Фаз1-Обв2 + Phs1-LFO1 Фаз1-LFO1 + Phs1-LFO2 Фаз1-LFO2 + Phs2-Env1 Фаз2-Обв1 + Phs2-Env2 Фаз2-Обв2 + Phs2-LFO1 Фаз2-LFO1 + Phs2-LFO2 Фаз2-LFO2 + Phs3-Env1 Фаз3-Обв1 + Phs3-Env2 Фаз3-Обв2 + Phs3-LFO1 Фаз3-LFO1 + Phs3-LFO2 Фаз3-LFO2 + Pit1-Env1 Тон1-Обв1 + Pit1-Env2 Тон1-Обв2 + Pit1-LFO1 Тон1-LFO1 + Pit1-LFO2 Тон1-LFO2 + Pit2-Env1 Тон2-Обв1 + Pit2-Env2 Тон2-Обв2 + Pit2-LFO1 Тон2-LFO1 + Pit2-LFO2 Тон2-LFO2 + Pit3-Env1 Тон3-Обв1 + Pit3-Env2 Тон3-Обв2 + Pit3-LFO1 Тон3-LFO1 + Pit3-LFO2 Тон3-LFO2 + PW1-Env1 PW1-Обв1 + PW1-Env2 PW1-Обв2 + PW1-LFO1 PW1-LFO1 + PW1-LFO2 PW1-LFO2 + Sub3-Env1 Sub3-Обв1 + Sub3-Env2 Sub3-Обв2 + Sub3-LFO1 Sub3-LFO1 + Sub3-LFO2 Sub3-LFO2 + + Sine wave Синусоїда + Bandlimited Triangle wave Трикутна хвиля з обмеженою смугою + Bandlimited Saw wave Зигзаг хвиля з обмеженою смугою + Bandlimited Ramp wave Спадаюча хвиля з обмеженою смугою + Bandlimited Square wave Квадратна хвиля з обмеженою смугою + Bandlimited Moog saw wave Муг-зигзаг хвиля з обмеженою смугою + + Soft square wave М'яка прямокутна хвиля + Absolute sine wave Абсолютна синусоїдна хвиля + + Exponential wave Експоненціальна хвиля + White noise Білий шум + Digital Triangle wave Цифрова трикутна хвиля + Digital Saw wave Цифрова зигзаг хвиля + Digital Ramp wave Цифрова спадна хвиля + Digital Square wave Цифрова квадратна хвиля + Digital Moog saw wave Цифрова Муг-зигзаг хвиля + Triangle wave Трикутна хвиля + Saw wave Зигзаг + Ramp wave Спадна хвиля + Square wave Квадратна хвиля + Moog saw wave Муг-зигзаг хвиля + Abs. sine wave Синусоїда по модулю + Random Випадково + Random smooth Випадкове зглажування @@ -4649,10 +5834,12 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MonstroView + Operators view Операторский вид + 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. @@ -4661,10 +5848,12 @@ Knobs and other widgets in the Operators view have their own what's this -t Регулятори й інші віджети в операторському вигляді мають свої підписи "Що це?", Таким чином по ним можна отримати більш детальну довідку. + Matrix view Матричний вигляд + 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. @@ -4677,80 +5866,266 @@ Each modulation target has 4 knobs, one for each modulator. By default the knobs Кожна ціль модуляції має 4 регулятори, по одному на кожен модулятор. За замовчуванням регулятори встановлені на 0, тобто без модуляції. Включення регуляторів на 1 веде до того, що модулятор впливає на ціль модуляції на стільки на скільки це можливо. Включення його в -1 робить те ж, але зі зворотньою модуляцією. + + + + Volume + Гучність + + + + + + Panning + Баланс + + + + + + Coarse detune + Грубе підстроювання + + + + + + semitones + півтон(а,ів) + + + + + Finetune left + Точне настроювання лівого каналу + + + + + + + cents + відсотків + + + + + Finetune right + Точне настроювання правого каналу + + + + + + Stereo phase offset + Зміщення стерео-фази + + + + + + + + deg + град + + + + Pulse width + Довжина імпульсу + + + + Send sync on pulse rise + Відправляти синхронізацію на підйомі імпульсу + + + + Send sync on pulse fall + Відправити синхронізацію на падінні пульсу + + + + Hard sync oscillator 2 + Жорстка синхронізація осциллятора 2 + + + + Reverse sync oscillator 2 + Верерс синхронізація осциллятора 2 + + + + Sub-osc mix + Мікс суб-осциляторів + + + + Hard sync oscillator 3 + Жорстка синхронізація осциллятора 3 + + + + Reverse sync oscillator 3 + Верерс синхронізація осциллятора 3 + + + + + + + Attack + Вступ + + + + + Rate + Частота вибірки + + + + + Phase + Фаза + + + + + Pre-delay + Передзатримка + + + + + Hold + Утримання + + + + + Decay + Згасання + + + + + Sustain + Витримка + + + + + Release + Зменшення + + + + + Slope + Нахил + + + Mix Osc2 with Osc3 Змішати Осц2 з Осц3 + Modulate amplitude of Osc3 with Osc2 Модулювати амплітуду осциллятора 3 сигналом з осц2 + Modulate frequency of Osc3 with Osc2 Модулювати частоту осциллятора 3 сигналом з осц2 + Modulate phase of Osc3 with Osc2 Модулювати фазу Осц3 осциллятором2 + The CRS knob changes the tuning of oscillator 1 in semitone steps. Регулятор CRS змінює налаштування осциллятора 1 у розмірі півтону. + The CRS knob changes the tuning of oscillator 2 in semitone steps. Регулятор CRS змінює налаштування осциллятора 2 у розмірі півтону. + The CRS knob changes the tuning of oscillator 3 in semitone steps. Регулятор CRS змінює налаштування осциллятора 3 у розмірі півтону. + + + + 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. FTL і FTR змінюють підстроювання осциллятора для лівого і правого каналів відповідно. Вони можуть додати стерео розстроювання осциллятора, яке розширює стерео картину і створює ілюзію космосу. + + + The SPO knob modifies the difference in phase between left and right channels. Higher difference creates a wider stereo image. Регулятор SPO змінює фазову різницю між лівим і правим каналами. Висока різниця створює більш широку стерео картину. + 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. PW регулятор контролює ширину пульсацій, також відому як робочий цикл осциллятора 1. Осциллятор 1 це цифровий імпульсний хвильовий генератор, він не відтворює сигнал з обмеженою смугою, це означає, що його можна використовувати як чутний осциллятор, але це призведе до накладення сигналів (або згладжування) . Його можна використовувати й як не чутне джерело синхронізуючого сигналу, для використання в синхронізації осцилляторів 2 і 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. Надсилати синхронізацію при підвищенні: при включенні, сигнал синхронізації надсилається кожен раз коли стан осциллятора 1 змінюється з низького на високий, тобто коли амплітуда змінюється від -1 до 1. Тон осциллятора 1, фаза і ширина пульсацій може впливати на час синхронізації, але гучність не має ефекту. Сигнал синхронізації надсилається незалежно для лівого і правого каналів. + 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. Надсилати синхронізацію при зниженні: при включенні, сигнал синхронізації надсилається кожен раз коли стан осциллятора 1 змінюється з виского на низьке, тобто коли амплітуда змінюється від 1 до -1. Тон осциллятора 1, фаза і ширина пульсацій може впливати на час синхронізації, але гучність не має ефекту. Сигнал синхронізації надсилається незалежно для лівого і правого каналів. + + Hard sync: Every time the oscillator receives a sync signal from oscillator 1, its phase is reset to 0 + whatever its phase offset is. Жорстка синхронізація: Кожен раз при отриманні осциллятором сигналу синхронізації від осциллятора 1, його фаза скидається до 0 + його межа фази, якою б вона не була. + + Reverse sync: Every time the oscillator receives a sync signal from oscillator 1, the amplitude of the oscillator gets inverted. Реверс синхронізація: Кожен раз при отриманні сигналу синхронізації від осциллятора 1, амплітуда осциллятора перевертається. + Choose waveform for oscillator 2. Вибрати форму хвилі для осциллятора 2. + Choose waveform for oscillator 3's first sub-osc. Oscillator 3 can smoothly interpolate between two different waveforms. Виберіть форму хвилі для першого додаткового осциллятора осциллятора 3. Осциллятор 3 може м'яко переходити між двома різними хвилями. + Choose waveform for oscillator 3's second sub-osc. Oscillator 3 can smoothly interpolate between two different waveforms. Виберіть форму хвилі для другого додаткового осциллятора осциллятора 3. Осциллятор 3 може м'яко переходити між двома різними хвилями. + 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. SUB змінює змішування двох дод осцилляторів осциллятора 3. Кожен дод. осц. може бути встановлений для створення різних хвиль і осциллятор 3 може м'яко переходити між ними. Усі вхідні модуляції для осциллятора 3 застосовуються на обидва дод.осц./хвилі одним і тим же чином. + 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. @@ -4759,6 +6134,7 @@ Mix mode means no modulation: the outputs of the oscillators are simply mixed to Змішаний (Mix) режим означає без модуляції: виходи осцилляторів просто змішуються один з одним. + 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. @@ -4767,6 +6143,7 @@ AM means amplitude modulation: Oscillator 3's amplitude (volume) is modulat AM режим значить Амплітуда Модуляції: Осциллятори 2 модулює амплітуду (гучність) осциллятора 3. + 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. @@ -4775,6 +6152,7 @@ FM means frequency modulation: Oscillator 3's frequency (pitch) is modulate FM (ЧМ) режим означає Частотна Модуляція: осциллятор 2 модулює частоту (pitch, тональність) осциллятора 3. Частота модуляції відбувається у фазі модуляції, яка дає більш стабільний загальний тон, ніж "чиста" частотна модуляція. + 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. @@ -4783,6 +6161,7 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PM (ФМ) режим означає Фазова Модуляція: Осциллятор 2 модулює фазу осциллятора 3. Це відрізняється від частотної модуляції тим, що зміни фаз не сумуються. + 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... Виберіть форму хвилі для LFO 1 (НизькоЧастотнийГенератор). @@ -4790,6 +6169,7 @@ PM (ФМ) режим означає Фазова Модуляція: Осцил Згладжена версія переходить між цими станами з косинусоїдальною інтерполяцією. Ці випадкові режими можуть бути використані, щоб дати "життя" вашим налаштуванням - додати трішки аналогової непередбачуваності ... + 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... Виберіть форму хвилі для LFO 2 (НизкоЧастотнийГенератор). @@ -4797,150 +6177,110 @@ PM (ФМ) режим означає Фазова Модуляція: Осцил Згладжена версія переходить між цими станами з косинусоїдальною інтерполяцією. Ці випадкові режими можуть бути використані, щоб дати "життя" вашим налаштуванням - додати трішки аналогової непередбачуваності ... + + Attack causes the LFO to come on gradually from the start of the note. Атака відповідає за плавність поведінки LFO від початку ноти. + + Rate sets the speed of the LFO, measured in milliseconds per cycle. Can be synced to tempo. Rate (Частота) встановлює швидкість LFO, вимірювану в мілісекундах за цикл. Може синхронізуватися з темпом. + + PHS controls the phase offset of the LFO. PHS контролює зсув фази LFO (НЧГ). + + PRE, or pre-delay, delays the start of the envelope from the start of the note. 0 means no delay. PRE передзатримка, затримує старт обвідної від початку ноти. 0 означає без затримки. + + ATT, or attack, controls how fast the envelope ramps up at start, measured in milliseconds. A value of 0 means instant. ATT атака контролює як швидко обвідна нарощується на старті, вимірюється в мілісекундах. Значення 0 означає миттєво. + + HOLD controls how long the envelope stays at peak after the attack phase. HOLD (УТРИМУВАТИ) контролює як довго обвідна залишається на піку після фази атаки. + + 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. DEC (decay) згасання контролює як швидко обвідна спадає з пікового значення, вимірюється в мілісекундах, як довго буде йти з піку до нуля. Реальне загасання може бути коротшим, якщо використовується витримка. + + 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. SUS (sustain) витримка, контролює рівень обвідної. Загасання фази не піде нижче цього рівня поки нота утримується. + + 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. REL (release) відпускання контролює як довго нота відпускається, вимірюється в довготі падіння від піку до нуля. Реальне відпускання може бути коротшим, залежно від фази, в якій нота відпущена. + + 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. Регулятор нахилу контролює криву або форму обвідної. Значення 0 створює прямі підйоми і спади. Від'ємні величини створюють криві з уповільненим початком, швидким піком і знову уповільненим спадом. Позитивні значення створюють криві які починаються і закінчуються швидко, але довше залишаються на піках. - Volume - Гучність - - - Panning - Баланс - - - Coarse detune - Грубе підстроювання - - - semitones - півтон(а,ів) - - - Finetune left - Точне настроювання лівого каналу - - - cents - відсотків - - - Finetune right - Точне настроювання правого каналу - - - Stereo phase offset - Зміщення стерео-фази - - - deg - град - - - Pulse width - Довжина імпульсу - - - Send sync on pulse rise - Відправляти синхронізацію на підйомі імпульсу - - - Send sync on pulse fall - Відправити синхронізацію на падінні пульсу - - - Hard sync oscillator 2 - Жорстка синхронізація осциллятора 2 - - - Reverse sync oscillator 2 - Верерс синхронізація осциллятора 2 - - - Sub-osc mix - Мікс суб-осциляторів - - - Hard sync oscillator 3 - Жорстка синхронізація осциллятора 3 - - - Reverse sync oscillator 3 - Верерс синхронізація осциллятора 3 - - - Attack - Вступ - - - Rate - Частота вибірки - - - Phase - Фаза - - - Pre-delay - Передзатримка - - - Hold - Утримання - - - Decay - Згасання - - - Sustain - Витримка - - - Release - Зменшення - - - Slope - Нахил - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Modulation amount Глибина модуляції @@ -4948,34 +6288,42 @@ PM (ФМ) режим означає Фазова Модуляція: Осцил MultitapEchoControlDialog + Length Довжина + Step length: Довжина кроку: + Dry Сухий + Dry Gain: Сухе підсилення: + Stages Етапи + Lowpass stages: НЧ етапи: + Swap inputs Обмін входами + Swap left and right input channel for reflections Дзеркальний обмін лівим і правим каналами @@ -4983,82 +6331,102 @@ PM (ФМ) режим означає Фазова Модуляція: Осцил NesInstrument + Channel 1 Coarse detune Грубе підстроювання 1 каналу + Channel 1 Volume Гучність 1 каналу + Channel 1 Envelope length Довжина обвідної 1 каналу + Channel 1 Duty cycle Робочий цикл 1 каналу + Channel 1 Sweep amount Кількість розгортки 1 каналу + Channel 1 Sweep rate Швидкість розгортки 1 каналу + Channel 2 Coarse detune Грубе підстроювання 2 каналу + Channel 2 Volume Гучність 2 каналу + Channel 2 Envelope length Довжина обвідної 2 каналу + Channel 2 Duty cycle Робочий цикл 2 каналу + Channel 2 Sweep amount Кількість розгортки 2 каналу + Channel 2 Sweep rate Швидкість розгортки 2 каналу + Channel 3 Coarse detune Грубе підстроювання 3 каналу + Channel 3 Volume Гучність 3 каналу + Channel 4 Volume Гучність 4 каналу + Channel 4 Envelope length Довжина обвідної 4 каналу + Channel 4 Noise frequency Частота шуму 4 каналу + Channel 4 Noise frequency sweep Частота розгортки шуму 4 каналу + Master volume Основна гучність + Vibrato Вібрато @@ -5066,114 +6434,155 @@ PM (ФМ) режим означає Фазова Модуляція: Осцил NesInstrumentView + + + + Volume Гучність + + + Coarse detune Грубе підстроювання + + + Envelope length Довжина обвідної + Enable channel 1 Увімкнути канал 1 + Enable envelope 1 Увімкнути обвідну 1 + Enable envelope 1 loop Увімкнти повтор обвідної 1 + Enable sweep 1 Увімкнути розгортку 1 + + Sweep amount Кількість розгортки + + Sweep rate Темп розгортки + + 12.5% Duty cycle 12.5% Робочого циклу + + 25% Duty cycle 25% Робочого циклу + + 50% Duty cycle 50% Робочого циклу + + 75% Duty cycle 75% Робочого циклу + Enable channel 2 Увімкнути канал 2 + Enable envelope 2 Увімкнути обвідну 2 + Enable envelope 2 loop Увімкнти повтор обвідної 2 + Enable sweep 2 Увімкнути розгортку 2 + Enable channel 3 Увімкнути канал 3 + Noise Frequency Частота шуму + Frequency sweep Частота темпу + Enable channel 4 Увімкнути канал 4 + Enable envelope 4 Увімкнути обвідну 4 + Enable envelope 4 loop Увімкнти повтор обвідної 4 + Quantize noise frequency when using note frequency Квантування частоту шуму при використанні частоти ноти + Use note frequency for noise Використовувати частоту ноти для шуму + Noise mode Форма шуму + Master Volume Основна гучність + Vibrato Вібрато @@ -5181,81 +6590,103 @@ PM (ФМ) режим означає Фазова Модуляція: Осцил OscillatorObject - Osc %1 volume - Гучність осциллятора %1 - - - Osc %1 panning - Стереобаланс для осциллятора %1 - - - Osc %1 coarse detuning - Підстроювання осциллятора %1 грубе - - - Osc %1 fine detuning left - Точне підстроювання лівого каналу осциллятора %1 - - - Osc %1 fine detuning right - Підстроювання правого каналу осциллятора %1 тонка - - - Osc %1 phase-offset - Зміщення фази осциллятора %1 - - - Osc %1 stereo phase-detuning - Підстроювання стерео-фази осциллятора %1 - - - Osc %1 wave shape - Гладкість сигналу осциллятора %1 - - - Modulation type %1 - Тип модуляції %1 - - + Osc %1 waveform Форма сигналу осциллятора %1 + Osc %1 harmonic Осц %1 гармонійний + + + + Osc %1 volume + Гучність осциллятора %1 + + + + + Osc %1 panning + Стереобаланс для осциллятора %1 + + + + + Osc %1 fine detuning left + Точне підстроювання лівого каналу осциллятора %1 + + + + Osc %1 coarse detuning + Підстроювання осциллятора %1 грубе + + + + Osc %1 fine detuning right + Підстроювання правого каналу осциллятора %1 тонка + + + + Osc %1 phase-offset + Зміщення фази осциллятора %1 + + + + Osc %1 stereo phase-detuning + Підстроювання стерео-фази осциллятора %1 + + + + Osc %1 wave shape + Гладкість сигналу осциллятора %1 + + + + Modulation type %1 + Тип модуляції %1 + PatchesDialog + Qsynth: Channel Preset Q-Синтезатор: Канал передустановлено + Bank selector Селектор банку + Bank Банк + Program selector Селектор програм + Patch Патч + Name І'мя + OK ОК + Cancel Скасувати @@ -5263,46 +6694,57 @@ PM (ФМ) режим означає Фазова Модуляція: Осцил PatmanView + Open other patch Відкрити інший патч + Click here to open another patch-file. Loop and Tune settings are not reset. Натисніть щоб відкрити інший патч-файл. Циклічність і налаштування при цьому збережуться. + Loop Повтор + Loop mode Режим повтору + Here you can toggle the Loop mode. If enabled, PatMan will use the loop information available in the file. Тут вмикається/вимикається режим повтору, при увімкнені PatMan буде використовувати інформацію про повтор з файлу. + Tune Підлаштувати + Tune mode Тип підстроювання + Here you can toggle the Tune mode. If enabled, PatMan will tune the sample to match the note's frequency. Тут вмикається/вимикається режим підстроювання. Якщо його увімкнено, то PatMan змінить запис так, щоб він збігався по частоті з нотою. + No file selected Файл не вибрано + Open patch file Відкрити патч-файл + Patch-Files (*.pat) Патч-файли (*.pat) @@ -5310,38 +6752,47 @@ PM (ФМ) режим означає Фазова Модуляція: Осцил PatternView - Open in piano-roll - Відкрити в редакторі нот - - - Clear all notes - Очистити всі ноти - - - Reset name - Скинути назву - - - Change name - Перейменувати - - - Add steps - Додати такти - - - Remove steps - Видалити такти - - + use mouse wheel to set velocity of a step використовуйте колесо миші для встановлення кроку гучності + double-click to open in Piano Roll Відкрити в редакторі нот подвійним клацанням миші + + Open in piano-roll + Відкрити в редакторі нот + + + + Clear all notes + Очистити всі ноти + + + + Reset name + Скинути назву + + + + Change name + Перейменувати + + + + Add steps + Додати такти + + + + Remove steps + Видалити такти + + + Clone Steps Клонувати такти @@ -5349,14 +6800,17 @@ PM (ФМ) режим означає Фазова Модуляція: Осцил 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. Через помилку в старій версії LMMS контролери вершин не можуть правильно підключатися. Будь-ласка переконайтеся, що контролери вершин правильно приєднані і перезбережіть цей файл, вибачте, за заподіяні незручності. @@ -5364,10 +6818,12 @@ PM (ФМ) режим означає Фазова Модуляція: Осцил PeakControllerDialog + PEAK ПІК + LFO Controller Контролер LFO @@ -5375,307 +6831,383 @@ PM (ФМ) режим означає Фазова Модуляція: Осцил PeakControllerEffectControlDialog + BASE БАЗА + Base amount: Базове значення: - Modulation amount: - Глибина модуляції: - - - Attack: - Вступ: - - - Release: - Зменшення: - - + AMNT ГЛИБ + + Modulation amount: + Глибина модуляції: + + + MULT МНОЖ + Amount Multiplicator: Величина множника: + ATCK ВСТУП + + Attack: + Вступ: + + + DCAY ЗГАС - Treshold: - Поріг: + + Release: + Зменшення: + TRSH - + TRSH + + + + Treshold: + Поріг: PeakControllerEffectControls + Base value Опорне значення + Modulation amount Глибина модуляції - Mute output - Заглушити вивід - - + Attack Вступ + Release Зменшення + + Treshold + Поріг + + + + Mute output + Заглушити вивід + + + Abs Value Абс Значення + Amount Multiplicator Величина множника - - Treshold - Поріг - PianoRoll - Please open a pattern by double-clicking on it! - Відкрийте шаблон за допомогою подвійного клацання мишею! - - - Last note - По останій ноті - - - Note lock - Фіксація нот - - + Note Velocity Гучність нот + Note Panning Стереофонія нот + Mark/unmark current semitone Відмітити/Зняти відмітку з поточного півтону - Mark current scale - Відмітити поточний підйом - - - Mark current chord - Відмітити поточний акорд - - - Unmark all - Зняти виділення - - - No scale - Без підйому - - - No chord - Прибрати акорди - - - Velocity: %1% - Гучність %1% - - - Panning: %1% left - Баланс %1% лівий - - - Panning: %1% right - Баланс %1% правий - - - Panning: center - Баланс: по середині - - - Please enter a new value between %1 and %2: - Введіть нове значення від %1 до %2: - - + 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% + Гучність %1% + + + + Panning: %1% left + Баланс %1% лівий + + + + Panning: %1% right + Баланс %1% правий + + + + Panning: center + Баланс: по середині + + + + Please open a pattern by double-clicking on it! + Відкрийте шаблон за допомогою подвійного клацання мишею! + + + + + Please enter a new value between %1 and %2: + Введіть нове значення від %1 до %2: + PianoRollWindow + Play/pause current pattern (Space) Гра/Пауза поточної мелодії (Пробіл) + Record notes from MIDI-device/channel-piano Записати ноти з цифрового музичного інструмента (MIDI) + Record notes from MIDI-device/channel-piano while playing song or BB track Записати ноти з цифрового музичного інструменту (MIDI) під час відтворення пісні або доріжки Ритм-Басу + 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. Натисніть цю кнопку, якщо ви хочете записати ноти з пристрою MIDI або віртуального синтезатора відповідного каналу. Пізніше ви зможете відредагувати записаний шаблон. + 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. Натисніть цю кнопку, якщо ви хочете записати ноти з пристрою MIDI або віртуального синтезатора відповідного каналу. Під час запису всі ноти записуються в цей шаблон, і ви будете чути композицію або РБ доріжку на задньому плані. + Click here to stop playback of current pattern. Натисніть тут, якщо ви хочете зупинити відтворення поточного шаблону. + + Edit actions + Зміна + + + Draw mode (Shift+D) Режим малювання (Shift + D) + Erase mode (Shift+E) Режим стирання (Shift+E) + Select mode (Shift+S) Режим вибору нот (Shift+S) - Detune mode (Shift+T) - Режим підлаштовування (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. Режим малювання нот, в ньому ви можете додавати/переміщати і змінювати тривалість одиночних нот. Це режим за замовчуванням і використовується більшу частину часу. Для включення цього режиму можна скористатися комбінацією клавіш Shift+D, утримуйте %1 для тимчасового перемикання в режим вибору. + 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. Режим стирання. У цьому режимі ви можете стирати ноти. Для увімкнення цього режиму можна скористатися комбінацією клавіш Shift+E. + 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. Режим виділення. У цьому режимі можна виділяти ноти, також можна утримувати %1 в режимі малювання, щоб на час увійти в режим виділення. - 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. - Режим підстроювання. У цьому режимі можна вибирати ноти для автоматизації їх підлаштування. Можна використовувати це для переходів нот від однієї до іншої. Для активації з клавіатури <Shift+T>. + + Pitch Bend mode (Shift+T) + Режим Pitch Bend (Shift+T) - Cut selected notes (%1+X) - Перемістити виділені ноти до буферу (%1+X) + + 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. + Натисніть тут для активації Pitch Blend режиму. Ви зможете клікнути на ноту, щоб почати автоматичний детюн. Можна використовувати це для "ковзання" від однієї ноти до іншої. Можна включити цей режим за допомогою Shift + T. - Copy selected notes (%1+C) - Копіювати виділені ноти до буферу (%1+X) - - - Paste notes from clipboard (%1+V) - Вставити ноти з буферу (%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. - При натиснені цієї кнопки ноти з буферу будуть вставлені в перший видимий такт. - - - 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. - "Q" позначає квантування і контролює розмір нотної сітки і контрольні точки тяжіння. З меншою величиною квантування, можна малювати короткі ноти в редаторі нот і більш точно контролювати точки в редакторі Автоматизації. - - - 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 - Дозволяє вибрати довжину нової ноти. "Остання Нота" означає, що LMMS буде використовувати довжину ноти, зміненої в останній раз - - - 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! - Функція безпосередньо пов'язана з контекстним меню на віртуальній клавіатурі зліва в нотному редакторі. Після того, як обраний масштаб у випадаючому меню, можна натиснути правою кнопкою у віртуальній клавіатурі і вибрати "Mark Current Scale" (Відзначити поточний масштаб). LMMS підсвітить всі ноти які лежать в обраному масштабі для обраної клавіші! - - - 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. - Дозволяє вибрати акорд, який LMMS потім зможе намалювати або підсвітити. У цьому меню можна знайти найбільш популярні акорди. Після того, як ви вибрали акорд, натисніть в будь-якому місці, щоб поставити його, а правим кліком по віртуальній клавіатурі відкривається контекстне меню і підсвічування акорду. Для повернення в режим однієї ноти потрібно вибрати "Без акорду" в цьому випадаючому меню. - - - Edit actions - Зміна + + Quantize + Квантовать + Copy paste controls Управління копіюванням та вставкою + + Cut selected notes (%1+X) + Перемістити виділені ноти до буферу (%1+X) + + + + Copy selected notes (%1+C) + Копіювати виділені ноти до буферу (%1+X) + + + + Paste notes from clipboard (%1+V) + Вставити ноти з буферу (%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. + "Q" позначає квантування і контролює розмір нотної сітки і контрольні точки тяжіння. З меншою величиною квантування, можна малювати короткі ноти в редаторі нот і більш точно контролювати точки в редакторі Автоматизації. + + + + 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 + Дозволяє вибрати довжину нової ноти. "Остання Нота" означає, що LMMS буде використовувати довжину ноти, зміненої в останній раз + + + + 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! + Функція безпосередньо пов'язана з контекстним меню на віртуальній клавіатурі зліва в нотному редакторі. Після того, як обраний масштаб у випадаючому меню, можна натиснути правою кнопкою у віртуальній клавіатурі і вибрати "Mark Current Scale" (Відзначити поточний масштаб). LMMS підсвітить всі ноти які лежать в обраному масштабі для обраної клавіші! + + + + 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. + Дозволяє вибрати акорд, який LMMS потім зможе намалювати або підсвітити. У цьому меню можна знайти найбільш популярні акорди. Після того, як ви вибрали акорд, натисніть в будь-якому місці, щоб поставити його, а правим кліком по віртуальній клавіатурі відкривається контекстне меню і підсвічування акорду. Для повернення в режим однієї ноти потрібно вибрати "Без акорду" в цьому випадаючому меню. + + + + Piano-Roll - %1 Нотний редактор - %1 + + Piano-Roll - no pattern Нотний редактор - без шаблону - - Quantize - Квантовать - PianoView + Base note Опорна нота @@ -5683,20 +7215,24 @@ PM (ФМ) режим означає Фазова Модуляція: Осцил Plugin + Plugin not found Модуль не знайдено + The plugin "%1" wasn't found or could not be loaded! Reason: "%2" Модуль «%1» відсутній чи не може бути завантажений! Причина: «%2» + Error while loading plugin Помилка завантаження модуля + Failed to load plugin "%1"! Не вдалося завантажити модуль «%1»! @@ -5704,25 +7240,30 @@ Reason: "%2" PluginBrowser + + Instrument Plugins + Модулі інструментів + + + Instrument browser Огляд інструментів + Drag an instrument into either the Song-Editor, the Beat+Bassline Editor or into an existing instrument track. Ви можете переносити потрібні вам інструменти з цієї панелі в музичний, ритм-бас редактор або в існуючу доріжку інструменту. - - Instrument Plugins - - PluginFactory + Plugin not found. Модуль не знайдено. + LMMS plugin %1 does not have a plugin descriptor named %2! LMMS плагін %1 не має опису плагіна з ім'ям %2! @@ -5730,118 +7271,147 @@ Reason: "%2" ProjectNotes - Project notes - Нотатки до проекту + + Project Notes + Примітки проекту - Put down your project notes here. - Тут ви можете тримати замітки до свого проекту. + + Enter project notes here + Напишіть примітки до проекту тут + Edit Actions Зміна + &Undo &U Скасувати + %1+Z %1+Z + &Redo &R Повторити + %1+Y %1+Y + &Copy &C Копіювати + %1+C %1+C + Cu&t &t Вирізати + %1+X %1+X + &Paste &P Вставити + %1+V %1+V + Format Actions Форматування + &Bold Напів&жирний + %1+B %1+B + &Italic &Курсив + %1+I %1+I + &Underline &Підкреслити + %1+U %1+U + &Left По &лівому краю + %1+L %1+L + C&enter По &центрі + %1+E %1+E + &Right По &правому краю + %1+R %1+R + &Justify По &ширині + %1+J %1+J + &Color... &C Колір... @@ -5849,142 +7419,274 @@ Reason: "%2" ProjectRenderer + WAV-File (*.wav) Файл WAV (*.wav) + Compressed OGG-File (*.ogg) Стиснутий файл OGG (*.ogg) + + + Compressed MP3-File (*.mp3) + Стиснутий MP3-файл (* .mp3) + QWidget + + + Name: І'мя: + + Maker: Розробник: + + Copyright: Авторське право: + + Requires Real Time: Потрібна обробка в реальному часі: + + + + + + Yes Так + + + + + + No Ні + + Real Time Capable: Робота в реальному часі: + + In Place Broken: Замість зламаного: + + Channels In: Канали в: + + Channels Out: Канали з: - File: - Файл: - - + File: %1 Файл: %1 + + + File: + Файл: + RenameDialog + Rename... Перейменувати ... + + ReverbSCControlDialog + + + Input + Ввід + + + + Input Gain: + Вхідне підсилення: + + + + Size + Розмір + + + + Size: + Розмір: + + + + Color + Колір + + + + Color: + Колір: + + + + Output + Вивід + + + + Output Gain: + Вихідне підсилення: + + + + ReverbSCControls + + + Input Gain + Вхідне підсилення + + + + Size + Розмір + + + + Color + Колір + + + + Output Gain + Вихідне підсилення + + SampleBuffer + + Fail to open file + Не вдається відкрити файл + + + + Audio files are limited to %1 MB in size and %2 minutes of playing time + Аудіофайли обмежено розміром в %1 МБ і %2 хвилин(и) програвання + + + Open audio file Відкрити звуковий файл + + All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + Всі Аудіо-файли (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + + + Wave-Files (*.wav) Файли Wave (*.wav) + OGG-Files (*.ogg) Файли OGG (*.ogg) + DrumSynth-Files (*.ds) Файли DrumSynth (*.ds) + FLAC-Files (*.flac) Файли FLAC (*.flac) + SPEEX-Files (*.spx) Файли SPEEX (*.spx) + VOC-Files (*.voc) Файли VOC (*.voc) + AIFF-Files (*.aif *.aiff) Файли AIFF (*.aif *.aiff) + AU-Files (*.au) Файли AU (*.au) + RAW-Files (*.raw) Файли RAW (*.raw) - - All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) - Всі Аудіо-файли (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) - SampleTCOView + double-click to select sample Виберіть запис подвійним натисненням миші + Delete (middle mousebutton) Видалити (середня кнопка мишки) + Cut Вирізати + Copy Копіювати + Paste Вставити + Mute/unmute (<%1> + middle click) Заглушити/включити (<%1> + середня кнопка миші) @@ -5992,41 +7694,51 @@ Reason: "%2" SampleTrack - Sample track - Доріжка запису - - + Volume Гучність + Panning Баланс + + + + Sample track + Доріжка запису + SampleTrackView + Track volume Гучність доріжки + Channel volume: Гучність каналу: + VOL ГУЧН + Panning Баланс + Panning: Баланс: + PAN БАЛ @@ -6034,496 +7746,659 @@ Reason: "%2" SetupDialog + Setup LMMS Налаштування 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 Синхронізувати VST плагіни з хостом відтворення + 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 + Використовувати вбудований обробник NaN + + + + PLUGIN EMBEDDING + ВСТАНОВИТИ УПРАВЛІННЯ + + + + No embedding + Не встановлено + + + + Embed using Qt API + Встановлення використовуючи Qt API + + + + Embed using native Win32 API + Встановлення використовуючи рідний Win32 API + + + + Embed using XEmbed protocol + Встановлення використовуючи протокол XEmbed + + + LANGUAGE МОВА + + Paths Шляхи + + Directories + Каталоги + + + LMMS working directory Робочий каталог LMMS - VST-plugin directory - Каталог модулів VST + + Themes directory + Каталог тем + Background artwork Фонове зображення + + VST-plugin directory + Каталог модулів VST + + + + GIG directory + Каталог GIG + + + + SF2 directory + Каталог SF2 + + + + LADSPA plugin directories + Каталог модулів LADSPA + + + STK rawwave directory Каталог STK rawwave + Default Soundfont File Основний Soundfont файл + + 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 + MIDI INTERFACE ІНТЕРФЕЙС MIDI + OK ОК + Cancel Скасувати + Restart LMMS Перезапустіть LMMS + Please note that most changes won't take effect until you restart LMMS! Врахуйте, що більшість налаштувань не вступлять в силу до перезапуску програми! + Frames: %1 Latency: %2 ms Фрагментів: %1 Затримка: %2 мс + 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. Тут ви можете налаштувати розмір внутрішнього звукового буфера LMMS. Менші значення дають менший час відгуку програми, але підвищують споживання ресурсів - це особливо помітно на старих машинах і системах, ядро ​​яких не підтримує пріоритету реального часу. Якщо спостерігається переривчастий звук, спробуйте збільшити розмір буферу. + Choose LMMS working directory Вибір робочого каталогу LMMS - Choose your VST-plugin directory - Вибір свого каталогу для модулів VST - - - Choose artwork-theme directory - Вибір каталогу з темою оформлення для LMMS - - - Choose LADSPA plugin directory - Вибір каталогу з модулями LADSPA - - - Choose STK rawwave directory - Вибір каталогу STK rawwave - - - Choose default SoundFont - Вибрати головний SoundFont - - - Choose background artwork - Вибрати фонове зображення - - - 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. - Будь ласка, виберіть звукову систему. Залежно від конфігурації під час компілювання програми, ви можете використовувати ALSA, JACK, OSS та інші. У нижній частині вікна налаштування можна задати специфічні параметри обраної системи. - - - 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. - Будь ласка, виберіть інтерфейс MIDI. Залежно від конфігурації під час компілювання програми, ви можете використовувати ALSA, OSS та інші. У нижній частині вікна налаштування можна задати специфічні параметри обраного інтерфейсу. - - - Reopen last project on start - Відкривати останній проект при запуску - - - Directories - Каталоги - - - Themes directory - Каталог тем - - - GIG directory - Каталог GIG - - - SF2 directory - Каталог SF2 - - - LADSPA plugin directories - Каталог модулів LADSPA - - - Auto save - Авто-збереження - - + Choose your GIG directory Виберіть каталог GIG + Choose your SF2 directory Виберіть каталог SF2 + + Choose your VST-plugin directory + Вибір свого каталогу для модулів VST + + + + Choose artwork-theme directory + Вибір каталогу з темою оформлення для LMMS + + + + Choose LADSPA plugin directory + Вибір каталогу з модулями LADSPA + + + + Choose STK rawwave directory + Вибір каталогу STK rawwave + + + + Choose default SoundFont + Вибрати головний SoundFont + + + + Choose background artwork + Вибрати фонове зображення + + + minutes хвилин + minute хвилина - Enable auto-save - - - - Allow auto-save while playing - - - + Disabled - + Вимкнено + Auto-save interval: %1 - + Інтервал автоматичного збереження: %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. - + Встановіть проміжок часу автоматичного резервного копіювання в %1. +Не забудьте також зберегти проект вручну. Ви можете вимкнути автозбереження, інколи деяким старим системи тяжко в таком режимі. + + + + 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. + Будь ласка, виберіть звукову систему. Залежно від конфігурації під час компілювання програми, ви можете використовувати ALSA, JACK, OSS та інші. У нижній частині вікна налаштування можна задати специфічні параметри обраної системи. + + + + 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. + Будь ласка, виберіть інтерфейс MIDI. Залежно від конфігурації під час компілювання програми, ви можете використовувати ALSA, OSS та інші. У нижній частині вікна налаштування можна задати специфічні параметри обраного інтерфейсу. Song + Tempo Темп + Master volume Основна гучність + Master pitch Основна тональність - Project saved - Проект збережено - - - The project %1 is now saved. - Проект %1 збережено. - - - Project NOT saved. - Проект НЕ ЗБЕРЕЖЕНО. - - - The project %1 was not saved! - Проект %1 не збережено! - - - Import file - Імпорт файлу - - - MIDI sequences - MiDi послідовність - - - Hydrogen projects - Hydrogen проекти - - - 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... - Вибір файлу для експорту проекту ... - - - The following errors occured while loading: - Наступні помилки виникли при завантаженні: - - - MIDI File (*.mid) - MIDI-файл (* mid) - - + LMMS Error report Повідомлення про помилку в LMMS + + Project saved + Проект збережено + + + + The project %1 is now saved. + Проект %1 збережено. + + + + Project NOT saved. + Проект НЕ ЗБЕРЕЖЕНО. + + + + The project %1 was not saved! + Проект %1 не збережено! + + + + Import file + Імпорт файлу + + + + MIDI sequences + MiDi послідовність + + + + Hydrogen projects + Hydrogen проекти + + + + 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) + MIDI-файл (* mid) + + + + The following errors occured while loading: + Наступні помилки виникли при завантаженні: SongEditor + Could not open file Не можу відкрити файл - Could not write 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. Неможливо відкрити файл %1, ймовірно, немає дозволу на його читання. Будь-ласка переконайтеся, що є принаймні права на читання цього файлу і спробуйте ще раз. - Error in file - Помилка у файлі - - - The file %1 seems to contain errors and therefore can't be loaded. - Файл %1 можливо містить помилки через які не може завантажитися. - - - Tempo - Темп - - - TEMPO/BPM - ТЕМП/BPM - - - tempo of song - Темп музики - - - 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). - Це значення задає темп музики в ударах в хвилину (англ. аббр. BPM). На кожен такт приходить чотири удари, так що темп в ударах в хвилину фактично вказує, скільки чвертей такту програється за хвилину (або, що те ж, кількість тактів, що програються за чотири хвилини). - - - High quality mode - Висока якість - - - Master volume - Основна гучність - - - master volume - основна гучність - - - Master pitch - Основна тональність - - - master pitch - основна тональність - - - Value: %1% - Значення: %1% - - - Value: %1 semitones - Значення: %1 півтон(у/ів) + + 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. Неможливо відкрити %1 для запису, можливо, немає дозволу на запис в цей файл, будь-ласка упевніться, що є доступ до цього файлу і спробуйте знову. + + Error in file + Помилка у файлі + + + + The file %1 seems to contain errors and therefore can't be loaded. + Файл %1 можливо містить помилки через які не може завантажитися. + + + + Version difference + Різниця версій + + + + This %1 was created with LMMS %2. + Цей %1 було створено в LMMS версії %2 + + + template шаблон + project проект - Version difference - + + Tempo + Темп - This %1 was created with LMMS %2. - Цей %1 було створено в LMMS версії %2 + + TEMPO/BPM + ТЕМП/BPM + + + + tempo of song + Темп музики + + + + 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). + Це значення задає темп музики в ударах в хвилину (англ. аббр. BPM). На кожен такт приходить чотири удари, так що темп в ударах в хвилину фактично вказує, скільки чвертей такту програється за хвилину (або, що те ж, кількість тактів, що програються за чотири хвилини). + + + + High quality mode + Висока якість + + + + + Master volume + Основна гучність + + + + master volume + основна гучність + + + + + Master pitch + Основна тональність + + + + master pitch + основна тональність + + + + Value: %1% + Значення: %1% + + + + Value: %1 semitones + Значення: %1 півтон(у/ів) SongEditorWindow + Song-Editor Музичний редактор + Play song (Space) Почати відтворення (Пробіл) + Record samples from Audio-device Записати семпл зі звукового пристрою + Record samples from Audio-device while playing song or BB track Записати семпл з аудіо-пристрої під час відтворення в музичному чи ритм/бас редакторі + Stop song (Space) Зупинити відтворення (Пробіл) - Add beat/bassline - Додати ритм/бас - - - Add sample-track - Додати доріжку запису - - - Add automation-track - Додати доріжку автоматизації - - - Draw mode - Режим малювання - - - Edit mode (select and move) - Правка (виділення/переміщення) - - + 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. Натисніть, щоб прослухати створену мелодію. Відтворення почнеться з позиції курсора (зелений трикутник); ви можете рухати його під час програвання. + 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 Стежити + + Add beat/bassline + Додати ритм/бас + + + + Add sample-track + Додати доріжку запису + + + + Add automation-track + Додати доріжку автоматизації + + + Edit actions Зміна + + Draw mode + Режим малювання + + + + Edit mode (select and move) + Правка (виділення/переміщення) + + + Timeline controls Управління хронологією + Zoom controls Управління масштабом @@ -6531,10 +8406,12 @@ Remember to also save your project manually. You can choose to disable saving wh SpectrumAnalyzerControlDialog + Linear spectrum Лінійний спектр + Linear Y axis Лінійна вісь ординат @@ -6542,14 +8419,17 @@ Remember to also save your project manually. You can choose to disable saving wh SpectrumAnalyzerControls + Linear spectrum Лінійний спектр + Linear Y axis Лінійна вісь ординат + Channel mode Режим каналу @@ -6557,14 +8437,17 @@ Remember to also save your project manually. You can choose to disable saving wh SubWindow + Close Закрити + Maximize Розгорнути + Restore Відновити @@ -6572,6 +8455,8 @@ Remember to also save your project manually. You can choose to disable saving wh TabWidget + + Settings for %1 Налаштування для %1 @@ -6579,74 +8464,93 @@ Remember to also save your project manually. You can choose to disable saving wh TempoSyncKnob + + Tempo Sync Синхронізація темпу + No Sync Синхронізації немає + Eight beats Вісім ударів (дві ноти) + Whole note Ціла нота + Half note Півнота + Quarter note Чверть ноти + 8th note Восьма ноти + 16th note 1/16 ноти + 32nd note 1/32 ноти + Custom... Своя... + Custom Своя + Synced to Eight Beats Синхро по 8 ударам + Synced to Whole Note Синхро по цілій ноті + Synced to Half Note Синхро по половині ноти + Synced to Quarter Note Синхро по чверті ноти + Synced to 8th Note Синхро по 1/8 ноти + Synced to 16th Note Синхро по 1/16 ноти + Synced to 32nd Note Синхро по 1/32 ноти @@ -6654,30 +8558,37 @@ Remember to also save your project manually. You can choose to disable saving wh TimeDisplayWidget + click to change time units натисніть для зміни одиниць часу + MIN ХВ + SEC С + MSEC МС + BAR БАР + BEAT БІТ + TICK ТІК @@ -6685,34 +8596,43 @@ Remember to also save your project manually. You can choose to disable saving wh TimeLineWidget + Enable/disable auto-scrolling Увімк/вимк автопрокрутку + Enable/disable loop-points Увімк/вимк точки петлі + After stopping go back to begin Після зупинки переходити до початку + After stopping go back to position at which playing was started Після зупинки переходити до місця, з якого почалося відтворення + After stopping keep position Залишатися на місці зупинки + + Hint Підказка + Press <%1> to disable magnetic loop points. Натисніть <%1>, щоб прибрати прилипання точок циклу. + Hold <Shift> to move the begin loop point; Press <%1> to disable magnetic loop points. Зажміть <Shift> щоб змістити початок точок циклу; Натисніть <%1>, щоб прибрати прилипання точок циклу. @@ -6720,10 +8640,12 @@ Remember to also save your project manually. You can choose to disable saving wh Track + Mute Тиша + Solo Соло @@ -6731,38 +8653,63 @@ Remember to also save your project manually. You can choose to disable saving wh TrackContainer + Couldn't import file Не можу імпортувати файл + Couldn't find a filter for importing file %1. You should convert this file into a format supported by LMMS using another software. Не можу знайти фільтр для імпорту файла %1. Для підключення цього файлу перетворіть його в формат, підтримуваний LMMS. + Couldn't open file Не можу відкрити файл + 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! Не можу відкрити файл %1 для запису. Перевірте, чи володієте ви правами на запис в обраний файл і каталог що його містить і спробуйте знову! + Loading project... Завантаження проекту ... + + Cancel Скасувати + + Please wait... Зачекайте будь-ласка ... + + Loading cancelled + Завантаження скасовано + + + + Project loading was cancelled. + Завантаження проекту скасовано. + + + + Loading Track %1 (%2/Total %3) + Завантаження треку %1 (%2/з %3) + + + Importing MIDI-file... Імпортую файл MIDI... @@ -6770,6 +8717,7 @@ Please make sure you have read-permission to the file and the directory containi TrackContentObject + Mute Тиша @@ -6777,46 +8725,59 @@ Please make sure you have read-permission to the file and the directory containi TrackContentObjectView + Current position Позиція + + Hint Підказка + Press <%1> and drag to make a copy. Натисніть <%1> і перетягніть, щоб створити копію. + Current length Тривалість + Press <%1> for free resizing. Для вільної зміни розміру натисніть <%1>. + + %1:%2 (%3:%4 to %5:%6) %1:%2 (від %3:%4 до %5:%6) + Delete (middle mousebutton) Видалити (середня кнопка мишки) + Cut Вирізати + Copy Копіювати + Paste Вставити + Mute/unmute (<%1> + middle click) Заглушити/включити (<%1> + середня кнопка миші) @@ -6824,193 +8785,243 @@ 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. Затисніть <%1> і натискайте мишку під час руху, щоб почати нову перезбірку. + Actions for this track Дії для цієї доріжки + Mute Тиша + + Solo Соло + Mute this track Відключити доріжку + Clone this track Клонувати доріжку + Remove this track Видалити доріжку + Clear this track Очистити цю доріжку + FX %1: %2 ЕФ %1: %2 + + Assign to new FX Channel + Призначити до нового каналу ефекту + + + Turn all recording on Включити все на запис + Turn all recording off Вимкнути всі записи - - Assign to new FX Channel - Призначити до нового каналу ефекту - TripleOscillatorView + Use phase modulation for modulating oscillator 1 with oscillator 2 Модулювати фазу осциллятора 2 сигналом з 1 + Use amplitude modulation for modulating oscillator 1 with oscillator 2 Модулювати амплітуду осциллятора 2 сигналом з 1 + Mix output of oscillator 1 & 2 Змішати виходи 1 і 2 осцилляторів + Synchronize oscillator 1 with oscillator 2 Синхронізувати 1 осциллятор по 2 + Use frequency modulation for modulating oscillator 1 with oscillator 2 Модулювати частоту осциллятора 2 сигналом з 1 + Use phase modulation for modulating oscillator 2 with oscillator 3 Модулювати фазу осциллятора 3 сигналом з 2 + Use amplitude modulation for modulating oscillator 2 with oscillator 3 Модулювати амплітуду осциллятора 3 сигналом з 2 + Mix output of oscillator 2 & 3 Поєднати виходи осцилляторів 2 і 3 + Synchronize oscillator 2 with oscillator 3 Синхронізувати осциллятор 2 і 3 + Use frequency modulation for modulating oscillator 2 with oscillator 3 Модулювати частоту осциллятора 3 сигналом з 2 + Osc %1 volume: Гучність осциллятора %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. Ця ручка встановлює гучність осциллятора %1. Якщо 0, то осциллятор вимикається, інакше буде чутно настільки голосно, настільки тут встановлено. + Osc %1 panning: Баланс для осциллятора %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. Регулятор стереобалансу осциллятора %1. Величина -100 позначає, що 100% сигналу йде в лівий канал, а 100 - в правий. + Osc %1 coarse detuning: Грубе підстроювання осциллятора %1: + semitones півтон(а,ів) + 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. Ця ручка встановлює грубе підстроювання осцилятора %1. Ви можете пістроїти осцилятор на 24 півтони (2 октави) вгору і вниз. Це корисно для створення звуків з акорду. + Osc %1 fine detuning left: Точне підстроювання лівого каналу осциллятора %1: + + cents Відсотки + 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. Ця ручка встановлює точне підстроювання для лівого каналу осциллятора %1. Підстроювання задається в діапазоні від -100 сотих до +100 сотих. Це корисно для створення "насичених" звуків. + Osc %1 fine detuning right: Точна підстройка правого канала осциллятора %1: + 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. Ця ручка встановлює точне підстроювання для правого каналу осциллятора %1. Підстроювання задається в діапазоні від -100 сотих до +100 сотих. Це корисно для створення "насичених" звуків. + Osc %1 phase-offset: Зміщення фази осциллятора %1: + + degrees градуси + 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. Ця ручка встановлює початкову фазу осциллятора %1, т. б. точку, з якої осциллятор починає виробляти сигнал. Наприклад, якщо ви задали синусоїдальну форму сигналу і початкову фазу 180º, хвиля спочатку піде вниз, а не вгору. Те ж саме для сигналу прямокутної форми. + Osc %1 stereo phase-detuning: Підстроювання стерео фази осциллятора %1: + 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. Ця ручка встановлює фазове підстроювання осциллятора %1 між каналами, тобто різницю фаз між лівим і правим каналами. Це зручно для створення розширення стереоефектів. + Use a sine-wave for current oscillator. - Використовувати гармонійний (синусоїдальний) сигнал для цього осциллятора. + Генерувати гармонійний (синусоїдальний) сигнал. + Use a triangle-wave for current oscillator. - Використовувати трикутний сигнал для цього осциллятора. + Генерувати трикутний сигнал. + Use a saw-wave for current oscillator. - Використовувати зигзагоподібний сигнал для цього осциллятора. + Генерувати зигзагоподібний сигнал. + Use a square-wave for current oscillator. - Використовувати квадратний сигнал для цього осциллятора. + Генерувати квадрат. + Use a moog-like saw-wave for current oscillator. Використовувати муг-зигзаг для цього осциллятора. + Use an exponential wave for current oscillator. Використовувати експонентний сигнал для цього осциллятора. + Use white-noise for current oscillator. - Використовувати білий шум для цього осциллятора. + Генерувати білий шум. + Use a user-defined waveform for current oscillator. Задати форму сигналу. @@ -7018,105 +9029,131 @@ Please make sure you have read-permission to the file and the directory containi VersionedSaveDialog + Increment version number Збільшуючийся номер версії + Decrement version number Зменшуючийся номер версії + already exists. Do you want to replace it? - + вже існує. Замінити його? VestigeInstrumentView + Open other VST-plugin Відкрити інший VST плагін + 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. Відкрити інший модуль VST. Після натискання на кнопку з'явиться стандартний діалог вибору файлу, де ви зможете вибрати потрібний модуль. - Show/hide GUI - Показати / приховати інтерфейс - - - Click here to show or hide the graphical user interface (GUI) of your VST-plugin. - Приховує / показує графічний користувальницький інтерфейс (GUI) обраного модуля VST. - - - Turn off all notes - Вимкнути всі ноти - - - Open VST-plugin - Відкрити модуль VST - - - DLL-files (*.dll) - Бібліотеки DLL (*.dll) - - - EXE-files (*.exe) - Програми EXE (*.exe) - - - No VST-plugin loaded - Модуль VST не завантажений - - + Control VST-plugin from LMMS host - Управління VST плагіном через LMMS + Управління VST плагіном через LMMS хост + Click here, if you want to control VST-plugin from host. - Натисніть тут для контролю VST плагіна через хост. + Натисніть тут, для контролю VST плагіном через хост. + Open VST-plugin preset - Відкрити передустановку VST модуля + Відкрити передустановку VST плагіна + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. - Відкрити інший .fxp. fxb VST плагін передустановки. + Відкрити іншу .fxp . fxb передустановку VST. + Previous (-) Попередній <-> + + Click here, if you want to switch to another VST-plugin preset program. - Натисніть тут для перемикання на іншу передустановку програми VST плагіна. + Перемикання на іншу передустановку програми VST плагіна. + Save preset Зберегти передустановку + Click here, if you want to save current VST-plugin preset program. Зберегти поточну передустановку програми VST плагіна. + Next (+) Наступний <+> + Click here to select presets that are currently loaded in VST. - Вибір з уже завантажених в VST передустановок. + Вибір із уже завантажених в VST предустановок. + + Show/hide GUI + Показати / приховати інтерфейс + + + + Click here to show or hide the graphical user interface (GUI) of your VST-plugin. + Приховує / показує графічний користувальницький інтерфейс (GUI) обраного модуля VST. + + + + Turn off all notes + Вимкнути всі ноти + + + + Open VST-plugin + Відкрити модуль VST + + + + DLL-files (*.dll) + Бібліотеки DLL (*.dll) + + + + EXE-files (*.exe) + Програми EXE (*.exe) + + + + No VST-plugin loaded + Модуль VST не завантажений + + + Preset Передустановка + by від + - VST plugin control - Управління VST плагіном @@ -7124,10 +9161,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 Натисніть для включення @@ -7135,54 +9174,69 @@ Please make sure you have read-permission to the file and the directory containi VstEffectControlDialog + Show/hide Показати/Сховати + Control VST-plugin from LMMS host Управління VST плагіном через LMMS хост + Click here, if you want to control VST-plugin from host. Натисніть тут, для контролю VST плагіном через хост. + Open VST-plugin preset Відкрити передустановку VST плагіна + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. Відкрити іншу .fxp . fxb передустановку VST. + Previous (-) Попередній <-> + + Click here, if you want to switch to another VST-plugin preset program. Перемикання на іншу передустановку програми VST плагіна. + Next (+) Наступний <+> + Click here to select presets that are currently loaded in VST. Вибір із уже завантажених в VST предустановок. + Save preset Зберегти налаштування + Click here, if you want to save current VST-plugin preset program. Зберегти поточну передустановку програми VST плагіна. + + Effect by: Ефекти по: + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> @@ -7190,173 +9244,217 @@ Please make sure you have read-permission to the file and the directory containi VstPlugin - Loading plugin - Завантаження модуля + + + The VST plugin %1 could not be loaded. + VST плагін %1 не може бути завантажено. + Open Preset Відкрити предустановку + + Vst Plugin Preset (*.fxp *.fxb) - Передустановка VST плагіна (*.fxp *.fxb) + Передустановка VST плагіна (*.fxp, *.fxb) + : default : основні + " " + ' ' + Save Preset Зберегти предустановку + .fxp .fxp + .FXP .FXP + .FXB .FXB + .fxb .fxb - Please wait while loading VST plugin... - Будь ласка, зачекайте доки завантажується VST плагін ... + + Loading plugin + Завантаження модуля - The VST plugin %1 could not be loaded. - VST плагін %1 не може бути завантажено. + + Please wait while loading VST plugin... + Будь ласка, зачекайте доки завантажується VST плагін ... WatsynInstrument + Volume A1 Гучність A1 + Volume A2 Гучність A2 + Volume B1 Гучність B1 + Volume B2 Гучність B2 + Panning A1 Баланс A1 + Panning A2 Баланс A2 + Panning B1 Баланс B1 + Panning B2 Баланс B2 + Freq. multiplier A1 Множник частоти A1 + Freq. multiplier A2 Множник частоти A2 + Freq. multiplier B1 Множник частоти B1 + Freq. multiplier B2 Множник частоти B2 + Left detune A1 Ліве підстроювання A1 + Left detune A2 Ліве підстроювання A2 + Left detune B1 Ліве підстроювання B1 + Left detune B2 Ліве підстроювання B2 + Right detune A1 Праве підстроювання A1 + Right detune A2 Праве підстроювання A2 + Right detune B1 Праве підстроювання B1 + Right detune B2 Праве підстроювання B2 + A-B Mix A-B Мікс + A-B Mix envelope amount A-B Мікс кіл. обвідної + A-B Mix envelope attack A-B Мікс атаки обвідної + A-B Mix envelope hold A-B Мікс утримання обвідної + A-B Mix envelope decay A-B Мікс згасання обвідної + A1-B2 Crosstalk Перехресні перешкоди A1-B2 + A2-A1 modulation Модуляція A2-A1 + B2-B1 modulation Модуляція B2-B1 + Selected graph Обраний графік @@ -7364,213 +9462,291 @@ Please make sure you have read-permission to the file and the directory containi WatsynView - Select oscillator A1 - Виберіть генератор A1 - - - Select oscillator A2 - Виберіть генератор A2 - - - Select oscillator B1 - Виберіть генератор B1 - - - Select oscillator B2 - Виберіть генератор B2 - - - Mix output of A2 to A1 - Змішати виходи A2 до A1 - - - Modulate amplitude of A1 with output of A2 - Модулювати амплітуду А1 виходом з А2 - - - Ring-modulate A1 and A2 - Кільцева модуляція А1 і А2 - - - Modulate phase of A1 with output of A2 - Модулювати фазу А1 виходом з А2 - - - Mix output of B2 to B1 - Змішати виходи В2 до В1 - - - Modulate amplitude of B1 with output of B2 - Модулювати амплітуду В1 виходом з В2 - - - Ring-modulate B1 and B2 - Кільцева модуляція В1 і В2 - - - Modulate phase of B1 with output of B2 - Модулювати фазу В1 виходом з В2 - - - Draw your own waveform here by dragging your mouse on this graph. - Тут ви можете малювати власний сигнал. - - - Load waveform - Завантаження форми звуку - - - Click to load a waveform from a sample file - Натисніть для завантаження форми звуку з файлу із зразком - - - Phase left - Фаза зліва - - - Click to shift phase by -15 degrees - Натисніть, щоб змістити фазу на -15 градусів - - - Phase right - Фаза праворуч - - - Click to shift phase by +15 degrees - Натисніть, щоб змістити фазу на +15 градусів - - - Normalize - Нормалізувати - - - Click to normalize - Натисніть для нормалізації - - - Invert - Інвертувати - - - Click to invert - Натисніть щоб інвертувати - - - Smooth - Згладити - - - Click to smooth - Натисніть щоб згладити - - - Sine wave - Синусоїда - - - Click for sine wave - Згенерувати гармонійний (синусоїдальний) сигнал - - - Triangle wave - Трикутна хвиля - - - Click for triangle wave - Згенерувати трикутний сигнал - - - Click for saw wave - Згенерувати зигзагоподібний сигнал - - - Square wave - Квадратна хвиля - - - Click for square wave - Згенерувати квадратний сигнал - - + + + + Volume Гучність + + + + Panning Баланс + + + + Freq. multiplier Множник частоти + + + + Left detune Ліве підстроювання + + + + + + + + cents відсотків + + + + Right detune Праве підстроювання + A-B Mix A-B Мікс + Mix envelope amount Мікс кількості обвідної + Mix envelope attack A-B Мікс вступу обвідної + Mix envelope hold A-B Мікс утримання обвідної + Mix envelope decay A-B Мікс згасання обвідної + Crosstalk Перехід + + + Select oscillator A1 + Виберіть генератор A1 + + + + Select oscillator A2 + Виберіть генератор A2 + + + + Select oscillator B1 + Виберіть генератор B1 + + + + Select oscillator B2 + Виберіть генератор B2 + + + + Mix output of A2 to A1 + Змішати виходи A2 до A1 + + + + Modulate amplitude of A1 with output of A2 + Модулювати амплітуду А1 виходом з А2 + + + + Ring-modulate A1 and A2 + Кільцева модуляція А1 і А2 + + + + Modulate phase of A1 with output of A2 + Модулювати фазу А1 виходом з А2 + + + + Mix output of B2 to B1 + Змішати виходи В2 до В1 + + + + Modulate amplitude of B1 with output of B2 + Модулювати амплітуду В1 виходом з В2 + + + + Ring-modulate B1 and B2 + Кільцева модуляція В1 і В2 + + + + Modulate phase of B1 with output of B2 + Модулювати фазу В1 виходом з В2 + + + + + + + Draw your own waveform here by dragging your mouse on this graph. + Тут ви можете малювати власний сигнал. + + + + Load waveform + Завантаження форми звуку + + + + Click to load a waveform from a sample file + Натисніть для завантаження форми звуку з файлу із зразком + + + + Phase left + Фаза зліва + + + + Click to shift phase by -15 degrees + Натисніть, щоб змістити фазу на -15 градусів + + + + Phase right + Фаза праворуч + + + + Click to shift phase by +15 degrees + Натисніть, щоб змістити фазу на +15 градусів + + + + Normalize + Нормалізувати + + + + Click to normalize + Натисніть для нормалізації + + + + Invert + Інвертувати + + + + Click to invert + Натисніть щоб інвертувати + + + + Smooth + Згладити + + + + Click to smooth + Натисніть щоб згладити + + + + Sine wave + Синусоїда + + + + Click for sine wave + Згенерувати гармонійний (синусоїдальний) сигнал + + + + + Triangle wave + Трикутна хвиля + + + + Click for triangle wave + Згенерувати трикутний сигнал + + + + Click for saw wave + Згенерувати зигзагоподібний сигнал + + + + Square wave + Квадратна хвиля + + + + Click for square wave + Згенерувати квадратний сигнал + ZynAddSubFxInstrument + Portamento Портаменто + Filter Frequency Фільтр Частот + Filter Resonance Фільтр резонансу + Bandwidth Ширина смуги + FM Gain Підсил FM + Resonance Center Frequency Частоти центру резонансу + Resonance Bandwidth Ширина смуги резонансу + Forward MIDI Control Change Events Переслати зміну подій MIDI управління @@ -7578,121 +9754,150 @@ Please make sure you have read-permission to the file and the directory containi ZynAddSubFxView - Show GUI - Показати інтерфейс - - - Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. - Натисніть сюди щоб сховати чи показати графічний інтерфейс ZynAddSubFX. - - + Portamento: Портаменто: + PORT PORT + Filter Frequency: Фільтр частот: + FREQ FREQ + Filter Resonance: Фільтр резонансу: + RES RES + Bandwidth: Смуга пропускання: + BW BW + FM Gain: Підсилення частоти модуляції (FM): + FM GAIN FM GAIN + Resonance center frequency: Частота центру резонансу: + RES CF RES CF + Resonance bandwidth: Ширина смуги резонансу: + RES BW RES BW + Forward MIDI Control Changes Переслати зміну подій MiDi управління + + + Show GUI + Показати інтерфейс + + + + Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. + Натисніть сюди щоб сховати чи показати графічний інтерфейс ZynAddSubFX. + audioFileProcessor + Amplify Підсилення + Start of sample Початок запису + End of sample Кінець запису - Reverse sample - Перевернути запис - - - Stutter - Заїкання - - + Loopback point Точка повернення з повтору + + Reverse sample + Перевернути запис + + + Loop mode Режим повтору + + Stutter + Заїкання + + + Interpolation mode Режим Інтерполяції + None Нічого + Linear Лінійний + Sinc Синхронізований + Sample not found: %1 Запис не знайдено: %1 @@ -7700,6 +9905,7 @@ Please make sure you have read-permission to the file and the directory containi bitInvader + Samplelength Тривалість @@ -7707,165 +9913,205 @@ Please make sure you have read-permission to the file and the directory containi bitInvaderView + Sample Length Тривалість запису - Sine wave - Синусоїда - - - Triangle wave - Трикутник - - - Saw wave - Зигзаг - - - Square wave - Квадрат - - - White noise wave - Білий шум - - - User defined wave - Користувацька - - - Smooth - Згладити - - - Click here to smooth waveform. - Клацніть щоб згладити форму сигналу. - - - Interpolation - Інтерполяція - - - Normalize - Нормалізувати - - + Draw your own waveform here by dragging your mouse on this graph. Тут ви можете малювати власний сигнал. - Click for a sine-wave. - Згенерувати гармонійний (синусоїдальний) сигнал. + + Sine wave + Синусоїда + + Click for a sine-wave. + Генерувати гармонійний (синусоїдальний) сигнал. + + + + Triangle wave + Трикутник + + + Click here for a triangle-wave. Згенерувати трикутний сигнал. + + Saw wave + Зигзаг + + + Click here for a saw-wave. - Згенерувати зигзагоподібний сигнал. + Згенерувати зигзаг. + + Square wave + Квадрат + + + Click here for a square-wave. - Згенерувати квадратну хвилю. + Згенерувати квадратний сигнал. + + White noise wave + Білий шум + + + Click here for white-noise. Згенерувати білий шум. + + User defined wave + Користувацька + + + Click here for a user-defined shape. Задати форму сигналу вручну. + + + Smooth + Згладити + + + + Click here to smooth waveform. + Клацніть щоб згладити форму сигналу. + + + + Interpolation + Інтерполяція + + + + Normalize + Нормалізувати + dynProcControlDialog + INPUT ВХІД + Input gain: Вхідне підсилення: + OUTPUT ВИХІД + Output gain: Вихідне підсилення: + ATTACK ВСТУП + Peak attack time: Час пікової атаки: + RELEASE ЗМЕНШЕННЯ + Peak release time: Час відпуску піку: + Reset waveform Скидання сигналу + Click here to reset the wavegraph back to default Натисніть тут, щоб скинути граф хвилі назад за замовчуванням + Smooth waveform Згладжений сигнал + Click here to apply smoothing to wavegraph Натисніть тут, щоб застосувати згладжування графа хвилі + Increase wavegraph amplitude by 1dB Збільште амплітуди графа хвилі на 1дБ + Click here to increase wavegraph amplitude by 1dB Натисніть тут, щоб збільшити амплітуду графа хвилі на 1дБ + Decrease wavegraph amplitude by 1dB Зменшення амплітуди графа хвилі на 1дБ + Click here to decrease wavegraph amplitude by 1dB Натисніть тут, щоб зменшити амплітуду графа хвилі на 1дБ + 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 Обробляє кожен стерео канал незалежно @@ -7873,22 +10119,27 @@ Please make sure you have read-permission to the file and the directory containi dynProcControls + Input gain Вхідне підсилення + Output gain Вихідне підсилення + Attack time Час вступу + Release time Час зменшення + Stereo mode Стерео режим @@ -7896,10 +10147,12 @@ Please make sure you have read-permission to the file and the directory containi fxLineLcdSpinBox + Assign to: Призначити до: + New FX Channel Новий ефект каналу @@ -7907,6 +10160,7 @@ Please make sure you have read-permission to the file and the directory containi graphModel + Graph Графік @@ -7914,50 +10168,62 @@ Please make sure you have read-permission to the file and the directory containi kickerInstrument + Start frequency Початкова частота + End frequency Кінцева частота - Gain - Підсилення - - + Length Довжина + Distortion Start Початкове спотворення + Distortion End Кінцеве спотворення + + Gain + Підсилення + + + Envelope Slope Нахил обвідної + Noise Шум + Click Натисніть + Frequency Slope Частота нахилу + Start from note Почати з замітки + End to note Закінчити заміткою @@ -7965,42 +10231,52 @@ Please make sure you have read-permission to the file and the directory containi kickerInstrumentView + Start frequency: Початкова частота: + End frequency: Кінцева частота: - Gain: - Підсилення: - - + Frequency Slope: Частота нахилу: + + Gain: + Підсилення: + + + Envelope Length: Довжина обвідної: + Envelope Slope: Нахил обвідної: + Click: Натиснення: + Noise: Шум: + Distortion Start: Початкове спотворення: + Distortion End: Кінцеве спотворення: @@ -8008,26 +10284,37 @@ Please make sure you have read-permission to the file and the directory containi ladspaBrowserView + + Available Effects Доступні ефекти + + Unavailable Effects Недоступні ефекти + + Instruments Інструменти + + Analysis Tools Аналізатори + + Don't know Невідомі + 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. @@ -8056,6 +10343,7 @@ Double clicking any of the plugins will bring up information on the ports. + Type: Тип: @@ -8063,10 +10351,12 @@ Double clicking any of the plugins will bring up information on the ports. ladspaDescription + Plugins Модулі + Description Опис @@ -8074,66 +10364,83 @@ Double clicking any of the plugins will bring up information on the ports. ladspaPortDialog + Ports Порти + Name І'мя + Rate Частота вибірки + Direction Напрямок + Type Тип + Min < Default < Max Менше < Стандарт <Більше + Logarithmic Логарифмічний + SR Dependent Залежність від SR + Audio Аудіо + Control Управління + Input Ввід + Output Вивід + Toggled Увімкнено + Integer Ціле + Float Дробове + + Yes Так @@ -8141,46 +10448,57 @@ Double clicking any of the plugins will bring up information on the ports. lb302Synth + VCF Cutoff Frequency Частота зрізу VCF + VCF Resonance Посилення VCF + VCF Envelope Mod Модуляція обвідної VCF + VCF Envelope Decay Спад обвідної VCF + Distortion Спотворення + Waveform Форма хвилі + Slide Decay Зміщення згасання + Slide Зміщення + Accent Акцент + Dead Глухо + 24dB/oct Filter 24дБ/окт фільтр @@ -8188,122 +10506,153 @@ Double clicking any of the plugins will bring up information on the ports. lb302SynthView + Cutoff Freq: Частота зрізу: + Resonance: Резонанс: + Env Mod: Мод Обвідної: + Decay: Згасання: + 303-es-que, 24dB/octave, 3 pole filter 303-ій, 24дБ/октаву, 3-польний фільтр + Slide Decay: Зміщення згасання: + DIST: СПОТ: + Saw wave Зигзаг + Click here for a saw-wave. Згенерувати зигзаг. + Triangle wave Трикутна хвиля + Click here for a triangle-wave. Згенерувати трикутний сигнал. + Square wave Квадрат + Click here for a square-wave. Згенерувати квадратний сигнал. + Rounded square wave Хвиля округленого квадрату + Click here for a square-wave with a rounded end. Створити квадратну хвилю закруглену в кінці. + Moog wave Муг хвиля + Click here for a moog-like wave. Згенерувати хвилю схожу на муг. + Sine wave Синусоїда + Click for a sine-wave. Генерувати гармонійний (синусоїдальний) сигнал. + + White noise wave Білий шум + Click here for an exponential wave. Генерувати експонентний сигнал. + Click here for white-noise. Згенерувати білий шум. + 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. Натисніть тут для муг-зигзаг хвилі з обмеженою смугою. @@ -8311,118 +10660,147 @@ Double clicking any of the plugins will bring up information on the ports. malletsInstrument + Hardness Жорсткість + Position Положення + Vibrato Gain Посилення вібрато + Vibrato Freq Частота вібрато + Stick Mix Зведення рученят + Modulator Модулятор + Crossfade Перехід + LFO Speed Швидкість LFO + LFO Depth Глибина LFO + ADSR ADSR + Pressure Тиск + Motion Рух + Speed Швидкість + Bowed Нахил + Spread Розкид + Marimba Марімба + Vibraphone Віброфон + Agogo Дискотека + Wood1 Дерево1 + Reso Ресо + Wood2 Дерево2 + Beats Удари + Two Fixed Два фіксованих + Clump Важка хода + Tubular Bells Трубні дзвони + Uniform Bar Рівномірні смуги + Tuned Bar Підстроєні смуги + Glass Скло + Tibetan Bowl Тибетські кулі @@ -8430,149 +10808,186 @@ Double clicking any of the plugins will bring up information on the ports. malletsInstrumentView + Instrument Інструмент + Spread Розкид + Spread: Розкид: - Hardness - Жорсткість - - - Hardness: - Жорсткість: - - - Position - Положення - - - Position: - Положення: - - - Vib Gain - Підс. вібрато - - - Vib Gain: - Підс. вібрато: - - - Vib Freq - Част. віб - - - Vib Freq: - Вібрато: - - - Stick Mix - Зведення рученят - - - Stick Mix: - Зведення рученят: - - - Modulator - Модулятор - - - Modulator: - Модулятор: - - - Crossfade - Перехід - - - Crossfade: - Перехід: - - - LFO Speed - Швидкість LFO - - - LFO Speed: - Швидкість LFO: - - - LFO Depth - Глибина LFO - - - LFO Depth: - Глибина LFO: - - - ADSR - ADSR - - - ADSR: - ADSR: - - - Pressure - Тиск - - - Pressure: - Тиск: - - - Speed - Швидкість - - - Speed: - Швидкість: - - + Missing files Відсутні файли + Your Stk-installation seems to be incomplete. Please make sure the full Stk-package is installed! Схоже, що встановлені не всі пакети Stk. Вам слід це перевірити! + + + Hardness + Жорсткість + + + + Hardness: + Жорсткість: + + + + Position + Положення + + + + Position: + Положення: + + + + Vib Gain + Підс. вібрато + + + + Vib Gain: + Підс. вібрато: + + + + Vib Freq + Част. віб + + + + Vib Freq: + Вібрато: + + + + Stick Mix + Зведення рученят + + + + Stick Mix: + Зведення рученят: + + + + Modulator + Модулятор + + + + Modulator: + Модулятор: + + + + Crossfade + Перехід + + + + Crossfade: + Перехід: + + + + LFO Speed + Швидкість LFO + + + + LFO Speed: + Швидкість LFO: + + + + LFO Depth + Глибина LFO + + + + LFO Depth: + Глибина LFO: + + + + ADSR + ADSR + + + + ADSR: + ADSR: + + + + Pressure + Тиск + + + + Pressure: + Тиск: + + + + Speed + Швидкість + + + + Speed: + Швидкість: + manageVSTEffectView + - VST parameter control Управление VST параметрами + VST Sync VST синхронізація + Click here if you want to synchronize all parameters with VST plugin. Натисніть тут для синхронізації всіх параметрів VST плагіна. + + Automated Автоматизовано + Click here if you want to display automated parameters only. Натисніть тут, якщо хочете бачити тільки автоматизовані параметри. + Close Закрити + Close VST effect knob-controller window. Закрити вікно управління регуляторами VST плагіна. @@ -8580,30 +10995,39 @@ Double clicking any of the plugins will bring up information on the ports. manageVestigeInstrumentView + + - VST plugin control Управління VST плагіном + VST Sync VST синхронізація + Click here if you want to synchronize all parameters with VST plugin. Натисніть тут для синхронізації всіх параметрів VST плагіна. + + Automated Автоматизовано + Click here if you want to display automated parameters only. Натисніть тут, якщо хочете бачити тільки автоматизовані параметри. + Close Закрити + Close VST plugin knob-controller window. Закрити вікно управління регуляторами VST плагіна. @@ -8611,118 +11035,147 @@ Double clicking any of the plugins will bring up information on the ports. opl2instrument + Patch Патч + Op 1 Attack ОП 1 Вступ + Op 1 Decay ОП 1 Спад + Op 1 Sustain ОП 1 Видержка + Op 1 Release ОП 1 Зменшення + Op 1 Level ОП 1 Рівень + Op 1 Level Scaling ОП 1 Рівень збільшення + Op 1 Frequency Multiple ОП 1 Множник частот + Op 1 Feedback ОП 1 Повернення + Op 1 Key Scaling Rate ОП 1 Ключова ставка множника + Op 1 Percussive Envelope ОП 1 Ударна обвідна + Op 1 Tremolo ОП 1 Тремоло + Op 1 Vibrato Оп 1 Вібрато + Op 1 Waveform ОП 1 Хвиля + Op 2 Attack ОП 2 Вступ + Op 2 Decay ОП 2 Спад + Op 2 Sustain ОП 2 Видержка + Op 2 Release ОП 2 Зменшення + Op 2 Level ОП 2 Рівень + Op 2 Level Scaling ОП 2 Рівень збільшення + Op 2 Frequency Multiple ОП 2 Множник частот + Op 2 Key Scaling Rate ОП 2 Ключова ставка множника + Op 2 Percussive Envelope ОП 2 Ударна обвідна + Op 2 Tremolo ОП 2 Тремоло + Op 2 Vibrato Оп 2 Вібрато + Op 2 Waveform ОП 2 Хвиля + FM FM + Vibrato Depth Глибина вібрато + Tremolo Depth Глибина тремоло @@ -8730,18 +11183,26 @@ Double clicking any of the plugins will bring up information on the ports. opl2instrumentView + + Attack Вступ + + Decay Згасання + + Release Зменшення + + Frequency multiplier Множник частоти @@ -8749,10 +11210,12 @@ Double clicking any of the plugins will bring up information on the ports. organicInstrument + Distortion Спотворення + Volume Гучність @@ -8760,50 +11223,63 @@ Double clicking any of the plugins will bring up information on the ports. organicInstrumentView + Distortion: Спотворення: - Volume: - Гучність: - - - Randomise - Випадково - - - Osc %1 waveform: - Форма сигналу осциллятора %1: - - - Osc %1 volume: - Гучність осциллятора %1: - - - Osc %1 panning: - Баланс для осциллятора %1: - - - cents - соті - - + The distortion knob adds distortion to the output of the instrument. Спотворення додає спотворення до виходу інструменту. + + 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: + Форма сигналу осциллятора %1: + + + + Osc %1 volume: + Гучність осциллятора %1: + + + + Osc %1 panning: + Баланс для осциллятора %1: + + + Osc %1 stereo detuning Осц %1 стерео расстройка + + cents + соті + + + Osc %1 harmonic: Осц %1 гармоніка: @@ -8811,265 +11287,351 @@ Double clicking any of the plugins will bring up information on the ports. papuInstrument + Sweep time Час поширення + Sweep direction Напрям поширення + Sweep RtShift amount - Кіль-ть поширення зсуву вправо + Кіл-ть розгортки зсуву вправо + + Wave Pattern Duty Робоча форма хвилі + Channel 1 volume Гучність першого каналу + + + Volume sweep direction Обсяг напрямку поширення + + + Length of each step in sweep - Довжина кожного такту в поширенні + Довжина кожного кроку в розгортці + Channel 2 volume Гучність другого каналу + Channel 3 volume Гучність третього каналу + Channel 4 volume Гучність четвертого каналу + + Shift Register width + Зміщення ширини регістра + + + Right Output level Вихідний рівень праворуч + Left Output level Вихідний рівень зліва + Channel 1 to SO2 (Left) Від першого каналу до SO2 (лівий канал) + Channel 2 to SO2 (Left) Від другого каналу до SO2 (лівий канал) + Channel 3 to SO2 (Left) Від третього каналу до SO2 (лівий канал) + Channel 4 to SO2 (Left) Від четвертого каналу до SO2 (лівий канал) + Channel 1 to SO1 (Right) Від першого каналу до SO1 (правий канал) + Channel 2 to SO1 (Right) Від другого каналу до SO1 (правий канал) + Channel 3 to SO1 (Right) Від третього каналу до SO1 (правий канал) + Channel 4 to SO1 (Right) Від четвертого каналу до SO1 (правий канал) + Treble Дискант + Bass Бас - - Shift Register width - Зміщення ширини регістра - papuInstrumentView + Sweep Time: Час розгортки: + Sweep Time Час розгортки - Sweep RtShift amount: - Кіл-ть розгортки зміщення вправо: - - - Sweep RtShift amount - Кіл-ть розгортки зсуву вправо - - - Wave pattern duty: - Робоча форма хвилі: - - - Wave Pattern Duty - Робоча форма хвилі - - - Square Channel 1 Volume: - Гучність квадратного каналу 1: - - - Length of each step in sweep: - Довжина кожного кроку в розгортці: - - - Length of each step in sweep - Довжина кожного кроку в розгортці - - - Wave pattern duty - Робоча форма хвилі - - - Square Channel 2 Volume: - Гучність квадратного каналу 2: - - - Square Channel 2 Volume - Гучність квадратного каналу 2 - - - Wave Channel Volume: - Гучність хвильового каналу: - - - Wave Channel Volume - Гучність хвильового каналу - - - Noise Channel Volume: - Гучність каналу шуму: - - - Noise Channel Volume - Гучність каналу шуму - - - SO1 Volume (Right): - Гучність SO1 (Правий): - - - SO1 Volume (Right) - Гучність SO1 (Правий) - - - SO2 Volume (Left): - Гучність SO2 (Лівий): - - - SO2 Volume (Left) - Гучність SO2 (Лівий) - - - Treble: - Дискант: - - - Treble - Дискант - - - Bass: - Бас: - - - Bass - Бас - - - Sweep Direction - Напрямок розгортки - - - Volume Sweep Direction - Гучність напрямки розгортки - - - Shift Register Width - Зміщення ширини регістра - - - Channel1 to SO1 (Right) - Канал1 в SO1 (Правий) - - - Channel2 to SO1 (Right) - Канал2 в SO1 (Правий) - - - Channel3 to SO1 (Right) - Канал3 в SO1 (Правий) - - - Channel4 to SO1 (Right) - Канал4 в SO1 (Правий) - - - Channel1 to SO2 (Left) - Канал1 в SO2 (Лівий) - - - Channel2 to SO2 (Left) - Канал2 в SO2 (Лівий) - - - Channel3 to SO2 (Left) - Канал3 в SO2 (Лівий) - - - Channel4 to SO2 (Left) - Канал4 в SO2 (Лівий) - - - Wave Pattern - Малюнок хвилі - - + 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: + Гучність квадратного каналу 1: + + + Square Channel 1 Volume Гучність квадратного каналу 1 + + + + Length of each step in sweep: + Довжина кожного кроку в розгортці: + + + + + + Length of each step in sweep + Довжина кожного кроку в розгортці + + + + + The delay between step change Затримка між змінами кроку + + Wave pattern duty + Робоча форма хвилі + + + + Square Channel 2 Volume: + Гучність квадратного каналу 2: + + + + + Square Channel 2 Volume + Гучність квадратного каналу 2 + + + + Wave Channel Volume: + Гучність хвильового каналу: + + + + + Wave Channel Volume + Гучність хвильового каналу + + + + Noise Channel Volume: + Гучність каналу шуму: + + + + + Noise Channel Volume + Гучність каналу шуму + + + + SO1 Volume (Right): + Гучність SO1 (Правий): + + + + SO1 Volume (Right) + Гучність SO1 (Правий) + + + + SO2 Volume (Left): + Гучність SO2 (Лівий): + + + + SO2 Volume (Left) + Гучність SO2 (Лівий) + + + + Treble: + Дискант: + + + + Treble + Дискант + + + + Bass: + Бас: + + + + Bass + Бас + + + + Sweep Direction + Напрямок розгортки + + + + + + + + Volume Sweep Direction + Гучність напрямки розгортки + + + + Shift Register Width + Зміщення ширини регістра + + + + Channel1 to SO1 (Right) + Канал1 в SO1 (Правий) + + + + Channel2 to SO1 (Right) + Канал2 в SO1 (Правий) + + + + Channel3 to SO1 (Right) + Канал3 в SO1 (Правий) + + + + Channel4 to SO1 (Right) + Канал4 в SO1 (Правий) + + + + Channel1 to SO2 (Left) + Канал1 в SO2 (Лівий) + + + + Channel2 to SO2 (Left) + Канал2 в SO2 (Лівий) + + + + Channel3 to SO2 (Left) + Канал3 в SO2 (Лівий) + + + + Channel4 to SO2 (Left) + Канал4 в SO2 (Лівий) + + + + Wave Pattern + Малюнок хвилі + + + Draw the wave here Малювати хвилю тут @@ -9077,34 +11639,42 @@ Double clicking any of the plugins will bring up information on the ports. patchesDialog + Qsynth: Channel Preset Q-Синтезатор: Канал передустановлено + Bank selector Селектор банку + Bank Банк + Program selector Селектор програм + Patch Патч + Name І'мя + OK ОК + Cancel Скасувати @@ -9112,239 +11682,302 @@ Double clicking any of the plugins will bring up information on the ports. pluginBrowser + no description опис відсутній - Incomplete monophonic imitation tb303 - Незавершена монофонічна імітація tb303 + + A native amplifier plugin + Рідний плагін підсилення - Plugin for freely manipulating stereo output - Модуль для довільного управління стереовиходом + + Simple sampler with various settings for using samples (e.g. drums) in an instrument-track + Простий семплер з різними налаштуваннями для використання записів (наприклад, ударні) в інструментальному трекі - Plugin for controlling knobs with sound peaks - Модуль для встановлення значень регуляторів на піках гучності + + Boost your bass the fast and simple way + Накачай свій бас швидко і просто - Plugin for enhancing stereo separation of a stereo input file - Модуль, що підсилює різницю між каналами стереозапису + + Customizable wavetable synthesizer + Налаштовуваний синтезатор звукозаписів (wavetable) + + An oversampling bitcrusher + Перевибірка малого дробдення + + + + Carla Patchbay Instrument + Carla Комутаційний інструмент + + + + Carla Rack Instrument + Carla підставочний інструмент + + + + A 4-band Crossover Equalizer + 4-смуговий еквалайзер Кросовер + + + + A native delay plugin + Рідний плагін затримки + + + + A Dual filter plugin + Плагін подвійного фільтру + + + + plugin for processing dynamics in a flexible way + плагін для обробки динаміки гнучким методом + + + + A native eq plugin + Рідний eq плагін + + + + A native flanger plugin + Рідний фланжер плагін + + + + Player for GIG files + Програвач GIG файлів + + + + Filter for importing Hydrogen files into LMMS + Фільтр для імпорту Hydrogen файлів в LMMS + + + + Versatile drum synthesizer + Універсальний барабанний синтезатор + + + List installed LADSPA plugins Показати встановлені модулі LADSPA - GUS-compatible patch instrument - Патч-інструмент, сумісний з GUS - - - Additive Synthesizer for organ-like sounds - Синтезатор звуків нашталт органу - - - Tuneful things to bang on - Мелодійні ударні - - - VST-host for using VST(i)-plugins within LMMS - VST - хост для підтримки модулів VST(i) в LMMS - - - Vibrating string modeler - Емуляція вібруючих струн - - + plugin for using arbitrary LADSPA-effects inside LMMS. Модуль, що дозволяє використовувати в LMMS будь які ефекти LADSPA. + + Incomplete monophonic imitation tb303 + Незавершена монофонічна імітація tb303 + + + + Filter for exporting MIDI-files from LMMS + Фільтри для експорту MIDI-файлів з LMMS + + + Filter for importing MIDI-files into LMMS Фільтр для включення файлу MIDI в проект ЛММС + + Monstrous 3-oscillator synth with modulation matrix + Монстро 3-осцилляторний синт з матрицею модуляції + + + + A multitap echo delay plugin + Плагін багаторазової послідовної затримки відлуння + + + + A NES-like synthesizer + NES-подібний синтезатор + + + + 2-operator FM Synth + 2-режимний синт модуляції частот (FM synth) + + + + Additive Synthesizer for organ-like sounds + Синтезатор звуків нашталт органу + + + + Emulation of GameBoy (TM) APU + Емуляція GameBoy (ТМ) + + + + GUS-compatible patch instrument + Патч-інструмент, сумісний з GUS + + + + Plugin for controlling knobs with sound peaks + Модуль для встановлення значень регуляторів на піках гучності + + + + Reverb algorithm by Sean Costello + Алгоритм реверберації Шона Костелло + + + + Player for SoundFont files + Програвач файлів SoundFont + + + + LMMS port of sfxr + LMMS порт SFXR + + + Emulation of the MOS6581 and MOS8580 SID. This chip was used in the Commodore 64 computer. Емуляція MOS6581 і MOS8580. Використовувалося на комп'ютері Commodore 64. - Player for SoundFont files - Програвач файлів SoundFont - - - Emulation of GameBoy (TM) APU - Емуляція GameBoy (ТМ) - - - Customizable wavetable synthesizer - Налаштовуваний синтезатор звукозаписів (wavetable) - - - Embedded ZynAddSubFX - Вбудований ZynAddSubFX - - - 2-operator FM Synth - 2-режимний синт модуляції частот (FM synth) - - - Filter for importing Hydrogen files into LMMS - Фільтр для імпорту Hydrogen файлів в LMMS - - - LMMS port of sfxr - LMMS порт SFXR - - - Monstrous 3-oscillator synth with modulation matrix - Монстро 3-осцилляторний синт з матрицею модуляції - - - Three powerful oscillators you can modulate in several ways - Три потужних генераторів можна модулювати декількома способами - - - A native amplifier plugin - Рідний плагін підсилення - - - Carla Rack Instrument - Carla підставочний інструмент - - - 4-oscillator modulatable wavetable synth - 4-генераторний модулюючий синтезатор звукозаписів - - - plugin for waveshaping - плагін формування сигналу - - - Boost your bass the fast and simple way - Накачай свій бас швидко і просто - - - Versatile drum synthesizer - Універсальний барабанний синтезатор - - - Simple sampler with various settings for using samples (e.g. drums) in an instrument-track - Простий семплер з різними налаштуваннями для використання записів (наприклад, ударні) в інструментальному трекі - - - plugin for processing dynamics in a flexible way - плагін для обробки динаміки гнучким методом - - - Carla Patchbay Instrument - Carla Комутаційний інструмент - - - plugin for using arbitrary VST effects inside LMMS. - плагін для використання довільних VST ефектів всередині LMMS. - - + Graphical spectrum analyzer plugin Плагін графічного аналізу спектру - A NES-like synthesizer - NES-подібний синтезатор + + Plugin for enhancing stereo separation of a stereo input file + Модуль, що підсилює різницю між каналами стереозапису - A native delay plugin - Рідний плагін затримки + + Plugin for freely manipulating stereo output + Модуль для довільного управління стереовиходом - Player for GIG files - Програвач GIG файлів + + Tuneful things to bang on + Мелодійні ударні - A multitap echo delay plugin - Плагін багаторазової послідовної затримки відлуння + + Three powerful oscillators you can modulate in several ways + Три потужних генераторів можна модулювати декількома способами - A native flanger plugin - Рідний фланжер плагін + + VST-host for using VST(i)-plugins within LMMS + VST - хост для підтримки модулів VST(i) в LMMS - An oversampling bitcrusher - Перевибірка малого дробдення + + Vibrating string modeler + Емуляція вібруючих струн - A native eq plugin - Рідний eq плагін + + plugin for using arbitrary VST effects inside LMMS. + плагін для використання довільних VST ефектів всередині LMMS. - A 4-band Crossover Equalizer - 4-смуговий еквалайзер Кросовер + + 4-oscillator modulatable wavetable synth + 4-генераторний модулюючий синтезатор звукозаписів - A Dual filter plugin - Плагін подвійного фільтру + + plugin for waveshaping + плагін формування сигналу - Filter for exporting MIDI-files from LMMS - Фільтри для експорту MIDI-файлів з LMMS + + Embedded ZynAddSubFX + Вбудований ZynAddSubFX sf2Instrument + Bank Банк + Patch Патч + 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 не вдається завантажити. @@ -9352,74 +11985,92 @@ This chip was used in the Commodore 64 computer. sf2InstrumentView + Open other SoundFont file Відкрити інший файл SoundFront + Click here to open another SF2 file Натисніть тут щоб відкрити інший файл SF2 + 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 Відкрити файл SoundFront + SoundFont2 Files (*.sf2) Файли SoundFont2 (*.sf2) @@ -9427,6 +12078,7 @@ This chip was used in the Commodore 64 computer. sfxrInstrument + Wave Form Форма хвилі @@ -9434,26 +12086,32 @@ This chip was used in the Commodore 64 computer. sidInstrument + Cutoff Зріз + Resonance Підсилення + Filter type Тип фільтру + Voice 3 off Голос 3 відкл + Volume Гучність + Chip model Модель чіпа @@ -9461,134 +12119,172 @@ This chip was used in the Commodore 64 computer. sidInstrumentView + Volume: Гучність: + Resonance: Підсилення: + + Cutoff frequency: Частота зрізу: + High-Pass filter Вис.ЧФ + Band-Pass filter Серед.ЧФ + Low-Pass filter Низ.ЧФ + Voice3 Off Голос 3 відкл + MOS6581 SID MOS6581 SID + MOS8580 SID MOS8580 SID + + Attack: Вступ: + Attack rate determines how rapidly the output of Voice %1 rises from zero to peak amplitude. Тривалість вступу визначає, наскільки швидко гучність %1-го голосу зростає від нуля до максимального значення. + + Decay: Згасання: + Decay rate determines how rapidly the output falls from the peak amplitude to the selected Sustain level. Тривалість спаду визначає, наскільки швидко гучність падає від максимуму до залишкового рівня. + Sustain: Витримка: + Output of Voice %1 will remain at the selected Sustain amplitude as long as the note is held. Гучність %1-го голосу залишатиметься на рівні амплітуди витримки, поки триває нота. + + Release: Зменшення: + The output of of Voice %1 will fall from Sustain amplitude to zero amplitude at the selected Release rate. Гучність %1-го голосу буде падати від залишкового рівня до нуля з вказаною тут швидкістю. + + 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. Тривалість імпульсу дозволяє м'яко регулювати проходження імпульсу без помітних збоїв. Імпульсна хвиля повинна бути обрана на осцилляторі %1, щоб отримати звучання. + Coarse: Грубість: + The Coarse detuning allows to detune Voice %1 one octave up or down. Грубі налаштування дозволяють підлаштувати Голос %1 на одну октаву вгору або вниз. + Pulse Wave Пульсуюча хвиля + Triangle Wave Трикутник + SawTooth Зигзаг + Noise Шум + Sync Синхро + Sync synchronizes the fundamental frequency of Oscillator %1 with the fundamental frequency of Oscillator %2 producing "Hard Sync" effects. Синхро синхронізує фундаментальну частоту осцилляторів %1 фундаментальною частотою осциллятора %2, створюючи ефект "Залізної синхронізації". + Ring-Mod Круговий режим + Ring-mod replaces the Triangle Waveform output of Oscillator %1 with a "Ring Modulated" combination of Oscillators %1 and %2. Круговий режим замінює трикутні хвилі на виході осциллятора %1 "Круговою модуляцією" комбінацією осцилляторів %1 і %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. Якщо цей прапорець встановлено, то %1-й голос буде проходити через фільтр. Інакше голос № %1 буде подаватися прямо на вихід. + Test Тест + Test, when set, resets and locks Oscillator %1 at zero until Test is turned off. Якщо «прапорець» встановлено, то %1-й осциллятор видає нульовий сигнал (поки прапорець не зніметься). @@ -9596,10 +12292,12 @@ This chip was used in the Commodore 64 computer. stereoEnhancerControlDialog + WIDE ШИРШЕ + Width: Ширина: @@ -9607,6 +12305,7 @@ This chip was used in the Commodore 64 computer. stereoEnhancerControls + Width Ширина @@ -9614,18 +12313,22 @@ This chip was used in the Commodore 64 computer. stereoMatrixControlDialog + Left to Left Vol: Від лівого на лівий: + Left to Right Vol: Від лівого на правий: + Right to Left Vol: Від правого на лівий: + Right to Right Vol: Від правого на правий: @@ -9633,18 +12336,22 @@ This chip was used in the Commodore 64 computer. stereoMatrixControls + Left to Left Від лівого на лівий + Left to Right Від лівого на правий + Right to Left Від правого на лівий + Right to Right Від правого на правий @@ -9652,10 +12359,12 @@ This chip was used in the Commodore 64 computer. vestigeInstrument + Loading plugin Завантаження модуля + Please wait while loading VST-plugin... Будь ласка зачекайте поки завантажеться модуль VST... @@ -9663,42 +12372,52 @@ This chip was used in the Commodore 64 computer. vibed + String %1 volume Гучність %1-й струни + String %1 stiffness Жорсткість %1-й струни + Pick %1 position Лад %1 + Pickup %1 position Положення %1-го звукознімача + Pan %1 Бал %1 + Detune %1 Підстроювання %1 + Fuzziness %1 Нечіткість %1 + Length %1 Довжина %1 + Impulse %1 Імпульс %1 + Octave %1 Октава %1 @@ -9706,90 +12425,112 @@ This chip was used in the Commodore 64 computer. vibedView + Volume: Гучність: + The 'V' knob sets the volume of the selected string. Регулятор 'V' встановлює гучність поточної струни. + 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. Регулятор 'S' встановлює жорсткість поточної струни. Цей параметр відповідає за тривалість звучання струни (чим більше значення жорсткості, тим довше дзвенить струна). + Pick position: Ударна позиція: + 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. Регулятор 'P' встановлює місце струни, де вона буде "притиснута". Чим нижче значення, тим ближче це місце буде до кобилки. + Pickup position: Положення звукознімача: + 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. Регулятор 'PU' встановлює місце струни, звідки буде зніматися звук. Чим нижче значення, тим ближче це місце буде до мосту. + Pan: Бал: + The Pan knob determines the location of the selected string in the stereo field. Ця ручка встановлює стереобаланс для поточної струни. + 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: Нечіткість: + 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: Довжина: + 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. Перемикач "Imp" встановлює режим роботи струни: якщо він включений, то зазначена форма сигналу інтерпретується як початковий імпульс, інакше - як початкова форма струни. + Octave Октава + 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. Перемикач октав дозволяє вказати гармоніку основної частоти, на якій буде звучати струна. Наприклад, "-2" означає, що струна буде звучати двома октавами нижче основної частоти, "F" змусить струну дзвеніти на основній частоті інструменту, а "6" - на частоті, на шість октав більш високій, ніж основна. + Impulse Editor Редактор сигналу + 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. @@ -9807,6 +12548,7 @@ The 'N' button will normalize the waveform. Кнопка 'N' нормалізує рівень. + 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. @@ -9837,129 +12579,160 @@ The LED in the lower right corner of the waveform editor determines whether the Індикатор-перемикач зліва внизу визначає, чи включена поточна струна. + Enable waveform Включити сигнал + Click here to enable/disable waveform. Натисніть, щоб увімкнути/вимкнути сигнал. + String Струна + 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. Перемикач струн дозволяє вибрати струну, чиї властивості редагуються. Інструмент Vibed містить до дев'яти незалежно звучних струн, індикатор в лівому нижньому куті показує, активна чи поточна струна (тобто чи буде вона чутна). + Sine wave Синусоїда - Triangle wave - Трикутник - - - Saw wave - Зигзаг - - - Square wave - Квадратна хвиля - - - White noise wave - Білий шум - - - User defined wave - Користувацька - - - Smooth - Згладити - - - Click here to smooth waveform. - Клацніть щоб згладити форму сигналу. - - - Normalize - Нормалізувати - - - Click here to normalize waveform. - Натисніть, щоб нормалізувати сигнал. - - + Use a sine-wave for current oscillator. Генерувати гармонійний (синусоїдальний) сигнал. + + Triangle wave + Трикутник + + + Use a triangle-wave for current oscillator. Генерувати трикутний сигнал. + + Saw wave + Зигзаг + + + Use a saw-wave for current oscillator. Генерувати зигзагоподібний сигнал. + + Square wave + Квадратна хвиля + + + Use a square-wave for current oscillator. Генерувати квадрат. + + White noise wave + Білий шум + + + Use white-noise for current oscillator. Генерувати білий шум. + + User defined wave + Користувацька + + + Use a user-defined waveform for current oscillator. Задати форму сигналу. + + + Smooth + Згладити + + + + Click here to smooth waveform. + Клацніть щоб згладити форму сигналу. + + + + Normalize + Нормалізувати + + + + Click here to normalize waveform. + Натисніть, щоб нормалізувати сигнал. + voiceObject + Voice %1 pulse width Голос %1 довжина сигналу + Voice %1 attack Вступ %1-го голосу + Voice %1 decay Згасання %1-го голосу + Voice %1 sustain Витримка для %1-го голосу + Voice %1 release Зменшення %1-го голосу + Voice %1 coarse detuning Підналаштування %1-голосу (грубо) + Voice %1 wave shape Форма сигналу для %1-го голосу + Voice %1 sync Синхронізація %1-го голосу + Voice %1 ring modulate Голос %1 кільцевий модулятор + Voice %1 filtered Фільтрований %1-й голос + Voice %1 test Голос %1 тест @@ -9967,58 +12740,72 @@ The LED in the lower right corner of the waveform editor determines whether the waveShaperControlDialog + INPUT ВХІД + Input gain: Вхідне підсилення: + OUTPUT ВИХІД + Output gain: Вихідне підсилення: + Reset waveform Скидання сигналу + Click here to reset the wavegraph back to default Натисніть тут, щоб скинути граф хвилі назад за замовчуванням + Smooth waveform Згладжений сигнал + Click here to apply smoothing to wavegraph Натисніть тут, щоб застосувати згладжування графа хвилі + Increase graph amplitude by 1dB Збільште амплітуди графа хвилі на 1дБ + Click here to increase wavegraph amplitude by 1dB Натисніть тут, щоб збільшити амплітуду графа хвилі на 1дБ + Decrease graph amplitude by 1dB Зменшення амплітуди графа хвилі на 1дБ + Click here to decrease wavegraph amplitude by 1dB Натисніть тут, щоб зменшити амплітуду графа хвилі на 1дБ + Clip input Зрізати вхідний сигнал + Clip input signal to 0dB Зрізати вхідний сигнал до 0дБ @@ -10026,10 +12813,12 @@ The LED in the lower right corner of the waveform editor determines whether the waveShaperControls + Input gain Вхідне підсилення + Output gain Вихідне підсилення diff --git a/data/locale/zh_TW.ts b/data/locale/zh_TW.ts index 54b9a3953..6d457bd1e 100644 --- a/data/locale/zh_TW.ts +++ b/data/locale/zh_TW.ts @@ -2,30 +2,62 @@ AboutDialog + About LMMS - 關於LMMS + 關於 LMMS + + LMMS + LMMS + + + Version %1 (%2/%3, Qt %4, %5) 版本 %1 (%2/%3, Qt %4, %5) + About 關於 + LMMS - easy music production for everyone LMMS - 人人都是作曲家 + + Copyright © %1 + 版權所有 © %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 作者 + + Involved + 參與者 + + + + Contributors ordered by number of commits: + 貢獻者名單(以提交次數排序): + + + Translation 翻譯 + 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! @@ -42,61 +74,50 @@ BrLi <brli at chakraos.org> 若你有興趣提高翻譯品質,請聯絡維護團隊 (https://github.com/AOSC-Dev/translations)、之前的譯者或本項目維護者! + License 授權協議 - - LMMS - LMMS - - - Involved - 參與者 - - - Contributors ordered by number of commits: - 貢獻者名單(以提交次數排序): - - - Copyright © %1 - 版權所有 © %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> - - AmplifierControlDialog + VOL VOL + Volume: 音量: + PAN PAN + Panning: 聲相: + LEFT + Left gain: 左增益: + RIGHT + Right gain: 右增益: @@ -104,18 +125,22 @@ BrLi <brli at chakraos.org> AmplifierControls + Volume 音量 + Panning 聲相 + Left gain 左增益 + Right gain 右增益 @@ -123,10 +148,12 @@ BrLi <brli at chakraos.org> AudioAlsaSetupWidget + DEVICE 裝置 + CHANNELS 聲道數 @@ -134,78 +161,98 @@ BrLi <brli at chakraos.org> AudioFileProcessorView + Open other sample 開啟其他取樣 + 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. 如果想打開另一個音訊檔,請點擊這裡。接著會出現檔案選擇視窗。諸如循環模式 (looping-mode),起始/結束點,放大率 (amplify-value) 之類的值不會被重置。因此聽起來會和取樣來源有差異。 + Reverse sample 反轉取樣 + If you enable this button, the whole sample is reversed. This is useful for cool effects, e.g. a reversed crash. 如果點擊此按鈕,整個取樣將會被反轉。能用於製作很酷的效果,例如 reversed crash. - Amplify: - 放大: - - - 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!) - 此旋鈕用於調整放大比率。當設爲100% 時採樣不會變化。除此之外,不是放大就是減弱(原始的採樣文件不會被改變) - - - Startpoint: - 起始點: - - - Endpoint: - 終點: - - - Continue sample playback across notes - 跨音符繼續播放採樣 - - - 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) - - - + Disable loop 停用循環 + This button disables looping. The sample plays only once from start to end. 點擊此按鈕可以禁止循環播放。取樣檔案將從頭到尾播放一次。 + + Enable loop 啟用循環 + This button enables forwards-looping. The sample loops between the end point and the loop point. 點擊此按鈕後,Forwards-looping 會被打開,採樣將在終止點(End Point)和循環點(Loop Point)之間播放。 + This button enables ping-pong-looping. The sample loops backwards and forwards between the end point and the loop point. 點擊此按鈕後,Ping-pong-looping 會被打開,採樣將在終止點 (End Point) 和循環點 (Loop Point) 之間來回播放。 + + Continue sample playback across notes + 跨音符繼續播放採樣 + + + + 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) + + + + + Amplify: + 放大: + + + + 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!) + 此旋鈕用於調整放大比率。當設爲100% 時採樣不會變化。除此之外,不是放大就是減弱(原始的採樣文件不會被改變) + + + + Startpoint: + 起始點: + + + With this knob you can set the point where AudioFileProcessor should begin playing your sample. 調節此旋鈕,以告訴 AudioFileProcessor 在哪裏開始播放。 + + Endpoint: + 終點: + + + With this knob you can set the point where AudioFileProcessor should stop playing your sample. 調節此旋鈕,以告訴 AudioFileProcessor 在哪裏停止播放。 + Loopback point: 循環點: + With this knob you can set the point where the loop starts. 調節此旋鈕,以設置循環開始的地方。 @@ -213,6 +260,7 @@ BrLi <brli at chakraos.org> AudioFileProcessorWaveView + Sample length: 採樣長度: @@ -220,26 +268,32 @@ BrLi <brli at chakraos.org> AudioJack + JACK client restarted - JACK客戶端已重啓 + JACK 客戶端已重啓 + 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由於某些原因與JACK斷開連接,這可能是因爲LMMS的JACK後端重啓導致的,你需要手動重新連接。 + LMMS 由於某些原因與 JACK 中斷連線,因此 LMMS 的 JACK 後端已重新啟動,您必須手動重新連線。 + JACK server down - JACK服務崩潰 + JACK 伺服器發生問題 + 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. - JACK服務好像崩潰了而重開也失敗了,因此LMMS無法繼續執行。你需要儲存你的工作然後重啓JACK和LMMS。 + JACK 伺服器似乎發生問題,而且無法重新啟動,因此 LMMS 無法繼續執行。請儲存專案,然後重新啟動 JACK 和 LMMS。 + CLIENT-NAME 客戶端名稱 + CHANNELS 聲道數 @@ -247,10 +301,12 @@ BrLi <brli at chakraos.org> AudioOss::setupWidget + DEVICE - 設備 + 裝置 + CHANNELS 聲道數 @@ -258,21 +314,25 @@ BrLi <brli at chakraos.org> AudioPortAudio::setupWidget + BACKEND 後端 + DEVICE - 設備 + 裝置 AudioPulseAudio::setupWidget + DEVICE - 設備 + 裝置 + CHANNELS 聲道數 @@ -280,17 +340,20 @@ BrLi <brli at chakraos.org> AudioSdl::setupWidget + DEVICE - 設備 + 裝置 AudioSndio::setupWidget + DEVICE 裝置 + CHANNELS 聲道數 @@ -298,72 +361,88 @@ BrLi <brli at chakraos.org> AudioSoundIo::setupWidget + BACKEND 後端 + DEVICE - 設備 + 裝置 AutomatableModel + &Reset (%1%2) - 重置(%1%2)(&R) + 重設(%1%2)(&R) + &Copy value (%1%2) 複製值(%1%2)(&C) + &Paste value (%1%2) 貼上值(%1%2)(&P) + Edit song-global automation 編輯歌曲全局的自動控制裝置 - Connected to %1 - 連接到%1 - - - Connected to controller - 連接到控制器 - - - Edit connection... - 編輯連接... - - - Remove connection - 刪除連接 - - - Connect to controller... - 連接到控制器... - - + Remove song-global automation - 刪除歌曲全局的自動控制裝置 + 移除歌曲全域自動控制裝置 + Remove all linked controls - 刪除所有已連接的控制器 + 移除所有已連線的控制器 + + + + Connected to %1 + 已連線至 %1 + + + + Connected to controller + 連線至控制器 + + + + Edit connection... + 編輯連線… + + + + Remove connection + 移除連線 + + + + Connect to controller... + 連線至控制器… AutomationEditor + Please open an automation pattern with the context menu of a control! - 請使用控制的上下文菜單打開一個自動控制樣式! + 請透過控制的右鍵選單開啟自動控制模式! + Values copied 值已複製 + All selected values were copied to the clipboard. 所有選中的值已複製。 @@ -371,142 +450,184 @@ BrLi <brli at chakraos.org> 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. 點擊這裏停止播放片段。 - Draw mode (Shift+D) - 繪製模式 (Shift+D) - - - Erase mode (Shift+E) - 擦除模式 (Shift+E) - - - Flip vertically - 垂直翻轉 - - - Flip horizontally - 水平翻轉 - - - Click here and the pattern will be inverted.The points are flipped in the y direction. - 點擊這裡來翻轉圖形 (pattern)。圖上的點會隨y軸翻轉。 - - - Click here and the pattern will be reversed. The points are flipped in the x direction. - 點擊這裡來翻轉圖形 (pattern)。圖上的點會隨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. - 點擊這裏啓用繪製模式。在此模式下你可以增加或移動單個值。 大部分時間下默認使用此模式。你也可以按鍵盤上的 ‘Shift+D’激活此模式。 - - - 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. - 點擊啓用擦除模式。此模式下你可以擦除單個值。你可以按鍵盤上的 'Shift+E' 啓用此模式。 - - - Discrete progression - 區間進程 (Discrete progression) - - - Linear 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. - - - - Cut selected values (%1+X) - 剪切選定值 (%1+X) - - - Copy selected values (%1+C) - 複製選定值 (%1+C) - - - Paste values from clipboard (%1+V) - 從剪貼簿貼上值 (%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. - 點擊這裏,選擇的值將從剪貼板粘貼到第一個可見的小節。 - - - Tension: - - - - Automation Editor - no pattern - 自動控制編輯器 - 沒有片段 - - - Automation Editor - %1 - 自動控制編輯器 - %1 - - + Edit actions 編輯功能 + + Draw mode (Shift+D) + 繪製模式 (Shift+D) + + + + Erase mode (Shift+E) + 擦除模式 (Shift+E) + + + + Flip vertically + 垂直翻轉 + + + + Flip horizontally + 水平翻轉 + + + + Click here and the pattern will be inverted.The points are flipped in the y direction. + 點擊這裡來翻轉圖形 (pattern)。圖上的點會隨y軸翻轉。 + + + + Click here and the pattern will be reversed. The points are flipped in the x direction. + 點擊這裡來翻轉圖形 (pattern)。圖上的點會隨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. + 點擊這裏啓用繪製模式。在此模式下你可以增加或移動單個值。 大部分時間下默認使用此模式。你也可以按鍵盤上的 ‘Shift+D’激活此模式。 + + + + 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. + 點擊啓用擦除模式。此模式下你可以擦除單個值。你可以按鍵盤上的 'Shift+E' 啓用此模式。 + + + Interpolation controls 補間控制 - Timeline controls - 時間線控制 + + Discrete progression + 區間進程 (Discrete progression) + + Linear 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) + 剪下選擇的值 (%1+X) + + + + Copy selected values (%1+C) + 複製選擇的值 (%1+C) + + + + Paste values from clipboard (%1+V) + 從剪貼簿貼上值 (%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 + 自動控制編輯器 - %1 + + + Model is already connected to this pattern. 模型已連接到此片段。 @@ -514,6 +635,7 @@ BrLi <brli at chakraos.org> AutomationPattern + Drag a control while pressing <%1> 按住<%1>拖動控制器 @@ -521,46 +643,57 @@ BrLi <brli at chakraos.org> AutomationPatternView + double-click to open this pattern in automation editor 雙擊在自動編輯器中打開此片段 + Open in Automation editor 在自動編輯器(Automation editor)中打開 + Clear 清除 + Reset name 重置名稱 + Change name 修改名稱 - %1 Connections - %1個連接 - - - Disconnect "%1" - 斷開“%1”的連接 - - + Set/clear record 設置/清除錄製 + Flip Vertically (Visible) 垂直翻轉 (可見) + Flip Horizontally (Visible) 水平翻轉 (可見) + + %1 Connections + %1個連接 + + + + Disconnect "%1" + 斷開“%1”的連接 + + + Model is already connected to this pattern. 模型已連接到此片段。 @@ -568,6 +701,7 @@ BrLi <brli at chakraos.org> AutomationTrack + Automation track 自動控制軌道 @@ -575,77 +709,95 @@ BrLi <brli at chakraos.org> BBEditor + Beat+Bassline Editor 節拍+低音線編輯器 + Play/pause current beat/bassline (Space) 播放/暫停當前節拍/低音線(空格) + Stop playback of current beat/bassline (Space) 停止播放當前節拍/低音線(空格) + Click here to play the current beat/bassline. The beat/bassline is automatically looped when its end is reached. 點擊這裏停止播放當前節拍/低音線。當結束時節拍/低音線會自動循環播放。 + Click here to stop playing of current beat/bassline. 點擊這裏停止播發當前節拍/低音線。 - Add beat/bassline - 添加節拍/低音線 - - - Add automation-track - 添加自動控制軌道 - - - Remove steps - 移除音階 - - - Add steps - 添加音階 - - + Beat selector 節拍選擇器 + Track and step actions - Clone Steps - + + Add beat/bassline + 添加節拍/低音線 + Add sample-track 新增採樣音軌 + + + Add automation-track + 添加自動控制軌道 + + + + Remove steps + 移除音階 + + + + Add steps + 添加音階 + + + + Clone Steps + + BBTCOView + Open in Beat+Bassline-Editor 在節拍+Bassline編輯器中打開 + Reset name 重置名稱 + Change name 修改名稱 + Change color 改變顏色 + Reset color to default 重置顏色 @@ -653,10 +805,12 @@ BrLi <brli at chakraos.org> BBTrack + Beat/Bassline %1 節拍/Bassline %1 + Clone of %1 %1 的副本 @@ -664,26 +818,32 @@ BrLi <brli at chakraos.org> BassBoosterControlDialog + FREQ 頻率 + Frequency: 頻率: + GAIN 增益 + Gain: 增益: + RATIO 比率 + Ratio: 比率: @@ -691,14 +851,17 @@ BrLi <brli at chakraos.org> BassBoosterControls + Frequency 頻率 + Gain 增益 + Ratio 比率 @@ -706,82 +869,98 @@ BrLi <brli at chakraos.org> BitcrushControlDialog + IN 輸入 + OUT 輸出 + + GAIN 增益 + Input Gain: 輸入增益: - NOIS + + NOISE + Input Noise: 輸入噪音: + Output Gain: 輸出增益: + CLIP 壓限 + Output Clip: 輸出壓限: - Rate - - - + Rate Enabled + Enable samplerate-crushing - Depth - 位深 - - + Depth Enabled 深度已啓用 + Enable bitdepth-crushing + + FREQ + 頻率 + + + Sample rate: 採樣率: - STD - STD + + STEREO + + Stereo difference: 雙聲道差異: - Levels - 級別 + + QUANT + + Levels: 級別: @@ -789,10 +968,12 @@ BrLi <brli at chakraos.org> CaptionMenu + &Help 幫助(&H) + Help (not available) 幫助(不可用) @@ -800,10 +981,12 @@ BrLi <brli at chakraos.org> CarlaInstrumentView + Show GUI 顯示圖形界面 + Click here to show or hide the graphical user interface (GUI) of Carla. 點擊此處可以顯示或隱藏 Carla 的圖形界面。 @@ -811,6 +994,7 @@ BrLi <brli at chakraos.org> Controller + Controller %1 控制器%1 @@ -818,58 +1002,73 @@ BrLi <brli at chakraos.org> ControllerConnectionDialog + Connection Settings 連接設置 + MIDI CONTROLLER MIDI控制器 + Input channel 輸入通道 + CHANNEL 通道 + Input controller 輸入控制器 + CONTROLLER 控制器 + + Auto Detect 自動檢測 + MIDI-devices to receive MIDI-events from 用來接收 MIDI 事件的MIDI 設備 + USER CONTROLLER 用戶控制器 + MAPPING FUNCTION 映射函數 + OK 確定 + Cancel 取消 + LMMS LMMS + Cycle Detected. 檢測到環路。 @@ -877,18 +1076,22 @@ BrLi <brli at chakraos.org> ControllerRackView + Controller Rack 控制器機架 + Add 增加 + Confirm Delete 刪除前確認 + Confirm delete? There are existing connection(s) associated with this controller. There is no way to undo. 確定要刪除嗎?此控制器仍處於被連接狀態。此操作不可撤銷。 @@ -896,93 +1099,115 @@ BrLi <brli at chakraos.org> ControllerView + Controls 控制器 + Controllers are able to automate the value of a knob, slider, and other controls. 控制器可以自動控制旋鈕,滑塊和其他控件的值。 + Rename controller 重命名控制器 + Enter the new name for this controller 輸入這個控制器的新名稱 + + LFO + + + + &Remove this controller + Re&name this controller - - LFO - - CrossoverEQControlDialog + Band 1/2 Crossover: + Band 2/3 Crossover: + Band 3/4 Crossover: + Band 1 Gain: + Band 2 Gain: + Band 3 Gain: + Band 4 Gain: + Band 1 Mute + Mute Band 1 + Band 2 Mute + Mute Band 2 + Band 3 Mute + Mute Band 3 + Band 4 Mute + Mute Band 4 @@ -990,22 +1215,27 @@ BrLi <brli at chakraos.org> DelayControls + Delay Samples + Feedback + Lfo Frequency + Lfo Amount + Output gain 輸出增益 @@ -1013,228 +1243,311 @@ BrLi <brli at chakraos.org> DelayControlsDialog - Lfo Amt - - - - Delay Time - 延遲時間 - - - Feedback Amount - - - - Lfo - - - - Out Gain - - - - Gain - 增益 - - + DELAY + + Delay Time + 延遲時間 + + + FDBK + + Feedback Amount + + + + RATE + + Lfo + + + + AMNT + + + Lfo Amt + + + + + Out Gain + + + + + Gain + 增益 + DualFilterControlDialog - Filter 1 enabled - 已啓用過濾器 1 - - - Filter 2 enabled - 已啓用過濾器 2 - - - Click to enable/disable Filter 1 - 點擊啓用/禁用過濾器 1 - - - Click to enable/disable Filter 2 - 點擊啓用/禁用過濾器 2 - - + + FREQ 頻率 + + Cutoff frequency 切除頻率 + + RESO + + Resonance 共鳴 + + GAIN 增益 + + Gain 增益 + MIX + Mix 混合 + + + Filter 1 enabled + 已啓用過濾器 1 + + + + Filter 2 enabled + 已啓用過濾器 2 + + + + Click to enable/disable Filter 1 + 點擊啓用/禁用過濾器 1 + + + + Click to enable/disable Filter 2 + 點擊啓用/禁用過濾器 2 + DualFilterControls + Filter 1 enabled 過濾器1 已啓用 + Filter 1 type 過濾器 1 類型 + Cutoff 1 frequency 濾波器 1 截頻 + Q/Resonance 1 濾波器 1 Q值 + Gain 1 增益 1 + Mix 混合 + Filter 2 enabled 已啓用過濾器 2 + Filter 2 type 過濾器 1 類型 {2 ?} + Cutoff 2 frequency 濾波器 2 截頻 + Q/Resonance 2 濾波器 2 Q值 + Gain 2 增益 2 + + LowPass 低通 + + HiPass 高通 + + BandPass csg 帶通 csg + + BandPass czpg 帶通 czpg + + Notch 凹口濾波器 + + Allpass 全通 + + Moog Moog + + 2x LowPass 2 個低通串聯 + + RC LowPass 12dB RC 低通(12dB) + + RC BandPass 12dB RC 帶通(12dB) + + RC HighPass 12dB RC 高通(12dB) + + RC LowPass 24dB RC 低通(24dB) + + RC BandPass 24dB RC 帶通(24dB) + + RC HighPass 24dB RC 高通(24dB) + + Vocal Formant Filter 人聲移除過濾器 + + 2x Moog + + SV LowPass + + SV BandPass + + SV HighPass + + SV Notch + + Fast Formant + + Tripole @@ -1242,41 +1555,50 @@ BrLi <brli at chakraos.org> Editor + + Transport controls + + + + Play (Space) 播放(空格) + Stop (Space) 停止(空格) + Record 錄音 + Record while playing 播放時錄音 - - Transport controls - - Effect + Effect enabled 啓用效果器 + Wet/Dry mix 幹/溼混合 + Gate 門限 + Decay 衰減 @@ -1284,6 +1606,7 @@ BrLi <brli at chakraos.org> EffectChain + Effects enabled 啓用效果器 @@ -1291,10 +1614,12 @@ BrLi <brli at chakraos.org> EffectRackView + EFFECTS CHAIN 效果器鏈 + Add effect 增加效果器 @@ -1302,22 +1627,28 @@ BrLi <brli at chakraos.org> EffectSelectDialog + Add effect 增加效果器 + + Name 名稱 + Type 類型 + Description 描述 + Author @@ -1325,54 +1656,67 @@ BrLi <brli at chakraos.org> EffectView + Toggles the effect on or off. 打開或關閉效果. + On/Off 開/關 + W/D 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. 衰減旋鈕控制在插件停止工作前,緩衝區中加入的靜音時常。較小的數值會降低CPU佔用率但是可能導致延遲或混響產生撕裂。 + 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. @@ -1389,14 +1733,17 @@ Right clicking will bring up a context menu where you can change the order in wh + Move &up 向上移(&U) + Move &down 向下移(&D) + &Remove this plugin 移除此插件(&R) @@ -1404,58 +1751,72 @@ Right clicking will bring up a context menu where you can change the order in wh EnvelopeAndLfoParameters + Predelay 預延遲 + Attack 打進聲 + Hold 保持 + Decay 衰減 + Sustain 持續 + Release 釋放 + Modulation 調製 + LFO Predelay LFO 預延遲 + LFO Attack LFO 打進聲(attack) + LFO speed LFO 速度 + LFO Modulation LFO 調製 + LFO Wave Shape LFO 波形形狀 + Freq x 100 頻率 x 100 + Modulate Env-Amount 調製所有包絡 @@ -1463,349 +1824,439 @@ Right clicking will bring up a context menu where you can change the order in wh EnvelopeAndLfoView + + DEL DEL + Predelay: 預延遲: + 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: 打進聲: + 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: 持續: + 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 衰減 + 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 持續 + 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 釋音 + 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 + + Modulation amount: 調製量: + 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對此包絡的調製量,較大的值會對此包絡控制的值(如音量或截頻)影響更大。 + LFO predelay: 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: + 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 + LFO speed: + 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. 點擊這裡使用正弦波。 + Click here for a triangle-wave. 點擊這裡使用三角波。 + Click here for a saw-wave for current. 點擊這裡使用鋸齒波。 + Click here for a square-wave. 點擊這裡使用方形波。 + Click here for a user-defined wave. Afterwards, drag an according sample-file onto the LFO graph. 點擊這裡使用自訂波形。之後請把所用波形的樣本檔案拖到LFO Graph上。 + + Click here for random wave. + 點擊這裡使用隨機波形。 + + + FREQ x 100 頻率 x 100 + Click here if the frequency of this LFO should be multiplied by 100. 點擊這裡把這個LFO的頻率乘以100。 + multiply LFO-frequency by 100 + MODULATE ENV-AMOUNT + Click here to make the envelope-amount controlled by this LFO. + control envelope-amount by this LFO + ms/LFO: + Hint 提示 + Drag a sample from somewhere and drop it in this window. 把樣本檔案拖到這個視窗上放開。 - - Click here for random wave. - 點擊這裡使用隨機波形。 - EqControls + Input gain 輸入增益 + Output gain 輸出增益 + Low shelf gain + Peak 1 gain + Peak 2 gain + Peak 3 gain + Peak 4 gain + High Shelf gain + HP res + Low Shelf res + Peak 1 BW + Peak 2 BW + Peak 3 BW + Peak 4 BW + High Shelf res + LP res + HP freq + Low Shelf freq + Peak 1 freq + Peak 2 freq + Peak 3 freq + Peak 4 freq + High shelf freq + LP freq + HP active + Low shelf active + Peak 1 active + Peak 2 active + Peak 3 active + Peak 4 active + High shelf active + LP active + LP 12 + LP 24 + LP 48 + HP 12 + HP 24 + HP 48 + low pass type + high pass type + Analyse IN + Analyse OUT @@ -1813,85 +2264,108 @@ Right clicking will bring up a context menu where you can change the order in wh EqControlsDialog + HP + Low Shelf + Peak 1 + Peak 2 + Peak 3 + Peak 4 + High Shelf + LP + In Gain + + + Gain 增益 + Out Gain + Bandwidth: + + Octave + + + + Resonance : + Frequency: 頻率: + lp grp + hp grp - - Octave - - EqHandle + Reso: + BW: + + Freq: @@ -1899,174 +2373,243 @@ Right clicking will bring up a context menu where you can change the order in wh ExportProjectDialog + Export project 導出工程 + Output 輸出 + File format: - 文件格式: + 檔案格式: + Samplerate: 採樣率: + 44100 Hz 44100 Hz + 48000 Hz 48000 Hz + 88200 Hz 88200 Hz + 96000 Hz 96000 Hz + 192000 Hz 192000 Hz - Bitrate: - 碼率: - - - 64 KBit/s - 64 KBit/s - - - 128 KBit/s - 128 KBit/s - - - 160 KBit/s - 160 KBit/s - - - 192 KBit/s - 192 KBit/s - - - 256 KBit/s - 256 KBit/s - - - 320 KBit/s - 320 KBit/s - - + Depth: 位深: + 16 Bit Integer 16 位整形 + + 24 Bit Integer + 24 位元整數 + + + 32 Bit Float 32 位浮點型 - Please note that not all of the parameters above apply for all file formats. - 請注意上面的參數不一定適用於所有文件格式。 + + Stereo mode: + + + Stereo + + + + + Joint Stereo + + + + + Mono + + + + + Bitrate: + 碼率: + + + + 64 KBit/s + 64 KBit/s + + + + 128 KBit/s + 128 KBit/s + + + + 160 KBit/s + 160 KBit/s + + + + 192 KBit/s + 192 KBit/s + + + + 256 KBit/s + 256 KBit/s + + + + 320 KBit/s + 320 KBit/s + + + + Use variable bitrate + 使用可變位元率 + + + Quality settings 質量設置 + Interpolation: 補間: + Zero Order Hold 零階保持 + Sinc Fastest 最快 Sinc 補間 + Sinc Medium (recommended) 中等 Sinc 補間 (推薦) + Sinc Best (very slow!) 最佳 Sinc 補間 (很慢!) + Oversampling (use with care!): 過採樣 (請謹慎使用!): + 1x (None) 1x (無) + 2x 2x + 4x 4x + 8x 8x - Start - 開始 - - - Cancel - 取消 - - + Export as loop (remove end silence) 導出爲迴環loop(移除結尾的靜音) + Export between loop markers 只導出迴環標記中間的部分 - Could not open file - 無法打開文件 + + Start + 開始 + + Cancel + 取消 + + + + 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! + 無法開啟 %1 以進行寫入。 +請確認您有權限存取此檔案,以及包含此檔案的目錄後再試一次。 + + + Export project to %1 導出項目到 %1 + Error 錯誤 + Error while determining file-encoder device. Please try to choose a different output format. - 尋找文件編碼設備時出錯。請使用另外一種輸出格式。 + 偵測檔案編碼裝置時發生錯誤。請嘗試使用其他輸出格式。 + Rendering: %1% 渲染中:%1% - - 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! - - Fader + + Please enter a new value between %1 and %2: 請輸入一個介於%1和%2之間的數值: @@ -2074,6 +2617,7 @@ Please make sure you have write permission to the file and the directory contain FileBrowser + Browser 瀏覽器 @@ -2081,65 +2625,80 @@ Please make sure you have write permission to the file and the directory contain FileBrowserTreeWidget + Send to active instrument-track 發送到活躍的樂器軌道 - Open in new instrument-track/B+B Editor - 在新樂器軌道/B+B 編輯器中打開 - - - Loading sample - 加載採樣中 - - - Please wait, loading sample for preview... - 請稍候,加載採樣中... - - - --- Factory files --- - ---軟件自帶文件--- - - + Open in new instrument-track/Song Editor 在新的樂器軌道/歌曲編輯器中打開 + + Open in new instrument-track/B+B Editor + 在新樂器軌道/B+B 編輯器中打開 + + + + Loading sample + 加載採樣中 + + + + Please wait, loading sample for preview... + 請稍候,加載採樣中... + + + Error 錯誤 + does not appear to be a valid 並不是一個有效的 + file - 文件 + 檔案 + + + + --- Factory files --- + --- 內建檔案 --- FlangerControls + Delay Samples + Lfo Frequency + Seconds + Regen + Noise 噪音 + Invert 反轉 @@ -2147,46 +2706,57 @@ Please make sure you have write permission to the file and the directory contain FlangerControlsDialog - Delay Time: - 延遲時間: - - - Feedback Amount: - - - - White Noise Amount: - 白噪音數量: - - + DELAY + + Delay Time: + 延遲時間: + + + RATE - Rate: + + Period: + AMNT + Amount: + FDBK + + Feedback Amount: + + + + NOISE + + White Noise Amount: + 白噪音數量: + + + Invert 反轉 @@ -2194,10 +2764,12 @@ Please make sure you have write permission to the file and the directory contain FxLine + Channel send amount 通道發送的數量 + 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. @@ -2208,22 +2780,27 @@ You can remove and move FX channels in the context menu, which is accessed by ri + Move &left 向左移(&L) + Move &right 向右移(&R) + Rename &channel 重命名通道(&C) + R&emove channel 刪除通道(&E) + Remove &unused channels 移除所有未用通道(&U) @@ -2231,37 +2808,62 @@ You can remove and move FX channels in the context menu, which is accessed by ri FxMixer + Master 主控 + + + FX %1 FX %1 + + + Volume + 音量 + + + + Mute + 靜音 + + + + Solo + 獨奏 + FxMixerView + FX-Mixer 效果混合器 + FX Fader %1 FX 衰減器 %1 + Mute 靜音 + Mute this FX channel 靜音此效果通道 + Solo 獨奏 + Solo FX channel 獨奏效果通道 @@ -2269,6 +2871,8 @@ You can remove and move FX channels in the context menu, which is accessed by ri FxRoute + + Amount to send from channel %1 to channel %2 從通道 %1 發送到通道 %2 的量 @@ -2276,14 +2880,17 @@ You can remove and move FX channels in the context menu, which is accessed by ri GigInstrument + Bank + Patch 音色 + Gain 增益 @@ -2291,740 +2898,926 @@ You can remove and move FX channels in the context menu, which is accessed by ri GigInstrumentView + Open other GIG file 打開另外的 GIG 文件 + Click here to open another GIG file 點擊這裏打開另外一個 GIG 文件 + Choose the patch 選擇路徑 + Click here to change which patch of the GIG file to use 點擊這裏選擇另一種 GIG 音色 + + Change which instrument of the GIG file is being played 更換正在使用的 GIG 文件中的樂器 + Which GIG file is currently being used 哪一個 GIG 文件正在被使用 + Which patch of the GIG file is currently being used GIG 文件的哪一個音色正在被使用 + Gain 增益 + Factor to multiply samples by + Open GIG file - 打開 GIG 文件 + 開啟 GIG 檔案 + GIG Files (*.gig) - GIG 文件 (*.gig) + GIG 檔案 (*.gig) GuiApplication + Working directory 工作目錄 + The LMMS working directory %1 does not exist. Create it now? You can change the directory later via Edit -> Settings. LMMS工作目錄%1不存在,現在新建一個嗎?你可以稍後在 編輯 -> 設置 中更改此設置。 + Preparing UI 正在準備界面 + Preparing song editor 正在準備歌曲編輯器 + Preparing mixer 正在準備混音器 + Preparing controller rack 正在準備控制機架 + Preparing project notes - 正在準備工程註釋 + 正在準備專案音符 + Preparing beat/bassline editor 正在準備節拍/低音線編輯器 + Preparing piano roll - 正在準備鋼琴窗 + 正在準備鋼琴捲簾 + Preparing automation editor - 正在準備自動編輯器 + 正在準備自動化控制編輯器 InstrumentFunctionArpeggio + Arpeggio + Arpeggio type + Arpeggio range - Arpeggio time + + Cycle steps - Arpeggio gate - - - - Arpeggio direction - - - - Arpeggio mode - - - - Up - 向上 - - - Down - 向下 - - - Up and down - 上和下 - - - Random - 隨機 - - - Free - 自由 - - - Sort - 排序 - - - Sync - 同步 - - - Down and up - 下和上 - - + Skip rate + Miss rate - Cycle steps + + Arpeggio time + + + Arpeggio gate + + + + + Arpeggio direction + + + + + Arpeggio mode + + + + + Up + 向上 + + + + Down + 向下 + + + + Up and down + 上和下 + + + + Down and up + 下和上 + + + + Random + 隨機 + + + + Free + 自由 + + + + Sort + 排序 + + + + Sync + 同步 + InstrumentFunctionArpeggioView + 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 範圍 + Arpeggio range: + octave(s) + Use this knob for setting the arpeggio range in octaves. The selected arpeggio will be played within specified number of octaves. - TIME - 時長 - - - Arpeggio time: - - - - ms - 毫秒 - - - Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. - - - - GATE - 門限 - - - 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: - 和絃: - - - Direction: - 方向: - - - Mode: - 模式: - - - SKIP - - - - Skip rate: - - - - 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. - - - + CYCLE + Cycle notes: + note(s) + 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 + + + + + Skip rate: + + + + + + + % + % + + + + 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 + 時長 + + + + Arpeggio time: + + + + + ms + 毫秒 + + + + Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. + + + + + GATE + 門限 + + + + 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: + 和絃: + + + + Direction: + 方向: + + + + Mode: + 模式: + InstrumentFunctionNoteStacking + octave octave + + Major Major + Majb5 Majb5 + 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 Maj7 + Maj7b5 Maj7b5 + Maj7#5 Maj7#5 + Maj7#11 Maj7#11 + Maj7add13 Maj7add13 + m7 m7 + m7b5 m7b5 + m7b9 m7b9 + m7add11 m7add11 + m7add13 m7add13 + m-Maj7 m-Maj7 + m-Maj7add11 m-Maj7add11 + m-Maj7add13 m-Maj7add13 + 9 9 + 9sus4 9sus4 + add9 add9 + 9#5 9#5 + 9b5 9b5 + 9#11 9#11 + 9b13 9b13 + Maj9 Maj9 + Maj9sus4 Maj9sus4 + Maj9#5 Maj9#5 + Maj9#11 Maj9#11 + m9 m9 + madd9 madd9 + m9b5 m9b5 + m9-Maj7 m9-Maj7 + 11 11 + 11b9 11b9 + Maj11 Maj11 + m11 m11 + m-Maj11 m-Maj11 + 13 13 + 13#9 13#9 + 13b9 13b9 + 13b5b9 13b5b9 + Maj13 Maj13 + m13 m13 + m-Maj13 m-Maj13 + Harmonic minor Harmonic minor + Melodic minor Melodic minor + Whole tone + Diminished Diminished + Major pentatonic Major pentatonic + Minor pentatonic Minor pentatonic + Jap in sen Jap in sen + Major bebop Major bebop + Dominant bebop Dominant bebop + Blues Blues + Arabic Arabic + Enigmatic Enigmatic + Neopolitan Neopolitan + Neopolitan minor Neopolitan minor + Hungarian minor Hungarian minor + Dorian Dorian - Phrygolydian + + Phrygian + Lydian Lydian + Mixolydian Mixolydian + Aeolian Aeolian + Locrian Locrian - Chords - Chords - - - Chord type - Chord type - - - Chord range - Chord range - - + Minor Minor + Chromatic Chromatic + Half-Whole Diminished + 5 5 + Phrygian dominant + Persian + + + Chords + Chords + + + + Chord type + Chord type + + + + Chord range + Chord range + InstrumentFunctionNoteStackingView - RANGE - 範圍 - - - Chord range: - 和絃範圍: - - - octave(s) - - - - Use this knob for setting the chord range in octaves. The selected chord will be played within specified number of octaves. - - - + STACKING 堆疊 + Chord: 和絃: + + + RANGE + 範圍 + + + + Chord range: + 和絃範圍: + + + + octave(s) + + + + + 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 啓用MIDI輸入 + + CHANNEL 通道 + + VELOCITY 力度 + ENABLE MIDI OUTPUT 啓用MIDI輸出 + PROGRAM 樂器 - MIDI devices to receive MIDI events from - 用於接收 MIDI 事件的 MIDI 設備 - - - MIDI devices to send MIDI events to - 用於發送 MIDI 事件的 MIDI 設備 - - + NOTE 音符 + + MIDI devices to receive MIDI events from + 用於接收 MIDI 事件的 MIDI 設備 + + + + MIDI devices to send MIDI events to + 用於發送 MIDI 事件的 MIDI 設備 + + + CUSTOM BASE VELOCITY 自定義基準力度 + Specify the velocity normalization base for MIDI-based instruments at 100% note velocity + BASE VELOCITY 基準力度 @@ -3032,10 +3825,12 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentMiscView + MASTER PITCH 主音高 + Enables the use of Master Pitch 啓用主音高 @@ -3043,126 +3838,158 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentSoundShaping + VOLUME 音量 + Volume 音量 + CUTOFF 切除 + + Cutoff frequency 切除頻率 + RESO + Resonance 共鳴 + Envelopes/LFOs 壓限/低頻振盪 + Filter type 過濾器類型 + Q/Resonance + LowPass 低通 + HiPass 高通 + BandPass csg 帶通 csg + BandPass czpg 帶通 czpg + Notch 凹口濾波器 + Allpass 全通 + Moog Moog + 2x LowPass 2 個低通串聯 + RC LowPass 12dB RC 低通(12dB) + RC BandPass 12dB RC 帶通(12dB) + RC HighPass 12dB RC 高通(12dB) + RC LowPass 24dB RC 低通(24dB) + RC BandPass 24dB RC 帶通(24dB) + RC HighPass 24dB RC 高通(24dB) + Vocal Formant Filter 人聲移除過濾器 + 2x Moog + SV LowPass + SV BandPass + SV HighPass + SV Notch + Fast Formant + Tripole @@ -3170,50 +3997,62 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentSoundShapingView + TARGET 目標 + 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 + 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. - 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 - - - - Resonance: - 共鳴: - - - 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. - - - + FREQ 頻率 + cutoff frequency: + + 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 + + + + + Resonance: + 共鳴: + + + + 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. 包絡和低頻振盪 (LFO) 不被當前樂器支持。 @@ -3221,85 +4060,107 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentTrack - unnamed_track - 未命名軌道 - - - Volume - 音量 - - - Panning - 聲相 - - - Pitch - 音高 - - - FX channel - 效果通道 - - - Default preset - 預置 - - + With this knob you can set the volume of the opened channel. 使用此旋鈕可以設置開放通道的音量。 + + + unnamed_track + 未命名軌道 + + + Base note 基本音 + + Volume + 音量 + + + + Panning + 聲相 + + + + Pitch + 音高 + + + Pitch range 音域範圍 + + FX channel + 效果通道 + + + Master Pitch 主音高 + + + + Default preset + 預置 + InstrumentTrackView + Volume 音量 + Volume: 音量: + VOL VOL + Panning 聲相 + Panning: 聲相: + PAN PAN + MIDI MIDI + Input 輸入 + Output 輸出 + FX %1: %2 效果 %1: %2 @@ -3307,125 +4168,160 @@ You can remove and move FX channels in the context menu, which is accessed by ri InstrumentTrackWindow + GENERAL SETTINGS 常規設置 - Instrument volume - 樂器音量 - - - Volume: - 音量: - - - VOL - VOL - - - Panning - 聲相 - - - Panning: - 聲相: - - - PAN - PAN - - - Pitch - 音高 - - - Pitch: - 音高: - - - cents - 音分 cents - - - PITCH - - - - FX channel - 效果通道 - - - ENV/LFO - 包絡/低振 - - - FUNC - 功能 - - - FX - 效果 - - - MIDI - MIDI - - - Save preset - 保存預置 - - - XML preset file (*.xpf) - XML 預設文件 (*.xpf) - - - PLUGIN - 插件 - - - Pitch range (semitones) - 音域範圍(半音) - - - RANGE - 範圍 - - - 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. - 如果你想保存當前樂器軌道設置到預設文件, 請點擊這裏。稍後你可以在預設瀏覽器中雙擊以使用它。 - - - MISC - 雜項 - - + Use these controls to view and edit the next/previous track in the song editor. 使用這些控制選項來查看和編輯在歌曲編輯器中的上個/下個軌道。 + + Instrument volume + 樂器音量 + + + + Volume: + 音量: + + + + VOL + VOL + + + + Panning + 聲相 + + + + Panning: + 聲相: + + + + PAN + PAN + + + + Pitch + 音高 + + + + Pitch: + 音高: + + + + cents + 音分 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 + MIDI設置 + + + + Miscellaneous + + + + + Save preset + 保存預置 + + + + XML preset file (*.xpf) + XML 預設集檔案 (*.xpf) + + + + Plugin + + 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: 請輸入一個介於%1和%2之間的數值: @@ -3433,6 +4329,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaControl + Link channels 關聯通道 @@ -3440,10 +4337,12 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaControlDialog + Link Channels 連接通道 + Channel 通道 @@ -3451,14 +4350,17 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaControlView + Link channels 連接通道 + Value: 值: + Sorry, no help available. 啊哦,這個沒有幫助文檔。 @@ -3466,6 +4368,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri LadspaEffect + Unknown LADSPA plugin %1 requested. 已請求未知 LADSPA 插件 %1. @@ -3473,6 +4376,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri LcdSpinBox + Please enter a new value between %1 and %2: 請輸入一個介於%1和%2之間的數值: @@ -3480,18 +4384,26 @@ You can remove and move FX channels in the context menu, which is accessed by ri LeftRightNav + + + Previous 上個 + + + Next 下個 + Previous (%1) 上 (%1) + Next (%1) 下 (%1) @@ -3499,30 +4411,37 @@ You can remove and move FX channels in the context menu, which is accessed by ri LfoController + LFO Controller LFO 控制器 + Base value 基準值 + Oscillator speed 振動速度 + Oscillator amount + Oscillator phase + Oscillator waveform 振動波形 + Frequency Multiplier @@ -3530,114 +4449,141 @@ You can remove and move FX channels in the context menu, which is accessed by ri LfoControllerDialog + LFO + LFO Controller LFO 控制器 + BASE 基準 + Base amount: 基礎值: + todo + SPD + LFO-speed: + Use this knob for setting speed of the LFO. The bigger this value the faster the LFO oscillates and the faster the effect. + + AMNT + + + + Modulation amount: 調製量: + 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 + Phase offset: + degrees + 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. 點擊這裡使用正弦波。 + Click here for a triangle-wave. 點擊這裡使用三角波。 + Click here for a saw-wave. + Click here for a square-wave. 點擊這裡使用方形波。 - Click here for an exponential wave. - - - - Click here for white-noise. - - - - Click here for a user-defined shape. -Double click to pick a file. - - - + Click here for a moog saw-wave. - AMNT + + Click here for an exponential wave. + + + + + Click here for white-noise. + + + + + Click here for a user-defined shape. +Double click to pick a file. LmmsCore + Generating wavetables 正在生成波形表 + Initializing data structures 正在初始化數據結構 + Opening audio and midi devices 正在啓動音頻和 MIDI 設備 + Launching mixer threads 生在啓動混音器線程 @@ -3645,405 +4591,500 @@ Double click to pick a file. MainWindow - Could not save config-file - 不能保存配置文件 + + Configuration file + 設定檔 - Could not save configuration file %1. You're probably not permitted to write to this file. -Please make sure you have write-access to the file and try again. - 不能保存配置文件%1,你可能沒有寫權限。 -請確保你可以寫入這個文件並重試。 + + Error while parsing configuration file at line %1:%2: %3 + 解析設定檔時發生錯誤(行 %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! + 無法開啟 %1 以進行寫入。 +請確認您有權限存取此檔案,以及包含此檔案的目錄後再試一次。 + + + + 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? + 發現復原檔案。可能是上一個工作階段未正常結束,或者另一個 LMMS 已在執行。您想要復原這個專案嗎? + + + + + + Recover + 恢復 + + + + Recover the file. Please don't run multiple instances of LMMS when you do this. + 復原檔案。請不要在復原檔案時同時開啟多個 LMMS 視窗。 + + + + + + Discard + 丟棄 + + + + Launch a default session and delete the restored files. This is not reversible. + 開啟新的預設工作階段並刪除已復原的檔案。此操作無法復原。 + + + + Version %1 + 版本 %1 + + + + Preparing plugin browser + 正在準備插件瀏覽器 + + + + Preparing file browsers + 正在準備檔案瀏覽器 + + + + My Projects + 我的工程 + + + + My Samples + 我的採樣 + + + + My Presets + 我的預設 + + + + My Home + 我的主目錄 + + + + Root directory + 根目錄 + + + + Volumes + 音量 + + + + My Computer + 我的電腦 + + + + Loading background artwork + 正在加載背景圖案 + + + + &File + 檔案(&F) + + + &New 新建(&N) + + New from template + 從模版新建工程 + + + &Open... 打開(&O)... + + &Recently Opened Projects + 最近打開的工程(&R) + + + &Save 保存(&S) + Save &As... 另存爲(&A)... + + Save as New &Version + 保存爲新版本(&V) + + + + Save as default template + 保存爲默認模板 + + + Import... 導入... + E&xport... 導出(&E)... + + E&xport Tracks... + 導出音軌(&X)... + + + + Export &MIDI... + 導出 MIDI (&M)... + + + &Quit 退出(&Q) + &Edit 編輯(&E) + + Undo + 撤銷 + + + + Redo + 重做 + + + Settings 設置 + + &View + 視圖 (&V) + + + &Tools 工具(&T) + &Help 幫助(&H) + + Online Help + 在線幫助 + + + Help 幫助 - What's this? - 這是什麼? + + What's This? + 這是什麼? + About 關於 + Create new project 新建工程 + Create new project from template 從模版新建工程 + Open existing project 打開已有工程 + Recently opened projects 最近打開的工程 + Save current project 保存當前工程 + Export current project 導出當前工程 - Song Editor + + What's this? + 這是什麼? + + + + Toggle metronome + 開啓/關閉節拍器 + + + + Show/hide Song-Editor 顯示/隱藏歌曲編輯器 + 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. 點擊這個按鈕, 你可以顯示/隱藏歌曲編輯器。在歌曲編輯器的幫助下, 你可以編輯歌曲播放列表並且設置哪個音軌在哪個時間播放。你還可以在播放列表中直接插入和移動採樣(如 RAP 採樣)。 - Beat+Bassline Editor + + Show/hide Beat+Bassline Editor 顯示/隱藏節拍+旋律編輯器 + 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. - Piano Roll + + Show/hide Piano-Roll 顯示/隱藏鋼琴窗 + Click here to show or hide the Piano-Roll. With the help of the Piano-Roll you can edit melodies in an easy way. 點擊這裏顯示或隱藏鋼琴窗。在鋼琴窗的幫助下, 你可以很容易地編輯旋律。 - Automation Editor + + Show/hide Automation Editor 顯示/隱藏自動控制編輯器 + 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. 點擊這裏顯示或隱藏自動控制編輯器。在自動控制編輯器的幫助下, 你可以很簡單地控制動態數值。 - FX Mixer + + Show/hide 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. 點擊這裏顯示或隱藏 FX 混音器。FX 混音器是管理你歌曲中不同音效的強大工具。你可以向不同的通道添加不同的效果。 - Project Notes + + Show/hide project notes 顯示/隱藏工程註釋 + Click here to show or hide the project notes window. In this window you can put down your project notes. 點擊這裏顯示或隱藏工程註釋窗。在此窗口中你可以寫下工程的註釋。 - Controller Rack + + Show/hide controller rack 顯示/隱藏控制器機架 + Untitled - 未標題 + 未命名 + + Recover session. Please save your work! + 恢復會話。請保存你的工作! + + + LMMS %1 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) + LMMS (*.mmp *.mmpz) + + + + Save Project + 保存工程 + + + + LMMS Project + LMMS 工程 + + + + LMMS Project Template + LMMS 工程模板 + + + + 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. LMMS現在沒有可用的幫助 請訪問 http://lmms.sf.net/wiki 瞭解LMMS的相關文檔。 - LMMS (*.mmp *.mmpz) - LMMS (*.mmp *.mmpz) - - - Version %1 - 版本 %1 - - - Configuration file - 配置文件 - - - Error while parsing configuration file at line %1:%2: %3 - 解析配置文件發生錯誤(行%1:%2:%3) - - - Volumes - 音量 - - - Undo - 撤銷 - - - Redo - 重做 - - - My Projects - 我的工程 - - - My Samples - 我的採樣 - - - My Presets - 我的預設 - - - My Home - 我的主目錄 - - - My Computer - 我的電腦 - - - &File - 文件(&F) - - - &Recently Opened Projects - 最近打開的工程(&R) - - - Save as New &Version - 保存爲新版本(&V) - - - E&xport Tracks... - 導出音軌(&X)... - - - Online Help - 在線幫助 - - - What's This? - 這是什麼? - - - Open Project - 打開工程 - - - Save Project - 保存工程 - - - 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? - 發現了一個恢復文件。看上去上個會話沒有正常結束或者其他的 LMMS 進程已經運行。你想要恢復這個項目嗎? - - - Recover - 恢復 - - - Recover the file. Please don't run multiple instances of LMMS when you do this. - 恢復文件。請不要在恢復文件時運行多個 LMMS 程序。 - - - Ignore - 忽略 - - - Launch LMMS as usual but with automatic backup disabled to prevent the present recover file from being overwritten. - 正常啓動 LMMS 但是關閉自動備份來防止備份文件被覆蓋。 - - - Discard - 丟棄 - - - Launch a default session and delete the restored files. This is not reversible. - 運行一個新的默認會話並且刪除恢復文件。此操作無法撤銷。 - - - Preparing plugin browser - 正在準備插件瀏覽器 - - - Preparing file browsers - 正在準備文件瀏覽器 - - - Root directory - 根目錄 - - - Loading background artwork - 正在加載背景圖案 - - - New from template - 從模版新建工程 - - - Save as default template - 保存爲默認模板 - - - &View - 視圖 (&V) - - - Toggle metronome - 開啓/關閉節拍器 - - - Show/hide Song-Editor + + Song Editor 顯示/隱藏歌曲編輯器 - Show/hide Beat+Bassline Editor + + Beat+Bassline Editor 顯示/隱藏節拍+旋律編輯器 - Show/hide Piano-Roll + + Piano Roll 顯示/隱藏鋼琴窗 - Show/hide Automation Editor + + Automation Editor 顯示/隱藏自動控制編輯器 - Show/hide FX Mixer + + FX Mixer 顯示/隱藏混音器 - Show/hide project notes + + Project Notes 顯示/隱藏工程註釋 - Show/hide controller rack + + Controller Rack 顯示/隱藏控制器機架 - Recover session. Please save your work! - 恢復會話。請保存你的工作! - - - Automatic backup disabled. Remember to save your work! - 自動備份已禁用。記得保存你的作品喲! - - - 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? - 這個工程已從上一個會話中恢復。它現在沒有被保存, 並且如果你不保存, 它將會丟失。你現在想保存它嗎? - - - LMMS Project - LMMS 工程 - - - LMMS Project Template - LMMS 工程模板 - - - Overwrite default template? - 覆蓋默認的模板? - - - This will overwrite your current default template. - 這將會覆蓋你的當前默認模板。 - - + Volume as dBFS + Smooth scroll 平滑滾動 + Enable note labels in piano roll 在鋼琴窗中顯示音號 - - Save project template - - MeterDialog + + Meter Numerator + + Meter Denominator + TIME SIG 拍子記號 @@ -4051,10 +5092,12 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MeterModel + Numerator + Denominator @@ -4062,10 +5105,12 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MidiController + MIDI Controller MIDI控制器 + unnamed_midi_controller @@ -4073,18 +5118,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. 你還沒有在設置(在編輯->設置)中設置默認的 Soundfont。因此在導入此 MIDI 文件後將會沒有聲音。你需要下載一個通用 MIDI (GM) 的 Soundfont, 並且在設置對話框中選中後再試一次。 + 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. - 你在編譯 LMMS 時沒有加入 SoundFont2 播放器支持, 此播放器默認用於添加導入的 MIDI 文件。因此在 MIDI 文件導入後, 將沒有聲音。 + 您在編譯 LMMS 時未一併啟用 SoundFont2 播放器支援,此播放器用於為匯入的 MIDI 檔案加入預設聲音,因此在匯入此 MIDI 檔後不會有聲音。 + Track 軌道 @@ -4092,11 +5142,13 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MidiJack + JACK server down When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (title) JACK服務崩潰 + The JACK server seems to be shuted down. When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (dialog message) @@ -4105,53 +5157,65 @@ 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 - Output MIDI program - - - - Receive MIDI-events - 接受 MIDI 事件 - - - Send MIDI-events - 發送 MIDI 事件 - - + Fixed output note + + Output MIDI program + + + + Base velocity 基準力度 + + + Receive MIDI-events + 接受 MIDI 事件 + + + + Send MIDI-events + 發送 MIDI 事件 + MidiSetupWidget + DEVICE 設備 @@ -4159,474 +5223,595 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MonstroInstrument + Osc 1 Volume + Osc 1 Panning + 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 + Osc 2 Panning + 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 + Osc 3 Panning + 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 + LFO 1 Attack + LFO 1 Rate + LFO 1 Phase + LFO 2 Waveform + LFO 2 Attack + LFO 2 Rate + LFO 2 Phase + Env 1 Pre-delay + Env 1 Attack + 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 + Vol1-Env1 + Vol1-Env2 + Vol1-LFO1 + Vol1-LFO2 + Vol2-Env1 + Vol2-Env2 + Vol2-LFO1 + Vol2-LFO2 + Vol3-Env1 + Vol3-Env2 + Vol3-LFO1 + Vol3-LFO2 + Phs1-Env1 + Phs1-Env2 + Phs1-LFO1 + Phs1-LFO2 + Phs2-Env1 + Phs2-Env2 + Phs2-LFO1 + Phs2-LFO2 + Phs3-Env1 + Phs3-Env2 + Phs3-LFO1 + Phs3-LFO2 + Pit1-Env1 + Pit1-Env2 + Pit1-LFO1 + Pit1-LFO2 + Pit2-Env1 + Pit2-Env2 + Pit2-LFO1 + Pit2-LFO2 + Pit3-Env1 + Pit3-Env2 + Pit3-LFO1 + Pit3-LFO2 + PW1-Env1 + PW1-Env2 + PW1-LFO1 + PW1-LFO2 + Sub3-Env1 + Sub3-Env2 + Sub3-LFO1 + Sub3-LFO2 + + Sine wave 正弦波 + Bandlimited Triangle wave + Bandlimited Saw wave + Bandlimited Ramp wave + Bandlimited Square wave + Bandlimited Moog saw wave + + Soft square wave + Absolute sine wave + + Exponential wave + White noise + Digital Triangle wave + Digital Saw wave + Digital Ramp wave + Digital Square wave + Digital Moog saw wave + Triangle wave 三角波 + Saw wave 鋸齒波 + Ramp wave + Square wave 方波 + Moog saw wave + Abs. sine wave + Random 隨機 + Random smooth @@ -4634,20 +5819,24 @@ Please visit http://lmms.sf.net/wiki for documentation on LMMS. MonstroView + Operators view + 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 矩陣視圖 + 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. @@ -4656,256 +5845,407 @@ Each modulation target has 4 knobs, one for each modulator. By default the knobs + + + + Volume + 音量 + + + + + + Panning + 聲相 + + + + + + Coarse detune + + + + + + + semitones + 半音 + + + + + Finetune left + + + + + + + + cents + + + + + + 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 + 打進聲 + + + + + Rate + + + + + + Phase + + + + + + Pre-delay + + + + + + Hold + 保持 + + + + + Decay + 衰減 + + + + + Sustain + 持續 + + + + + 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. + 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. - Volume - 音量 - - - Panning - 聲相 - - - Coarse detune - - - - semitones - 半音 - - - Finetune left - - - - cents - - - - 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 - 打進聲 - - - Rate - - - - Phase - - - - Pre-delay - - - - Hold - 保持 - - - Decay - 衰減 - - - Sustain - 持續 - - - Release - 釋放 - - - Slope - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Modulation amount 調製量 @@ -4913,34 +6253,42 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator MultitapEchoControlDialog + Length 長度 + Step length: 步進長度: + Dry 幹聲 + Dry Gain: 幹聲增益: + Stages + Lowpass stages: + Swap inputs + Swap left and right input channel for reflections @@ -4948,82 +6296,102 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator NesInstrument + Channel 1 Coarse detune + Channel 1 Volume + Channel 1 Envelope length + Channel 1 Duty cycle + Channel 1 Sweep amount + Channel 1 Sweep rate + Channel 2 Coarse detune + Channel 2 Volume + Channel 2 Envelope length + Channel 2 Duty cycle + Channel 2 Sweep amount + Channel 2 Sweep rate + Channel 3 Coarse detune + Channel 3 Volume + Channel 4 Volume + Channel 4 Envelope length + Channel 4 Noise frequency + Channel 4 Noise frequency sweep + Master volume 主音量 + Vibrato @@ -5031,114 +6399,155 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator NesInstrumentView + + + + Volume 音量 + + + Coarse detune + + + Envelope length + Enable channel 1 + Enable envelope 1 + Enable envelope 1 loop + Enable sweep 1 + + Sweep amount + + Sweep rate + + 12.5% Duty cycle + + 25% Duty cycle + + 50% Duty cycle + + 75% Duty cycle + Enable channel 2 + Enable envelope 2 + Enable envelope 2 loop + Enable sweep 2 + Enable channel 3 + Noise Frequency + Frequency sweep + Enable channel 4 + Enable envelope 4 + Enable envelope 4 loop + Quantize noise frequency when using note frequency + Use note frequency for noise + Noise mode + Master Volume 主音量 + Vibrato @@ -5146,81 +6555,103 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator OscillatorObject - Osc %1 volume - Osc %1 音量 - - - Osc %1 panning - Osc %1 聲像 - - - Osc %1 coarse detuning - - - - Osc %1 fine detuning left - - - - Osc %1 fine detuning right - - - - Osc %1 phase-offset - - - - Osc %1 stereo phase-detuning - - - - Osc %1 wave shape - - - - Modulation type %1 - - - + Osc %1 waveform Osc %1 波形 + Osc %1 harmonic + + + + Osc %1 volume + Osc %1 音量 + + + + + Osc %1 panning + 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 + + + + + Modulation type %1 + + PatchesDialog + Qsynth: Channel Preset Qsynth: 通道預設 + Bank selector 音色選擇器 + Bank + Program selector + Patch 音色 + Name 名稱 + OK 確定 + Cancel 取消 @@ -5228,46 +6659,57 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PatmanView + Open other patch 打開其他音色 + Click here to open another patch-file. Loop and Tune settings are not reset. 點擊這裏打開另一個音色文件。循環和調音設置不會被重設。 + Loop 循環 + Loop mode 循環模式 + Here you can toggle the Loop mode. If enabled, PatMan will use the loop information available in the file. 在這裏你可以開關循環模式。如果啓用,PatMan 會使用文件中的循環信息。 + Tune 調音 + Tune mode 調音模式 + Here you can toggle the Tune mode. If enabled, PatMan will tune the sample to match the note's frequency. 這裏可以開關調音模式。如果啓用,PatMan 會將採樣調成和音符一樣的頻率。 + No file selected - 未選擇文件 + 未選擇檔案 + Open patch file 打開音色文件 + Patch-Files (*.pat) 音色文件 (*.pat) @@ -5275,38 +6717,47 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PatternView - Open in piano-roll - 在鋼琴窗中打開 - - - Clear all notes - 清除所有音符 - - - Reset name - 重置名稱 - - - Change name - 修改名稱 - - - Add steps - 添加音階 - - - Remove steps - 移除音階 - - + use mouse wheel to set velocity of a step + double-click to open in Piano Roll + + Open in piano-roll + 在鋼琴窗中打開 + + + + Clear all notes + 清除所有音符 + + + + Reset name + 重置名稱 + + + + Change name + 修改名稱 + + + + Add steps + 添加音階 + + + + Remove steps + 移除音階 + + + Clone Steps @@ -5314,25 +6765,30 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PeakController + Peak Controller 峯值控制器 + Peak Controller Bug 峯值控制器 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. - 在老版本的 LMMS 中, 峯值控制器因爲有 bug 而可能沒有正確連接。請確保峯值控制器正常連接後再次保存次文件。我們對給你造成的不便深表歉意。 + 由於在舊版 LMMS 中的錯誤,峰值控制器可能並未正確地連線。請確認峰值控制器正確地連線後再次儲存檔案。造成您的不便,深感抱歉。 PeakControllerDialog + PEAK + LFO Controller LFO 控制器 @@ -5340,306 +6796,382 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator PeakControllerEffectControlDialog + BASE 基準 + Base amount: 基礎值: - Modulation amount: - 調製量: - - - Attack: - 打擊聲: - - - Release: - 釋音: - - + AMNT + + Modulation amount: + 調製量: + + + MULT + Amount Multiplicator: + ATCK 打擊 + + Attack: + 打擊聲: + + + DCAY - Treshold: + + Release: + 釋音: + + + + TRSH - TRSH + + Treshold: PeakControllerEffectControls + Base value 基準值 + Modulation amount 調製量 - Mute output - 輸出靜音 - - + Attack 打進聲 + Release 釋放 + + Treshold + 閥值 + + + + Mute output + 輸出靜音 + + + Abs Value + Amount Multiplicator - - Treshold - 閥值 - PianoRoll - Please open a pattern by double-clicking on it! - 雙擊打開片段! - - - Last note - 上一個音符 - - - Note lock - 音符鎖定 - - + Note Velocity 音符音量 + Note Panning 音符聲相偏移 + Mark/unmark current semitone 標記/取消標記當前半音 - Mark current scale - - - - Mark current chord - - - - Unmark all - 取消標記所有 - - - No scale - - - - No chord - - - - Velocity: %1% - 音量:%1% - - - Panning: %1% left - 聲相:%1% 偏左 - - - Panning: %1% right - 聲相:%1% 偏右 - - - Panning: center - 聲相:居中 - - - Please enter a new value between %1 and %2: - 請輸入一個介於 %1 和 %2 的值: - - + 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% + 音量:%1% + + + + Panning: %1% left + 聲相:%1% 偏左 + + + + Panning: %1% right + 聲相:%1% 偏右 + + + + Panning: center + 聲相:居中 + + + + Please open a pattern by double-clicking on it! + 雙擊打開片段! + + + + + Please enter a new value between %1 and %2: + 請輸入一個介於 %1 和 %2 的值: + PianoRollWindow + Play/pause current pattern (Space) 播放/暫停當前片段(空格) + Record notes from MIDI-device/channel-piano 從 MIDI 設備/通道鋼琴(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. - Draw mode (Shift+D) - 繪製模式 (Shift+D) - - - Erase mode (Shift+E) - 擦除模式 (Shift+E) - - - Select mode (Shift+S) - 選擇模式 (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. - 點擊啓用擦除模式。此模式下你可以擦除音符。你可以按鍵盤上的 'Shift+E' 啓用此模式。 - - - 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. - - - - Cut selected notes (%1+X) - 剪切選定音符 (%1+X) - - - Copy selected notes (%1+C) - 複製選定音符 (%1+C) - - - Paste notes from clipboard (%1+V) - 從剪貼板粘貼音符 (%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. - - - - 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. - - - + Edit actions 編輯功能 + + Draw mode (Shift+D) + 繪製模式 (Shift+D) + + + + Erase mode (Shift+E) + 擦除模式 (Shift+E) + + + + Select mode (Shift+S) + 選擇模式 (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. + + + + + 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. + 點擊啓用擦除模式。此模式下你可以擦除音符。你可以按鍵盤上的 'Shift+E' 啓用此模式。 + + + + 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 + + + + Copy paste controls + + Cut selected notes (%1+X) + 剪切選定音符 (%1+X) + + + + Copy selected notes (%1+C) + 複製選定音符 (%1+C) + + + + Paste notes from clipboard (%1+V) + 從剪貼板粘貼音符 (%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 鋼琴窗 - %1 + + Piano-Roll - no pattern 鋼琴窗 - 沒有片段 - - Quantize - - PianoView + Base note 基本音 @@ -5647,20 +7179,24 @@ PM means phase modulation: Oscillator 3's phase is modulated by oscillator Plugin + Plugin not found 未找到插件 + The plugin "%1" wasn't found or could not be loaded! Reason: "%2" 插件“%1”無法找到或無法載入! 原因:%2 + Error while loading plugin 載入插件時發生錯誤 + Failed to load plugin "%1"! 載入插件“%1”失敗! @@ -5668,25 +7204,30 @@ Reason: "%2" PluginBrowser + + Instrument Plugins + + + + Instrument browser 樂器瀏覽器 + Drag an instrument into either the Song-Editor, the Beat+Bassline Editor or into an existing instrument track. 將樂器插件拖入歌曲編輯器, 節拍低音線編輯器, 或者現有的樂器軌道。 - - Instrument Plugins - - PluginFactory + Plugin not found. 未找到插件。 + LMMS plugin %1 does not have a plugin descriptor named %2! @@ -5694,118 +7235,147 @@ Reason: "%2" ProjectNotes - Project notes - 工程註釋 + + Project Notes + 顯示/隱藏工程註釋 - Put down your project notes here. - 在這裏寫下你的工程註釋。 + + Enter project notes here + + Edit Actions 編輯功能 + &Undo 撤銷(&U) + %1+Z %1+Z + &Redo 重做(&R) + %1+Y %1+Y + &Copy 複製(&C) + %1+C %1+C + Cu&t 剪切(&T) + %1+X %1+X + &Paste 粘貼(&P) + %1+V %1+V + Format Actions 格式功能 + &Bold 加粗(&B) + %1+B %1+B + &Italic 斜體(&I) + %1+I %1+I + &Underline 下劃線(&U) + %1+U %1+U + &Left 左對齊(&L) + %1+L %1+L + C&enter 居中(&E) + %1+E %1+E + &Right 右對齊(&R) + %1+R %1+R + &Justify 勻齊(&J) + %1+J %1+J + &Color... 顏色(&C)... @@ -5813,142 +7383,274 @@ Reason: "%2" ProjectRenderer + WAV-File (*.wav) WAV-文件 (*.wav) + Compressed OGG-File (*.ogg) 壓縮的 OGG 文件(*.ogg) + + + Compressed MP3-File (*.mp3) + + QWidget + + + Name: 名稱: + + Maker: 製作者: + + Copyright: 版權: + + Requires Real Time: 要求實時: + + + + + + Yes + + + + + + No + + Real Time Capable: 是否支持實時: + + In Place Broken: + + Channels In: 輸入通道: + + Channels Out: 輸出通道: - File: - 文件: + + File: %1 + 檔案:%1 - File: %1 - 文件:%1 + + File: + 檔案: RenameDialog + Rename... 重命名... + + ReverbSCControlDialog + + + Input + 輸入 + + + + Input Gain: + 輸入增益: + + + + Size + + + + + Size: + + + + + Color + + + + + Color: + + + + + Output + 輸出 + + + + Output Gain: + 輸出增益: + + + + ReverbSCControls + + + Input Gain + + + + + Size + + + + + Color + + + + + Output Gain + + + SampleBuffer + + Fail to open file + 無法開啟檔案 + + + + Audio files are limited to %1 MB in size and %2 minutes of playing time + 音訊檔案的檔案大小已限制為 %1 MB,播放時間已限制為 %2 分鐘。 + + + Open audio file - 打開音頻文件 - - - Wave-Files (*.wav) - Wave波形文件 (*.wav) - - - OGG-Files (*.ogg) - OGG-文件 (*.ogg) - - - DrumSynth-Files (*.ds) - DrumSynth-文件 (*.ds) - - - FLAC-Files (*.flac) - FLAC-文件 (*.flac) - - - SPEEX-Files (*.spx) - SPEEX-文件 (*.spx) - - - VOC-Files (*.voc) - VOC-文件 (*.voc) - - - AIFF-Files (*.aif *.aiff) - AIFF-文件 (*.aif *.aiff) - - - AU-Files (*.au) - AU-文件 (*.au) - - - RAW-Files (*.raw) - RAW-文件 (*.raw) + 開啟音訊檔案 + All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) - 所有音頻文件 (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + 所有音訊檔案 (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + + + + Wave-Files (*.wav) + Wave 波形檔案 (*.wav) + + + + OGG-Files (*.ogg) + OGG 檔案 (*.ogg) + + + + DrumSynth-Files (*.ds) + DrumSynth 檔案 (*.ds) + + + + FLAC-Files (*.flac) + FLAC 檔案 (*.flac) + + + + SPEEX-Files (*.spx) + SPEEX 檔案 (*.spx) + + + + VOC-Files (*.voc) + VOC 檔案 (*.voc) + + + + AIFF-Files (*.aif *.aiff) + AIFF 檔案 (*.aif *.aiff) + + + + AU-Files (*.au) + AU 檔案 (*.au) + + + + RAW-Files (*.raw) + RAW 檔案 (*.raw) SampleTCOView + double-click to select sample 雙擊選擇採樣 + Delete (middle mousebutton) 刪除 (鼠標中鍵) + Cut 剪切 + Copy 複製 + Paste 粘貼 + Mute/unmute (<%1> + middle click) 靜音/取消靜音 (<%1> + 鼠標中鍵) @@ -5956,41 +7658,51 @@ Reason: "%2" SampleTrack - Sample track - 採樣軌道 - - + Volume 音量 + Panning 聲相 + + + + Sample track + 採樣軌道 + SampleTrackView + Track volume 軌道音量 + Channel volume: 通道音量: + VOL VOL + Panning 聲相 + Panning: 聲相: + PAN PAN @@ -5998,496 +7710,658 @@ Reason: "%2" SetupDialog + Setup LMMS 設置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 同步 VST 插件和主機回放 + 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 LMMS工作目錄 - VST-plugin directory - VST插件目錄 + + Themes directory + 主題文件目錄 + Background artwork 背景圖片 + + VST-plugin directory + VST插件目錄 + + + + GIG directory + GIG 目錄 + + + + SF2 directory + SF2 目錄 + + + + LADSPA plugin directories + LADSPA 插件目錄 + + + STK rawwave directory STK rawwave 目錄 + Default Soundfont File - 默認 SoundFont 文件 + 預設 SoundFont 檔案 + + Performance settings 性能設置 + + Auto save + 自動保存 + + + + Enable auto-save + + + + + Allow auto-save while playing + + + + UI effects vs. performance 界面特效 vs 性能 + Smooth scroll in Song Editor 歌曲編輯器中啓用平滑滾動 + Show playback cursor in AudioFileProcessor - 在 AudioFileProcessor 中顯示回放光標 + 在 AudioFileProcessor 中顯示播放指標 + + Audio settings 音頻設置 + AUDIO INTERFACE 音頻接口 + + MIDI settings MIDI設置 + MIDI INTERFACE MIDI接口 + OK 確定 + Cancel 取消 + Restart LMMS 重啓LMMS + Please note that most changes won't take effect until you restart LMMS! 請注意很多設置需要重啓LMMS纔可生效! + Frames: %1 Latency: %2 ms 幀數: %1 延遲: %2 毫秒 + 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. 在這裏,你可以設置 LMMS 所用緩衝區的大小。緩衝區越小,延遲越小,但聲音質量和性能可能會受影響。 + Choose LMMS working directory 選擇 LMMS 工作目錄 - Choose your VST-plugin directory - 選擇 VST 插件目錄 - - - Choose artwork-theme directory - 選擇插圖目錄 - - - Choose LADSPA plugin directory - 選擇 LADSPA 插件目錄 - - - Choose STK rawwave directory - 選擇 STK rawwave 目錄 - - - Choose default SoundFont - 選擇默認的 SoundFont - - - Choose background artwork - 選擇背景圖片 - - - 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. - 在這裏你可以選擇你想要的音頻接口。取決於你的系統和編譯時的設置, 你可以選擇 ALSA, JACK, OSS 等選項。在下面的方框中你可以設置音頻接口的控制項目。 - - - 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. - 在這裏你可以選擇你想要的 MIDI 接口。取決於你的系統和編譯時的設置, 你可以選擇 ALSA, OSS 等選項。在下面的方框中你可以設置 MIDI 接口的控制項目。 - - - Reopen last project on start - 啓動時打開最近的項目 - - - Directories - 目錄 - - - Themes directory - 主題文件目錄 - - - GIG directory - GIG 目錄 - - - SF2 directory - SF2 目錄 - - - LADSPA plugin directories - LADSPA 插件目錄 - - - Auto save - 自動保存 - - + Choose your GIG directory 選擇 GIG 目錄 + Choose your SF2 directory 選擇 SF2 目錄 + + Choose your VST-plugin directory + 選擇 VST 插件目錄 + + + + Choose artwork-theme directory + 選擇插圖目錄 + + + + Choose LADSPA plugin directory + 選擇 LADSPA 插件目錄 + + + + Choose STK rawwave directory + 選擇 STK rawwave 目錄 + + + + Choose default SoundFont + 選擇默認的 SoundFont + + + + Choose background artwork + 選擇背景圖片 + + + minutes 分鐘 + minute 分鐘 - Enable auto-save - - - - Allow auto-save while playing - - - + 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. + 在這裏你可以選擇你想要的音頻接口。取決於你的系統和編譯時的設置, 你可以選擇 ALSA, JACK, OSS 等選項。在下面的方框中你可以設置音頻接口的控制項目。 + + + + 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. + 在這裏你可以選擇你想要的 MIDI 接口。取決於你的系統和編譯時的設置, 你可以選擇 ALSA, OSS 等選項。在下面的方框中你可以設置 MIDI 接口的控制項目。 + Song + Tempo 節奏 + Master volume 主音量 + Master pitch 主音高 - Project saved - 工程已保存 - - - The project %1 is now saved. - 工程 %1 已保存。 - - - Project NOT saved. - 工程 **沒有** 保存。 - - - The project %1 was not saved! - 工程%1沒有保存! - - - Import file - 導入文件 - - - MIDI sequences - MIDI 音序器 - - - Hydrogen projects - Hydrogen工程 - - - 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... - 爲工程導出選擇文件... - - - The following errors occured while loading: - 載入時發生以下錯誤: - - - MIDI File (*.mid) - MIDI 文件 (*.mid) - - + LMMS Error report LMMS錯誤報告 + + Project saved + 工程已保存 + + + + The project %1 is now saved. + 工程 %1 已保存。 + + + + Project NOT saved. + 工程 **沒有** 保存。 + + + + The project %1 was not saved! + 工程%1沒有保存! + + + + Import file + 匯入檔案 + + + + MIDI sequences + MIDI 音序器 + + + + Hydrogen projects + Hydrogen工程 + + + + 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) + MIDI 檔案 (*.mid) + + + + The following errors occured while loading: + 載入時發生以下錯誤: + SongEditor + Could not open file - 無法打開文件 - - - Could not write 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. - 無法打開 %1 。或許沒有權限讀此文件。 -請確保您擁有對此文件的讀權限,然後重試。 + 無法開啟 %1。 +請確認您至少有權限讀取此檔案後再試一次。 - Error in file - 文件錯誤 - - - The file %1 seems to contain errors and therefore can't be loaded. - 文件 %1 似乎包含錯誤,無法被加載。 - - - Tempo - 節奏 - - - TEMPO/BPM - 節奏/BPM - - - tempo of song - 歌曲的節奏 - - - 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 - 高質量模式 - - - Master volume - 主音量 - - - master volume - 主音量 - - - Master pitch - 主音高 - - - master pitch - 主音高 - - - Value: %1% - 值: %1% - - - Value: %1 semitones - 值: %1 半音程 + + 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. - 無法打開 %1 寫入數據。或許沒有權限修改此文件。請確保您擁有對此文件的寫權限,然後重試。 + 無法開啟 %1 以進行寫入。請確認您有權限寫入此檔案後再試一次。 - template - + + Error in file + 於檔案中發現錯誤 - project - + + The file %1 seems to contain errors and therefore can't be loaded. + 檔案 %1 似乎包含錯誤,無法進行載入。 + Version difference + This %1 was created with LMMS %2. + + + template + + + + + project + + + + + Tempo + 節奏 + + + + TEMPO/BPM + 節奏/BPM + + + + tempo of song + 歌曲的節奏 + + + + 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 + 高質量模式 + + + + + Master volume + 主音量 + + + + master volume + 主音量 + + + + + Master pitch + 主音高 + + + + master pitch + 主音高 + + + + Value: %1% + 值: %1% + + + + Value: %1 semitones + 值: %1 半音程 + SongEditorWindow + Song-Editor 歌曲編輯器 + Play song (Space) 播放歌曲(空格) + Record samples from Audio-device 從音頻設備錄製樣本 + Record samples from Audio-device while playing song or BB track 在播放歌曲或BB軌道時從音頻設備錄入樣本 + Stop song (Space) 停止歌曲(空格) - Add beat/bassline - 添加節拍/Bassline - - - Add sample-track - 添加採樣軌道 - - - Add automation-track - 添加自動控制軌道 - - - Draw mode - 繪製模式 - - - Edit mode (select and move) - 編輯模式(選定和移動) - - + 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. 點擊這裏完整播放歌曲。將從綠色歌曲標記開始播放。在播放的同時可以對它進行移動。 + 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 軌道動作 + + Add beat/bassline + 添加節拍/Bassline + + + + Add sample-track + 添加採樣軌道 + + + + Add automation-track + 添加自動控制軌道 + + + Edit actions 編輯動作 + + Draw mode + 繪製模式 + + + + Edit mode (select and move) + 編輯模式(選定和移動) + + + Timeline controls 時間線控制 + Zoom controls 縮放控制 @@ -6495,10 +8369,12 @@ Remember to also save your project manually. You can choose to disable saving wh SpectrumAnalyzerControlDialog + Linear spectrum 線性頻譜圖 + Linear Y axis 線性 Y 軸 @@ -6506,14 +8382,17 @@ Remember to also save your project manually. You can choose to disable saving wh SpectrumAnalyzerControls + Linear spectrum 線性頻譜圖 + Linear Y axis 線性 Y 軸 + Channel mode 通道模式 @@ -6521,14 +8400,17 @@ Remember to also save your project manually. You can choose to disable saving wh SubWindow + Close + Maximize + Restore @@ -6536,6 +8418,8 @@ Remember to also save your project manually. You can choose to disable saving wh TabWidget + + Settings for %1 %1 的設定 @@ -6543,74 +8427,93 @@ Remember to also save your project manually. You can choose to disable saving wh TempoSyncKnob + + Tempo Sync + No Sync 無同步 + Eight beats + Whole note + Half note + Quarter note + 8th note + 16th note + 32nd note + Custom... + Custom + 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 @@ -6618,30 +8521,37 @@ Remember to also save your project manually. You can choose to disable saving wh TimeDisplayWidget + click to change time units 點擊改變時間單位 + MIN + SEC + MSEC + BAR + BEAT + TICK @@ -6649,34 +8559,43 @@ Remember to also save your project manually. You can choose to disable saving wh TimeLineWidget + Enable/disable auto-scrolling 啓用/禁用自動滾動 + Enable/disable loop-points 啓用/禁用循環點 + After stopping go back to begin 停止後前往開頭 + After stopping go back to position at which playing was started 停止後前往播放開始的地方 + After stopping keep position 停止後保持位置不變 + + Hint 提示 + Press <%1> to disable magnetic loop points. 按住 <%1> 禁用磁性吸附。 + Hold <Shift> to move the begin loop point; Press <%1> to disable magnetic loop points. 按住 <Shift> 移動起始循環點;按住 <%1> 禁用磁性吸附。 @@ -6684,10 +8603,12 @@ Remember to also save your project manually. You can choose to disable saving wh Track + Mute 靜音 + Solo 獨奏 @@ -6695,45 +8616,71 @@ Remember to also save your project manually. You can choose to disable saving wh TrackContainer + Couldn't import file - 無法導入文件 + 無法匯入檔案 + Couldn't find a filter for importing file %1. You should convert this file into a format supported by LMMS using another software. - 無法找到導入文件 %1 的導入器 -你需要使用其他軟件將此文件轉換成 LMMS 支持的格式。 + 不支援 %1 的檔案類型。 +請使用其他軟體將此檔案轉換成 LMMS 支援的格式。 + Couldn't open file - 無法打開文件 + 無法開啟檔案 + 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! - 無法讀取文件 %1 -請確認你有對該文件及其目錄的讀取權限後再試! + 無法開啟 %1。 +請確認您有權限讀取此檔案,以及包含此檔案的目錄後再試一次。 + Loading project... 正在加載工程... + + Cancel 取消 + + Please wait... 請稍等... + + Loading cancelled + + + + + Project loading was cancelled. + + + + + Loading Track %1 (%2/Total %3) + + + + Importing MIDI-file... - 正在導入 MIDI-文件... + 正在匯入 MIDI 檔案… TrackContentObject + Mute 靜音 @@ -6741,46 +8688,59 @@ Please make sure you have read-permission to the file and the directory containi TrackContentObjectView + Current position 當前位置 + + Hint 提示 + Press <%1> and drag to make a copy. 按住 <%1> 並拖動以創建副本。 + Current length 當前長度 + Press <%1> for free resizing. 按住 <%1> 自由調整大小。 + + %1:%2 (%3:%4 to %5:%6) %1:%2 (%3:%4 到 %5:%6) + Delete (middle mousebutton) 刪除 (鼠標中鍵) + Cut 剪切 + Copy 複製 + Paste 粘貼 + Mute/unmute (<%1> + middle click) 靜音/取消靜音 (<%1> + 鼠標中鍵) @@ -6788,193 +8748,243 @@ 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 效果 %1: %2 + + Assign to new FX Channel + + + + Turn all recording on + Turn all recording off - - Assign to new FX Channel - - 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 + 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 + Synchronize oscillator 2 with oscillator 3 + Use frequency modulation for modulating oscillator 2 with oscillator 3 + Osc %1 volume: + 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: + 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 + 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 音分 cents + 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 + 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. 爲當前振盪器使用正弦波。 + Use a triangle-wave for current oscillator. 爲當前振盪器使用三角波。 + Use a saw-wave for current oscillator. 爲當前振盪器使用鋸齒波。 + Use a square-wave for current oscillator. 爲當前振盪器使用方波。 + Use a moog-like saw-wave for current oscillator. + Use an exponential wave for current oscillator. + Use white-noise for current oscillator. 爲當前振盪器使用白噪音。 + Use a user-defined waveform for current oscillator. 爲當前振盪器使用用戶自定波形。 @@ -6982,14 +8992,17 @@ Please make sure you have read-permission to the file and the directory containi VersionedSaveDialog + Increment version number 遞增版本號 + Decrement version number 遞減版本號 + already exists. Do you want to replace it? @@ -6997,90 +9010,113 @@ Please make sure you have read-permission to the file and the directory containi VestigeInstrumentView + Open other VST-plugin 打開其他的VST插件 + 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. - Show/hide GUI - 顯示/隱藏界面 - - - Click here to show or hide the graphical user interface (GUI) of your VST-plugin. - 點此顯示/隱藏VST插件的界面。 - - - Turn off all notes - 全部靜音 - - - Open VST-plugin - 打開VST插件 - - - DLL-files (*.dll) - DLL-文件 (*.dll) - - - EXE-files (*.exe) - EXE-文件 (*.exe) - - - No VST-plugin loaded - 未載入VST插件 - - + Control VST-plugin from LMMS host 從 LMMS 宿主控制 VST-插件 + Click here, if you want to control VST-plugin from host. + Open VST-plugin preset 打開 VST-插件預設 + 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. 點擊這裏, 如果你想保存當前 VST-插件預設。 + 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. + 點此顯示/隱藏VST插件的界面。 + + + + Turn off all notes + 全部靜音 + + + + Open VST-plugin + 打開VST插件 + + + + DLL-files (*.dll) + DLL 檔案 (*.dll) + + + + EXE-files (*.exe) + EXE 檔案 (*.exe) + + + + No VST-plugin loaded + 未載入VST插件 + + + Preset 預置 + by + - VST plugin control - VST插件控制 @@ -7088,10 +9124,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 點擊啓用 @@ -7099,54 +9137,69 @@ Please make sure you have read-permission to the file and the directory containi VstEffectControlDialog + Show/hide 顯示/隱藏 + Control VST-plugin from LMMS host 從 LMMS 宿主控制 VST-插件 + Click here, if you want to control VST-plugin from host. + Open VST-plugin preset 打開 VST-插件預設 + 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. 點擊這裏, 如果你想保存當前 VST-插件預設。 + + Effect by: + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> @@ -7154,173 +9207,217 @@ Please make sure you have read-permission to the file and the directory containi VstPlugin - Loading plugin - 載入插件 + + + The VST plugin %1 could not be loaded. + 無法載入VST插件 %1。 + Open Preset 打開預置 + + Vst Plugin Preset (*.fxp *.fxb) VST插件預置文件(*.fxp *.fxb) + : default : 默認 + " " + ' ' + Save Preset 保存預置 + .fxp .fxp + .FXP .FXP + .FXB .FXB + .fxb .fxb - Please wait while loading VST plugin... - 正在載入VST插件,請稍候…… + + Loading plugin + 載入插件 - The VST plugin %1 could not be loaded. - 無法載入VST插件 %1。 + + Please wait while loading VST plugin... + 正在載入VST插件,請稍候…… WatsynInstrument + Volume A1 + Volume A2 + Volume B1 + Volume B2 + Panning A1 + Panning A2 + Panning B1 + Panning 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 + Right detune B1 + Right detune B2 + 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 + B2-B1 modulation + Selected graph @@ -7328,213 +9425,291 @@ Please make sure you have read-permission to the file and the directory containi WatsynView - Select oscillator A1 - - - - Select oscillator A2 - - - - Select oscillator B1 - - - - Select oscillator B2 - - - - Mix output of A2 to A1 - - - - Modulate amplitude of A1 with output of A2 - - - - Ring-modulate A1 and A2 - - - - Modulate phase of A1 with output of A2 - - - - Mix output of B2 to B1 - - - - Modulate amplitude of B1 with output of B2 - - - - Ring-modulate B1 and B2 - - - - Modulate phase of B1 with output of B2 - - - - Draw your own waveform here by dragging your mouse on this graph. - - - - Load waveform - 載入波形 - - - Click to load a waveform from a sample file - - - - Phase left - - - - Click to shift phase by -15 degrees - - - - Phase right - - - - Click to shift phase by +15 degrees - - - - Normalize - 標準化 - - - Click to normalize - - - - Invert - 反轉 - - - Click to invert - - - - Smooth - 平滑 - - - Click to smooth - - - - Sine wave - 正弦波 - - - Click for sine wave - - - - Triangle wave - 三角波 - - - Click for triangle wave - - - - Click for saw wave - - - - Square wave - 方波 - - - Click for square wave - - - + + + + Volume 音量 + + + + Panning 聲相 + + + + Freq. multiplier + + + + Left detune + + + + + + + + cents + + + + Right detune + A-B Mix + Mix envelope amount + Mix envelope attack + Mix envelope hold + Mix envelope decay + Crosstalk + + + Select oscillator A1 + + + + + Select oscillator A2 + + + + + Select oscillator B1 + + + + + Select oscillator B2 + + + + + Mix output of A2 to A1 + + + + + Modulate amplitude of A1 with output of A2 + + + + + Ring-modulate A1 and A2 + + + + + Modulate phase of A1 with output of A2 + + + + + Mix output of B2 to B1 + + + + + Modulate amplitude of B1 with output of B2 + + + + + Ring-modulate B1 and B2 + + + + + Modulate phase of B1 with output of B2 + + + + + + + + Draw your own waveform here by dragging your mouse on this graph. + + + + + Load waveform + 載入波形 + + + + Click to load a waveform from a sample file + + + + + Phase left + + + + + Click to shift phase by -15 degrees + + + + + Phase right + + + + + Click to shift phase by +15 degrees + + + + + Normalize + 標準化 + + + + Click to normalize + + + + + Invert + 反轉 + + + + Click to invert + + + + + Smooth + 平滑 + + + + Click to smooth + + + + + Sine wave + 正弦波 + + + + Click for sine wave + + + + + + Triangle wave + 三角波 + + + + Click for triangle wave + + + + + Click for saw wave + + + + + Square wave + 方波 + + + + Click for square wave + + ZynAddSubFxInstrument + Portamento + Filter Frequency + Filter Resonance + Bandwidth 帶寬 + FM Gain FM 增益 + Resonance Center Frequency + Resonance Bandwidth + Forward MIDI Control Change Events @@ -7542,121 +9717,150 @@ Please make sure you have read-permission to the file and the directory containi ZynAddSubFxView - Show GUI - 顯示圖形界面 - - - Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. - - - + 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. + + audioFileProcessor + Amplify 增益 + Start of sample 採樣起始 + End of sample 採樣結尾 - Reverse sample - 反轉採樣 - - - Stutter - - - + Loopback point 循環點 + + Reverse sample + 反轉採樣 + + + Loop mode 循環模式 + + Stutter + + + + Interpolation mode 補間方式 + None + Linear 線性插補 + Sinc 辛格(Sinc)插補 + Sample not found: %1 採樣未找到: %1 @@ -7664,6 +9868,7 @@ Please make sure you have read-permission to the file and the directory containi bitInvader + Samplelength 採樣長度 @@ -7671,165 +9876,205 @@ Please make sure you have read-permission to the file and the directory containi bitInvaderView + Sample Length 採樣長度 - Sine wave - 正弦波 - - - Triangle wave - 三角波 - - - Saw wave - 鋸齒波 - - - Square wave - 方波 - - - White noise wave - 白噪音 - - - User defined wave - 用戶自定義波形 - - - Smooth - 平滑 - - - Click here to smooth waveform. - 點擊這裏平滑波形。 - - - Interpolation - - - - Normalize - 標準化 - - + Draw your own waveform here by dragging your mouse on this graph. + + Sine wave + 正弦波 + + + Click for a sine-wave. + + Triangle wave + 三角波 + + + Click here for a triangle-wave. 點擊這裡使用三角波。 + + Saw wave + 鋸齒波 + + + Click here for a saw-wave. + + Square wave + 方波 + + + Click here for a square-wave. 點擊這裡使用方形波。 + + White noise wave + 白噪音 + + + Click here for white-noise. + + User defined wave + 用戶自定義波形 + + + Click here for a user-defined shape. + + + Smooth + 平滑 + + + + Click here to smooth waveform. + 點擊這裏平滑波形。 + + + + Interpolation + + + + + Normalize + 標準化 + dynProcControlDialog + INPUT 輸入 + Input gain: 輸入增益: + OUTPUT 輸出 + Output gain: 輸出增益: + ATTACK + Peak attack time: + RELEASE + Peak release time: + Reset waveform 重置波形 + Click here to reset the wavegraph back to default + Smooth waveform 平滑波形 + Click here to apply smoothing to wavegraph 點擊這裏來使波形圖更爲平滑 + Increase wavegraph amplitude by 1dB + Click here to increase wavegraph amplitude by 1dB + Decrease wavegraph amplitude by 1dB + Click here to decrease wavegraph amplitude by 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 @@ -7837,22 +10082,27 @@ Please make sure you have read-permission to the file and the directory containi dynProcControls + Input gain 輸入增益 + Output gain 輸出增益 + Attack time + Release time + Stereo mode @@ -7860,10 +10110,12 @@ Please make sure you have read-permission to the file and the directory containi fxLineLcdSpinBox + Assign to: 分配給: + New FX Channel 新的效果通道 @@ -7871,6 +10123,7 @@ Please make sure you have read-permission to the file and the directory containi graphModel + Graph 圖形 @@ -7878,50 +10131,62 @@ Please make sure you have read-permission to the file and the directory containi kickerInstrument + Start frequency 起始頻率 + End frequency 結束頻率 - Gain - 增益 - - + Length 長度 + Distortion Start 起始失真度 + Distortion End 結束失真度 + + Gain + 增益 + + + Envelope Slope 包絡線傾斜度 + Noise 噪音 + Click 力度 + Frequency Slope 頻率傾斜度 + Start from note 從哪個音符開始 + End to note 到哪個音符結束 @@ -7929,42 +10194,52 @@ Please make sure you have read-permission to the file and the directory containi kickerInstrumentView + Start frequency: 起始頻率: + End frequency: 結束頻率: - Gain: - 增益: - - + Frequency Slope: 頻率傾斜度: + + Gain: + 增益: + + + Envelope Length: 包絡長度: + Envelope Slope: 包絡線傾斜度: + Click: 力度: + Noise: 噪音: + Distortion Start: 起始失真度: + Distortion End: 結束失真度: @@ -7972,26 +10247,37 @@ Please make sure you have read-permission to the file and the directory containi ladspaBrowserView + + Available Effects 可用效果器 + + Unavailable Effects 不可用效果器 + + Instruments 樂器插件 + + Analysis Tools 分析工具 + + Don't know 未知 + 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. @@ -8020,6 +10306,7 @@ Double clicking any of the plugins will bring up information on the ports. + Type: 類型: @@ -8027,10 +10314,12 @@ Double clicking any of the plugins will bring up information on the ports. ladspaDescription + Plugins 插件 + Description 描述 @@ -8038,66 +10327,83 @@ Double clicking any of the plugins will bring up information on the ports. ladspaPortDialog + Ports + Name 名稱 + Rate + Direction 方向 + Type 類型 + Min < Default < Max 最小 < 默認 < 最大 + Logarithmic 對數 + SR Dependent + Audio 音頻 + Control 控制 + Input 輸入 + Output 輸出 + Toggled + Integer 整型 + Float 浮點 + + Yes @@ -8105,46 +10411,57 @@ Double clicking any of the plugins will bring up information on the ports. lb302Synth + VCF Cutoff Frequency + VCF Resonance + VCF Envelope Mod + VCF Envelope Decay + Distortion 失真 + Waveform 波形 + Slide Decay + Slide + Accent + Dead + 24dB/oct Filter @@ -8152,122 +10469,153 @@ Double clicking any of the plugins will bring up information on the ports. lb302SynthView + Cutoff Freq: + Resonance: 共鳴: + Env Mod: + Decay: 衰減: + 303-es-que, 24dB/octave, 3 pole filter + Slide Decay: + DIST: + Saw wave 鋸齒波 + Click here for a saw-wave. + Triangle wave 三角波 + Click here for a triangle-wave. 點擊這裡使用三角波。 + Square wave 方波 + Click here for a square-wave. 點擊這裡使用方形波。 + Rounded square wave + Click here for a square-wave with a rounded end. + Moog wave + Click here for a moog-like wave. + Sine wave 正弦波 + Click for a sine-wave. + + White noise wave 白噪音 + Click here for an exponential wave. + Click here for white-noise. + 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. @@ -8275,118 +10623,147 @@ Double clicking any of the plugins will bring up information on the ports. malletsInstrument + Hardness + Position + Vibrato Gain + Vibrato Freq + Stick Mix + Modulator + Crossfade + LFO Speed + LFO Depth + ADSR + Pressure + Motion + Speed + Bowed + Spread + Marimba + Vibraphone + Agogo + Wood1 + Reso + Wood2 + Beats + Two Fixed + Clump + Tubular Bells + Uniform Bar + Tuned Bar + Glass + Tibetan Bowl @@ -8394,149 +10771,186 @@ Double clicking any of the plugins will bring up information on the ports. malletsInstrumentView + Instrument + Spread + Spread: + + Missing files + 檔案遺失 + + + + Your Stk-installation seems to be incomplete. Please make sure the full Stk-package is installed! + + + + Hardness + Hardness: + Position + Position: + Vib Gain + Vib Gain: + Vib Freq + Vib Freq: + Stick Mix + Stick Mix: + Modulator + Modulator: + Crossfade + Crossfade: + LFO Speed + LFO Speed: + LFO Depth + LFO Depth: + ADSR + ADSR: + Pressure + Pressure: + Speed + Speed: - - Missing files - - - - Your Stk-installation seems to be incomplete. Please make sure the full Stk-package is installed! - - manageVSTEffectView + - VST parameter control - VST 參數控制 + VST Sync VST 同步 + Click here if you want to synchronize all parameters with VST plugin. 點擊這裏, 如果你想與 VST 插件同步所有參數。 + + Automated 自動 + Click here if you want to display automated parameters only. + Close 關閉 + Close VST effect knob-controller window. @@ -8544,30 +10958,39 @@ Double clicking any of the plugins will bring up information on the ports. manageVestigeInstrumentView + + - VST plugin control - VST插件控制 + VST Sync VST 同步 + Click here if you want to synchronize all parameters with VST plugin. 點擊這裏, 如果你想與 VST 插件同步所有參數。 + + Automated 自動 + Click here if you want to display automated parameters only. + Close 關閉 + Close VST plugin knob-controller window. @@ -8575,118 +10998,147 @@ Double clicking any of the plugins will bring up information on the ports. opl2instrument + Patch 音色 + Op 1 Attack + Op 1 Decay + Op 1 Sustain + Op 1 Release + Op 1 Level + Op 1 Level Scaling + Op 1 Frequency Multiple + Op 1 Feedback + 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 + Vibrato Depth + Tremolo Depth @@ -8694,18 +11146,26 @@ Double clicking any of the plugins will bring up information on the ports. opl2instrumentView + + Attack 打進聲 + + Decay 衰減 + + Release 釋放 + + Frequency multiplier @@ -8713,10 +11173,12 @@ Double clicking any of the plugins will bring up information on the ports. organicInstrument + Distortion 失真 + Volume 音量 @@ -8724,50 +11186,63 @@ Double clicking any of the plugins will bring up information on the ports. organicInstrumentView + Distortion: 失真: - Volume: - 音量: - - - Randomise - 隨機 - - - Osc %1 waveform: - - - - Osc %1 volume: - - - - Osc %1 panning: - - - - cents - 音分 cents - - + The distortion knob adds distortion to the output of the instrument. + + 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: + + + + + Osc %1 volume: + + + + + Osc %1 panning: + + + + Osc %1 stereo detuning + + cents + 音分 cents + + + Osc %1 harmonic: @@ -8775,265 +11250,351 @@ Double clicking any of the plugins will bring up information on the ports. papuInstrument + Sweep time + Sweep direction + Sweep RtShift amount + + Wave Pattern Duty + Channel 1 volume + + + Volume sweep direction + + + Length of each step in sweep + Channel 2 volume + Channel 3 volume + Channel 4 volume + + Shift Register width + + + + Right Output level 右聲道輸出電平 + Left Output level + Channel 1 to SO2 (Left) + Channel 2 to SO2 (Left) + Channel 3 to SO2 (Left) + Channel 4 to SO2 (Left) + Channel 1 to SO1 (Right) + Channel 2 to SO1 (Right) + Channel 3 to SO1 (Right) + Channel 4 to SO1 (Right) + Treble + Bass 低音 - - Shift Register width - - papuInstrumentView + Sweep Time: + Sweep Time - Sweep RtShift amount: - - - - Sweep RtShift amount - - - - Wave pattern duty: - - - - Wave Pattern Duty - - - - Square Channel 1 Volume: - - - - Length of each step in sweep: - - - - Length of each step in sweep - - - - 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 - - - + 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 + + + + + + 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 @@ -9041,34 +11602,42 @@ Double clicking any of the plugins will bring up information on the ports. patchesDialog + Qsynth: Channel Preset Qsynth: 通道預設 + Bank selector 音色選擇器 + Bank + Program selector + Patch 音色 + Name 名稱 + OK 確定 + Cancel 取消 @@ -9076,239 +11645,302 @@ Double clicking any of the plugins will bring up information on the ports. pluginBrowser + no description 沒有描述 - Incomplete monophonic imitation tb303 + + A native amplifier plugin + 原生增益插件 + + + + Simple sampler with various settings for using samples (e.g. drums) in an instrument-track + 簡單地在樂器欄使用採樣(比如鼓音源), 同時也提供多種設置 + + + + Boost your bass the fast and simple way - Plugin for freely manipulating stereo output + + Customizable wavetable synthesizer + 可自定製的波表合成器 + + + + An oversampling bitcrusher - Plugin for controlling knobs with sound peaks + + Carla Patchbay Instrument + Carla Patchbay 樂器 + + + + Carla Rack Instrument + Carla Rack 樂器 + + + + A 4-band Crossover Equalizer - Plugin for enhancing stereo separation of a stereo input file + + A native delay plugin + 原生的衰減插件 + + + + A Dual filter plugin + + plugin for processing dynamics in a flexible way + + + + + A native eq plugin + 原生的 EQ 插件 + + + + A native flanger plugin + 一個原生的 鑲邊 (Flanger) 插件 + + + + Player for GIG files + 播放 GIG 檔案的播放器 + + + + Filter for importing Hydrogen files into LMMS + 匯入 Hydrogen 專案檔至 LMMS 的解析器 + + + + Versatile drum synthesizer + 多功能鼓合成器 + + + List installed LADSPA plugins 列出已安裝的 LADSPA 插件 - GUS-compatible patch instrument - GUS 兼容音色的樂器 - - - Additive Synthesizer for organ-like sounds - - - - Tuneful things to bang on - - - - VST-host for using VST(i)-plugins within LMMS - LMMS的VST(i)插件宿主 - - - Vibrating string modeler - - - + plugin for using arbitrary LADSPA-effects inside LMMS. 在 LMMS 中使用任意 LADSPA 效果的插件。 - Filter for importing MIDI-files into LMMS + + Incomplete monophonic imitation tb303 + + Filter for exporting MIDI-files from LMMS + 從 LMMS 匯出 MIDI 檔的解析器 + + + + Filter for importing MIDI-files into LMMS + 匯入 MIDI 檔至 LMMS 的解析器 + + + + Monstrous 3-oscillator synth with modulation matrix + + + + + A multitap echo delay plugin + + + + + A NES-like synthesizer + 類似於 NES 的合成器 + + + + 2-operator FM Synth + + + + + Additive Synthesizer for organ-like sounds + + + + + Emulation of GameBoy (TM) APU + GameBoy (TM) APU 模擬器 + + + + GUS-compatible patch instrument + GUS 兼容音色的樂器 + + + + Plugin for controlling knobs with sound peaks + + + + + Reverb algorithm by Sean Costello + + + + + Player for SoundFont files + 播放 SoundFont 檔案的播放器 + + + + LMMS port of sfxr + sfxr 的 LMMS 移植版本 + + + Emulation of the MOS6581 and MOS8580 SID. This chip was used in the Commodore 64 computer. 模擬 MOS6581 和 MOS8580 SID 的模擬器 這些芯片曾在 Commodore 64 電腦上用過。 - Player for SoundFont files - 在工程中使用SoundFont - - - Emulation of GameBoy (TM) APU - GameBoy (TM) APU 模擬器 - - - Customizable wavetable synthesizer - 可自定製的波表合成器 - - - Embedded ZynAddSubFX - 內置的 ZynAddSubFX - - - 2-operator FM Synth - - - - Filter for importing Hydrogen files into LMMS - 導入 Hydrogen 工程文件到 LMMS 的解析器 - - - LMMS port of sfxr - sfxr 的 LMMS 移植版本 - - - Monstrous 3-oscillator synth with modulation matrix - - - - Three powerful oscillators you can modulate in several ways - - - - A native amplifier plugin - 原生增益插件 - - - Carla Rack Instrument - Carla Rack 樂器 - - - 4-oscillator modulatable wavetable synth - - - - plugin for waveshaping - - - - Boost your bass the fast and simple way - - - - Versatile drum synthesizer - 多功能鼓合成器 - - - Simple sampler with various settings for using samples (e.g. drums) in an instrument-track - 簡單地在樂器欄使用採樣(比如鼓音源), 同時也提供多種設置 - - - plugin for processing dynamics in a flexible way - - - - Carla Patchbay Instrument - Carla Patchbay 樂器 - - - plugin for using arbitrary VST effects inside LMMS. - - - + Graphical spectrum analyzer plugin 圖形頻譜分析器插件 - A NES-like synthesizer - 類似於 NES 的合成器 + + Plugin for enhancing stereo separation of a stereo input file + 用以增強雙聲道輸入檔的聲道分離插件 - A native delay plugin - 原生的衰減插件 - - - Player for GIG files - 播放 GIG 文件的播放器 - - - A multitap echo delay plugin + + Plugin for freely manipulating stereo output - A native flanger plugin - 一個原生的 鑲邊 (Flanger) 插件 - - - An oversampling bitcrusher + + Tuneful things to bang on - A native eq plugin - 原生的 EQ 插件 - - - A 4-band Crossover Equalizer + + Three powerful oscillators you can modulate in several ways - A Dual filter plugin + + VST-host for using VST(i)-plugins within LMMS + LMMS的VST(i)插件宿主 + + + + Vibrating string modeler - Filter for exporting MIDI-files from LMMS + + plugin for using arbitrary VST effects inside LMMS. + + + 4-oscillator modulatable wavetable synth + + + + + plugin for waveshaping + + + + + Embedded ZynAddSubFX + 內置的 ZynAddSubFX + sf2Instrument + Bank + Patch 音色 + 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。 @@ -9316,74 +11948,92 @@ This chip was used in the Commodore 64 computer. sf2InstrumentView + Open other SoundFont file 打開其他SoundFont文件 + Click here to open another SF2 file 點擊此處打開另一個SF2文件 + 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 - 打開SoundFont文件 + 開啟 SoundFont 檔案 + SoundFont2 Files (*.sf2) SoundFont2 Files (*.sf2) @@ -9391,6 +12041,7 @@ This chip was used in the Commodore 64 computer. sfxrInstrument + Wave Form 波形 @@ -9398,26 +12049,32 @@ This chip was used in the Commodore 64 computer. sidInstrument + Cutoff 切除 + Resonance 共鳴 + Filter type 過濾器類型 + Voice 3 off 聲音 3 關 + Volume 音量 + Chip model 芯片型號 @@ -9425,134 +12082,172 @@ This chip was used in the Commodore 64 computer. sidInstrumentView + Volume: 音量: + Resonance: 共鳴: + + Cutoff frequency: 頻譜刀頻率: + High-Pass filter 高通濾波器 + Band-Pass filter 帶通濾波器 + Low-Pass filter 低通濾波器 + Voice3 Off 聲音 3 關 + MOS6581 SID MOS6581 SID + MOS8580 SID MOS8580 SID + + Attack: 打進聲: + Attack rate determines how rapidly the output of Voice %1 rises from zero to peak amplitude. + + Decay: 衰減: + Decay rate determines how rapidly the output falls from the peak amplitude to the selected Sustain level. + Sustain: 振幅持平: + Output of Voice %1 will remain at the selected Sustain amplitude as long as the note is held. + + 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 噪音 + Sync 同步 + 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 測試 + Test, when set, resets and locks Oscillator %1 at zero until Test is turned off. @@ -9560,10 +12255,12 @@ This chip was used in the Commodore 64 computer. stereoEnhancerControlDialog + WIDE + Width: 寬度: @@ -9571,6 +12268,7 @@ This chip was used in the Commodore 64 computer. stereoEnhancerControls + Width 寬度 @@ -9578,18 +12276,22 @@ This chip was used in the Commodore 64 computer. stereoMatrixControlDialog + Left to Left Vol: 從左到左音量: + Left to Right Vol: 從左到右音量: + Right to Left Vol: 從右到左音量: + Right to Right Vol: 從右到右音量: @@ -9597,18 +12299,22 @@ This chip was used in the Commodore 64 computer. stereoMatrixControls + Left to Left 從左到左 + Left to Right 從左到右 + Right to Left 從右到左 + Right to Right 從右到右 @@ -9616,10 +12322,12 @@ This chip was used in the Commodore 64 computer. vestigeInstrument + Loading plugin 載入插件 + Please wait while loading VST-plugin... 請等待VST插件加載完成... @@ -9627,42 +12335,52 @@ This chip was used in the Commodore 64 computer. vibed + String %1 volume + String %1 stiffness + Pick %1 position + Pickup %1 position + Pan %1 聲相 %1 + Detune %1 去諧 %1 + Fuzziness %1 模糊度 %1 + Length %1 長度 %1 + Impulse %1 + Octave %1 八度音 %1 @@ -9670,90 +12388,112 @@ This chip was used in the Commodore 64 computer. vibedView + Volume: 音量: + The 'V' knob sets the volume of the selected string. + 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: + 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: + 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: + The Pan knob determines the location of the selected string in the stereo field. + 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: + 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: 長度: + 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 + 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 + 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. @@ -9764,6 +12504,7 @@ 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. @@ -9778,129 +12519,160 @@ The LED in the lower right corner of the waveform editor determines whether the + Enable waveform 啓用波形 + Click here to enable/disable waveform. 點擊這裏啓用/禁用波形。 + String + 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 正弦波 - Triangle wave - 三角波 - - - Saw wave - 鋸齒波 - - - Square wave - 方波 - - - White noise wave - 白噪音 - - - User defined wave - 用戶自定義波形 - - - Smooth - 平滑 - - - Click here to smooth waveform. - 點擊這裏平滑波形。 - - - Normalize - 標準化 - - - Click here to normalize waveform. - 點擊這裏標準化波形。 - - + Use a sine-wave for current oscillator. 爲當前振盪器使用正弦波。 + + Triangle wave + 三角波 + + + Use a triangle-wave for current oscillator. 爲當前振盪器使用三角波。 + + Saw wave + 鋸齒波 + + + Use a saw-wave for current oscillator. 爲當前振盪器使用鋸齒波。 + + Square wave + 方波 + + + Use a square-wave for current oscillator. 爲當前振盪器使用方波。 + + White noise wave + 白噪音 + + + Use white-noise for current oscillator. 爲當前振盪器使用白噪音。 + + User defined wave + 用戶自定義波形 + + + Use a user-defined waveform for current oscillator. 爲當前振盪器使用用戶自定波形。 + + + Smooth + 平滑 + + + + Click here to smooth waveform. + 點擊這裏平滑波形。 + + + + Normalize + 標準化 + + + + Click here to normalize waveform. + 點擊這裏標準化波形。 + voiceObject + Voice %1 pulse width + Voice %1 attack + Voice %1 decay + Voice %1 sustain + Voice %1 release + Voice %1 coarse detuning + Voice %1 wave shape 聲音 %1 波形形狀 + Voice %1 sync 聲音 %1 同步 + Voice %1 ring modulate + Voice %1 filtered + Voice %1 test 聲音 %1 測試 @@ -9908,58 +12680,72 @@ The LED in the lower right corner of the waveform editor determines whether the waveShaperControlDialog + INPUT 輸入 + Input gain: 輸入增益: + OUTPUT 輸出 + Output gain: 輸出增益: + Reset waveform 重置波形 + Click here to reset the wavegraph back to default + Smooth waveform 平滑波形 + Click here to apply smoothing to wavegraph 點擊這裏來使波形圖更爲平滑 + Increase graph amplitude by 1dB + Click here to increase wavegraph amplitude by 1dB + Decrease graph amplitude by 1dB + Click here to decrease wavegraph amplitude by 1dB + Clip input 輸入壓限 + Clip input signal to 0dB 將輸入信號限制到 0dB @@ -9967,10 +12753,12 @@ The LED in the lower right corner of the waveform editor determines whether the waveShaperControls + Input gain 輸入增益 + Output gain 輸出增益 From 37f0c3f33dbd7d4012e37e6b287890b432a9d65c Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Tue, 22 May 2018 15:45:35 +0300 Subject: [PATCH 320/445] SampleBuffer -> Use processingSampleRate. SampleBuffer was using baseSampleRate as the default samplerate instead of the actual processingSampleRate. --- include/SampleBuffer.h | 2 ++ src/core/SampleBuffer.cpp | 17 +++++++++++------ src/core/SamplePlayHandle.cpp | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/include/SampleBuffer.h b/include/SampleBuffer.h index 3acf2c10b..1e48a44f4 100644 --- a/include/SampleBuffer.h +++ b/include/SampleBuffer.h @@ -265,6 +265,8 @@ public slots: void sampleRateChanged(); private: + static sample_rate_t mixerSampleRate(); + void update( bool _keep_settings = false ); void convertIntToFloat ( int_sample_t * & _ibuf, f_cnt_t _frames, int _channels); diff --git a/src/core/SampleBuffer.cpp b/src/core/SampleBuffer.cpp index a364be4b8..7f0980fe9 100644 --- a/src/core/SampleBuffer.cpp +++ b/src/core/SampleBuffer.cpp @@ -73,7 +73,7 @@ SampleBuffer::SampleBuffer( const QString & _audio_file, m_amplification( 1.0f ), m_reversed( false ), m_frequency( BaseFreq ), - m_sampleRate( Engine::mixer()->baseSampleRate() ) + m_sampleRate( mixerSampleRate () ) { if( _is_base64_data == true ) { @@ -99,7 +99,7 @@ SampleBuffer::SampleBuffer( const sampleFrame * _data, const f_cnt_t _frames ) : m_amplification( 1.0f ), m_reversed( false ), m_frequency( BaseFreq ), - m_sampleRate( Engine::mixer()->baseSampleRate() ) + m_sampleRate( mixerSampleRate () ) { if( _frames > 0 ) { @@ -127,7 +127,7 @@ SampleBuffer::SampleBuffer( const f_cnt_t _frames ) : m_amplification( 1.0f ), m_reversed( false ), m_frequency( BaseFreq ), - m_sampleRate( Engine::mixer()->baseSampleRate() ) + m_sampleRate( mixerSampleRate () ) { if( _frames > 0 ) { @@ -155,6 +155,11 @@ void SampleBuffer::sampleRateChanged() update( true ); } +sample_rate_t SampleBuffer::mixerSampleRate() +{ + return Engine::mixer()->processingSampleRate(); +} + void SampleBuffer::update( bool _keep_settings ) { @@ -190,7 +195,7 @@ void SampleBuffer::update( bool _keep_settings ) int_sample_t * buf = NULL; sample_t * fbuf = NULL; ch_cnt_t channels = DEFAULT_CHANNELS; - sample_rate_t samplerate = Engine::mixer()->baseSampleRate(); + sample_rate_t samplerate = mixerSampleRate(); m_frames = 0; const QFileInfo fileInfo( file ); @@ -378,10 +383,10 @@ void SampleBuffer::normalizeSampleRate( const sample_rate_t _src_sr, bool _keep_settings ) { // do samplerate-conversion to our default-samplerate - if( _src_sr != Engine::mixer()->baseSampleRate() ) + if( _src_sr != mixerSampleRate() ) { SampleBuffer * resampled = resample( _src_sr, - Engine::mixer()->baseSampleRate() ); + mixerSampleRate() ); MM_FREE( m_data ); m_frames = resampled->frames(); m_data = MM_ALLOC( sampleFrame, m_frames ); diff --git a/src/core/SamplePlayHandle.cpp b/src/core/SamplePlayHandle.cpp index 7f383c68e..25faed4f0 100644 --- a/src/core/SamplePlayHandle.cpp +++ b/src/core/SamplePlayHandle.cpp @@ -153,7 +153,7 @@ bool SamplePlayHandle::isFromTrack( const Track * _track ) const f_cnt_t SamplePlayHandle::totalFrames() const { - return ( m_sampleBuffer->endFrame() - m_sampleBuffer->startFrame() ) * ( Engine::mixer()->processingSampleRate() / Engine::mixer()->baseSampleRate() ); + return ( m_sampleBuffer->endFrame() - m_sampleBuffer->startFrame() ) * ( Engine::mixer()->processingSampleRate() / m_sampleBuffer->sampleRate() ); } From 6d27f90271a4f968a6f50549a540ae33cb1af358 Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Sat, 16 Dec 2017 11:41:18 +0200 Subject: [PATCH 321/445] Bugfix - SampleTrack -> Load & Save: Fix recorded sample track not being played correctly after saving and loading a project due to sample rate not getting saved in the project file. --- src/tracks/SampleTrack.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index b45f442d1..ad1ae1b81 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -260,6 +260,8 @@ void SampleTCO::saveSettings( QDomDocument & _doc, QDomElement & _this ) QString s; _this.setAttribute( "data", m_sampleBuffer->toBase64( s ) ); } + + _this.setAttribute ("sample_rate", m_sampleBuffer->sampleRate()); // TODO: start- and end-frame } @@ -279,6 +281,10 @@ void SampleTCO::loadSettings( const QDomElement & _this ) } changeLength( _this.attribute( "len" ).toInt() ); setMuted( _this.attribute( "muted" ).toInt() ); + + if (_this.hasAttribute("sample_rate")) { + m_sampleBuffer->setSampleRate(_this.attribute("sample_rate").toInt()); + } } From 665e50395cfa4f57d83d6ffc77f62a3d607f6d53 Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Sat, 16 Dec 2017 11:47:08 +0200 Subject: [PATCH 322/445] Bugfix - SampleTrack -> Play: Fix sample track not being played in the right place when it not played from the begining. That has created a difference between the ticks and the metronome and the sample track. The cause of the problem was that the calculation of the frame to play was wrong: we had calculated `framesPerTick` according to the current engine's sample rate instead of the SampleBuffer's sample rate. --- include/Engine.h | 4 ++++ src/core/Engine.cpp | 6 ++++++ src/tracks/SampleTrack.cpp | 9 ++++++--- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/include/Engine.h b/include/Engine.h index 2f940dfbf..54ada4062 100644 --- a/include/Engine.h +++ b/include/Engine.h @@ -31,6 +31,7 @@ #include "export.h" +#include "lmms_basics.h" class BBTrackContainer; class DummyTrackContainer; @@ -100,6 +101,9 @@ public: { return s_framesPerTick; } + + static float framesPerTick(sample_rate_t sample_rate); + static void updateFramesPerTick(); static inline LmmsCore * inst() diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp index a53abbe5d..ee8aef708 100644 --- a/src/core/Engine.cpp +++ b/src/core/Engine.cpp @@ -103,6 +103,12 @@ void LmmsCore::destroy() delete ConfigManager::inst(); } +float LmmsCore::framesPerTick(sample_rate_t sample_rate) +{ + return sample_rate * 60.0f * 4 / + DefaultTicksPerTact / s_song->getTempo(); +} + diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index ad1ae1b81..23decb1f0 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -626,13 +626,16 @@ bool SampleTrack::play( const MidiTime & _start, const fpp_t _frames, { TrackContentObject * tco = getTCO( i ); SampleTCO * sTco = dynamic_cast( tco ); - float framesPerTick = Engine::framesPerTick(); + if( _start >= sTco->startPosition() && _start < sTco->endPosition() ) { if( sTco->isPlaying() == false ) { - f_cnt_t sampleStart = framesPerTick * ( _start - sTco->startPosition() ); - f_cnt_t tcoFrameLength = framesPerTick * ( sTco->endPosition() - sTco->startPosition() ); + auto bufferFramesPerTick = Engine::framesPerTick (sTco->sampleBuffer ()->sampleRate ()); + f_cnt_t sampleStart = bufferFramesPerTick * ( _start - sTco->startPosition() ); + + f_cnt_t tcoFrameLength = bufferFramesPerTick * ( sTco->endPosition() - sTco->startPosition() ); + f_cnt_t sampleBufferLength = sTco->sampleBuffer()->frames(); //if the Tco smaller than the sample length we play only until Tco end //else we play the sample to the end but nothing more From 359de2083e7b7f8c65a7c67ef7af8641fd5c7b0c Mon Sep 17 00:00:00 2001 From: liushuyu Date: Wed, 5 Jun 2019 19:29:07 -0600 Subject: [PATCH 323/445] i18n: update template strings --- data/locale/en.ts | 58 +++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/data/locale/en.ts b/data/locale/en.ts index 5a75e2e88..0a0af108f 100644 --- a/data/locale/en.ts +++ b/data/locale/en.ts @@ -7549,67 +7549,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) @@ -7617,32 +7617,32 @@ Reason: "%2" SampleTCOView - + double-click to select sample - + Delete (middle mousebutton) - + Cut - + Copy - + Paste - + Mute/unmute (<%1> + middle click) @@ -7650,18 +7650,18 @@ Reason: "%2" SampleTrack - + Volume - + Panning - - + + Sample track @@ -7669,32 +7669,32 @@ Reason: "%2" SampleTrackView - + Track volume - + Channel volume: - + VOL - + Panning - + Panning: - + PAN From c37228c7e3809ae550be2fc89148ba97efb9bfee Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Thu, 6 Jun 2019 19:33:10 +0900 Subject: [PATCH 324/445] Travis: fix macOS build due to the old default version of Node.js appdmg recently dropped support for Node.js < 8.5 --- .travis/osx..before_install.sh | 9 +++++++++ .travis/osx..install.sh | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.travis/osx..before_install.sh b/.travis/osx..before_install.sh index 75b692e97..f9481c496 100644 --- a/.travis/osx..before_install.sh +++ b/.travis/osx..before_install.sh @@ -1,3 +1,12 @@ #!/usr/bin/env bash brew update + +# appdmg doesn't work with old versions of Node.js +nvm install --lts + +# Avoid permission issues with npm and node-gyp +# https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally +mkdir ~/.npm-global +npm config set prefix '~/.npm-global' +export PATH=~/.npm-global/bin:$PATH diff --git a/.travis/osx..install.sh b/.travis/osx..install.sh index 3e49695f4..68d50790b 100644 --- a/.travis/osx..install.sh +++ b/.travis/osx..install.sh @@ -14,4 +14,4 @@ if [ -z "$QT5" ]; then brew install qt@4 fi -sudo npm install -g appdmg +npm install -g appdmg From 47d6388182e9105c0cf7e87d494dd2db593350c5 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Thu, 6 Jun 2019 20:24:06 +0900 Subject: [PATCH 325/445] MP3 export: initialize ID3 tag with id3tag_init Fixes wrongly set 'Blues' genre(ID 0) in exported mp3 files. --- src/core/audio/AudioFileMP3.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/audio/AudioFileMP3.cpp b/src/core/audio/AudioFileMP3.cpp index cce7ec8e4..a00cdf611 100644 --- a/src/core/audio/AudioFileMP3.cpp +++ b/src/core/audio/AudioFileMP3.cpp @@ -120,6 +120,7 @@ bool AudioFileMP3::initEncoder() lame_set_brate(m_lame, bitRate); // Add a comment + id3tag_init(m_lame); id3tag_set_comment(m_lame, "Created with LMMS"); return lame_init_params(m_lame) != -1; From d194c70391e66ada12396584d095c8679c9eb98b Mon Sep 17 00:00:00 2001 From: Rebecca DeField Date: Thu, 6 Jun 2019 18:18:49 -0700 Subject: [PATCH 326/445] updated splash (#5002) --- data/themes/default/splash.png | Bin 113394 -> 110016 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/data/themes/default/splash.png b/data/themes/default/splash.png index f95733e957786f53442b1acf5a82936055f69048..bca810bbada26dbb66ce10223719266dbb530298 100644 GIT binary patch literal 110016 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≻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
%$TKXeJ z8#RUy*8@UUREoUm@%v9(nlVXQL1lljwsd<7o49|BfZ_oL>2Fxmks;I5@fX~Src21JG3Z2kDQzSRlKMxP*+PmD{4b5KI4H!tKWhc|!!m!=sf z+sT@3JVC=jNc}^yM8TygXI7CAPh{vyHhDV}xlJTbomHeg#;ogsTXlF^$^xbCA&-aE z>x(w$acSqEEMtO5zCl(4J-Ir>9Z$P6BeW~Sm_&(I7&hh?{-t!PwcPCs<8K_=JKBR= zQd;h-msw>}j2VJ0%qFphFkfCy`U09hfQ)#=`{$>{R*Zwr)6XiTup*gQX_(T`3Ev>2 z%e|(LUx+(Uh+rLG9<24-y58vCTj`iO`HpiFXW=oQlLx}k!-k?@!&=K;|BguKr zYzEc;O!^DItQWdB_44tWmOf(R08(oTd!=0ZK(XGE)h&T%-Q4#;Hadyk26tu$(i{Wq+W^>lqfgG61? zHp*i%ZE>gc!=94^-7 zJspjd3IhBb*H+CsX1|(>46D_{UEL22?tNV-U2Mu1>7qXoP%XEITtwo3P={I@6CSO4 zpIdVw$XG&L2>M&Hd7V(Ij;}FFpvpRWFXGpt`~yh%HF4{6d4SYmeO(wmD3v#$HD(KGGVY+Pdz z1fJ1_E$=s6U(7es`jN|4Rk#1R5mp@~JLXr?-V}1KmoLi=-PKm=PZo~E07%R$^Y5sy z5%s*u({pp3*2Wmk!<|n^!qd;Wsc!4(5w?@RH^xnc4pp3MqY<;+g-?8pweMcW5BecT z<2KRXY%f8}95qRxXJ#3)xIwLa>@g|%H__X%UW0|Ky|YI+#2pk>F=+LBUn}H_Qxk&h zb2`iOcnaxx^a>08RmC=EZ;XE}TGjUv&m~&C3HmYCykb{-Or_K_p~po4mg)LuP*vr} zjoTRGyRI=?w-Y^yDhtD_F80UCgHr4?WANDl2)UtYRZaJd-=P{=PB}%w5Pj7>XiXJ9 zD4Z)hmfzw~zY!ObjTJKiB_p@LNg$FlCY$~#lHA4+X($(t|KarGNsRa=kp`v6`u4X! zN%KAB6wFXX#Tx(EE@$Ft(!=;RT#bEiv)}k~i9(`P$c&$%JNgUWvY0B)Eaci5sCGA+ zf^t()lG+J;E-V9D(4V*8nIjEdP-u2Yy|Ske*Opl%Hce>-pSa8hZqA<>z}CWcmZ~Io zD-t$CezCqh2U+~dXjcZ=0=)SLhOBm(#4GhZTCnec-;_ZWtd=uSbtb7Satd!b2+MA6 zdLGtWdB$DEaGeFy6?%A!J?PO;ruA6L_2rJAA9Gelw0_w65M}(EDQS zwbIa~q{5CB>Rg2*cc2Y_s{zFnV2q?z9edQ|Cq{9=ZWlp8ZcZriw825V5ugu~-YP|v zQWGHzlSV1ok1ky;C!~s^i0H6}+WurD)K3`HE~q2S>s07wpn0NM7eBn+@4ettDiXhU zJ4^q(C3){q9I!AFc2)Q~BiI~!?jt?9xdn-WhEzcnTPLVBbjN-Up-f^ z@5`oe)$@iAIuMxN_pM-)NV{;ooF*XL*qm1)0V}_XlYcv&v)nI{XNO3Z zcp6nxh&}INs}rY8j7*m21w=T1;`L3Xn?Y|U)qyTJ&{ku}TVXBwudBFYLW45OLHYVL zsNn8qzxWCjyXk35++}OREojg!`0r+8A3Q4sJ}$FFUZ4u{|FgogZWSS1F>w@Mb7GrZ zi9%gc_M3j~OJsxNfV&-LZ7KFAYM4;65!G1aA$AJltoZcb2;Hr?XQiGcKV#)ra4wM0 zVs-v@63rx?Hr5E!1oSEI=MzsqAw7G}-{_Vdu8^KhhwK)RNn|%vxBCgRhMT`Z_d1O4 zwuUmJE>A8>nxz69RUW)F`~R%W1Zx)eJcKPyY4vW$jY+|H&O7fy{6e#k>V@p5QNyBc zT};j11=PE9AUdhA=*MQPPs<@`g|r`mkV{qyqn3GDe(3w3aL9zwRt2c%uv9}&MGHS; z9jjaMU_Jk1n6Ilb3?Y>zn_3oP%tHfso0R1?m&ya(E7Xkzk3Z|70d5$&k*S;)y%ioZ z3tN#wc`&fL7H&koz%@_~)b5IJVP59`x-U7%GGlgEK#bzs^>n(I8Iy+Rm>`HTQGqd; z?EZXX-nKpxppVHO*L%HD;88*Z#cbPJAg8G^ej8P`ic=DsyaAopiqbSQH=a)<%1n&q zPsS~4x}^Pgl46qS4N+w>7JWz93bTqa@iaf6J7E4TN{QF^nxhto9pJ`u@!VsqUff>e zm-Y`?u%}RWCrIAeT+A$$rCO7c8s6R7(0jA$rTYA1x0mq+QXKdo@Y?hVdLI0*q41G2 z(a6idpLo8JvX+w{2Hd0_RisIduEt!p4|6bKQau9Idn?Rfr*K;iD(v;`;eu##c;&Tm zZNjpQiXlTH5qdyAr(6+Q10{L`?mQsczv)07+YRH-NJ5yES_3_HI&M#jn=gvgT5}4 z*tMiT*g$JrAfk^QOyTClt!Ja}@*1iYA*v_`_Pkc;vY_$L2FX}DkhI+2Y6Bz|Ai))y zdovQ1g+xbgRuv90FEA%I@v}Z&30af@R)Ob%p&(A=$4rz1h03r-tr|8notD9Jt8RvQ z9=sC=P5+a|V)!SW4y|C@1q{Q1c0@PX2Oz|9m_)j{$|1Q0 z^P1_1g%<@iJ9U@wvb@#a{KdfX1Er+rGnQ9}a@_?y;r-$SS6*g1(}P0m?1qm*t2&7m zuuM$-1IPtOmM21Q$M%IW-hM`9tsVJ5(tE_%okMR&$In7B_b9$Cw9s#B-qEEGFSgeQ^K0ErHFcJ+i@P1p?Ez*Jb zL40Hhhc+{aoQPD-YDHBWs0p$)X1eMmG*5SA0d(hzn4?x*&5=B)q=~;5F#Fdk#QkJM zdM1QY0*Yms<;=sv`gzg4{K_m9LlbDellnqj-JlG(;X8wZ@uVMfF}P=b3{{^?dhY&{ z34C&q4tx3b{HOBumQ0{Kvl$YqJF%7tjM;mMjCQn+^DrJA@ZaO2383w^CY2Sbv_LzE zkNysXSue786y!9iC%i}OPX>^T;zjq%NriOe?U%I+s#y|^AI}VCe2Jfb-kT&a)y&?| z&7{J)o<{5ENN_R!aUNnL^q%}qh>y&N@x#%9Kf10mSo^OM9d0`1DP^?8&*sVKye{B= zX7?b!VEYNSfoP-~hQ-FRjlQG-oExwez$~rdAUU*tIC5jYQ8LHfcU1P8(f@jp1hJL* zw5InqIf|>}Meg&*EoNSxeBgFFOcE&TqDf-f4H1Onkvi zxY|W&GL@*Yre!!z!ha`+hVztcb`|H{CrDhVS8()q{*|Fc;%A8U-nILMn}yEyl)JOxLWWbE29#67)lpkF zAbddDK^6%wYAEe@i=!LK^NK3EtIFiJKW~=ieI+>_j&iuad&EGEiQfaNc?Y&KLR21n z1>gRxPFKm^R$}2?;c&vSl}&LMZWDSPCBYna%(TWBnaGnxE~gv?lngn$>+B&)ne>+b zk{c-hq};ozhyEA_KjEZuHWmiKQR=DRzkxftROSDqsj4x+jn7; zjSqSGXhm8KKSPH6EJMUJ=r(%7d@=68pvYF)cL&8y7D+D=22t`bT9W)9qs+K{*OaiJe3p20K0cP~NDYOi12r6(5>1u99M z|6!%xk~ylB_rnlJMi%vfaEK@A{pGExo~hXA7aWvp>3hGhnvkW&W|1L zJ~^LaP;aqhw_w=w5oLt|uB+%VIYyR$0HW3(ELUc!UEmRFUY6X0Fc2~FY15vegpX0* z@OQ)~BqdtQJ`9JIhMsaj+^Z+2oKl6Li7Tf&#rWX*)0z0+hg5O=5`@p zSZ%w|Mz7&h$Bz+X>+XPNdt+&?=1Q>jmjkl$o1Yl8FJK4hAhkOc&}%e*s0x{d?@9T~ zQL>AS`-)E~pBa=#px&Zm5oULDBZR;Yu|iOM%b?1-)68}p2sABmhaXDr(p_UgTK~@H z8QgiUwNLf7`Ja|L_>toZxLR|sc@;2Gg^Z*Q2BE>h;)mAhe_YV^9{-d;Q*WbEKc>M{ zo|`0arUYi#+5f6?XCeKuZwP)C8FsrEK5rrkL6npKJ3v0f49V39h37!o+YsHg1 z({h82mOB3gV+r+#IYQ0uk%(` zo2A-4r)iHnOMm!5poD7h7%LkoDQPV(L`4kAQHj%%&7ZX z9eM2_`#4C0nSwH8`Wi(Q$@e$GNAN74rx|)BNtn6Gus!bv;KcNS^+=Hxe@7pVh+0y78Cbo*k7fy=fUEQz@&;_K^3L%}nD{H7i~~@Q_Xr{fUfj+C)Ns9Est`(+$XUEUgq%Ij8gyQzNVvn+|PkWbHl@fmM+TLlHvTGrxywy5h&}Gm4J0Vw)*Cx?80+|Z#QM&5qHeU!QMjuq7#bb8j)bg+ZQb0;J?CM; zG{mWJ&BqBXR^uoNehO%mdJGr~P)dt=*%=7EOU;&g_;KF4JhXtm#X6~r|hGx zeUON_F+fgy%Dkmh1wMMKy#rK@OXkGW%A6?@PK#TKjx25k=yPh%p^Abc3Np5rO$77Q zte%~%Pe~FCd5-cl9GLW}aUkdOw`TK91**n7d_gT&@x~RLX|Ha+*P}o@W^m}d{?z>0 zf{Lwe1n%0H->j$e1Wfr!|ErHVbAD^j)uhg}Us6AcFnfnGi#l}qA5AbiRf})hNK{4$ zG|OQ^2v9`TK+0!jpD{JbnU`e5NV9*~yq^j2fT1gKVEROw*CNgTz$zh&`&*>-RZe^z zWL1xY>3&Q(1s~;#XTd+XWCs+!ynq8lN7$*{d4w7qlAg<=5968sNyvTd{e4qqaU09J z6PXy6zW*ZxWAiR@>)(x(NdM{I6e)b#S_ylzS0yWpjka?JA>Jcz!_Ac-?wkli$XtNr zyTESX)e-1ArwPzGX*sBl-DA+rfYJahqs6h5GY@AnI(BriSMW0Q=>+{vT4d$Qt4{KX z{o4)bHtV)F0~F$DS|Mtrh$HoA|}AJ<>25p z2a$2<4yF6+Lu`wv@>(0{&l6juuQ>@=eq>{Hz5OB|)ddk&j#wGHq(ebrt-9b8;Nb6J z{C_}1bdUch88`FNmrKuH{)H$$@LVrm_a`KU!|sa%0dv2Z%&L#nTF+86*%P3m%fzZe z|L+oRT`;=y$G|9e4&0LV<({u!Ie%g&C1c})fZht-z26AoSHM{5cG){WTz6n$D09vQ zW*5Oh6NkDXx~xbF*5c=jDK$`Z!)n@Rg^RQm_^6k{Vs6fJTA2}6xH(&1`iUE&8)iUY zoTIhAPMo8?@;J8A8{6%rENWs!d#?|UQKS`k-N<17z;&^?t(Rj5nHQ|FBDLqfqIB5U z(-|7Xdl%&!e8NxqW~1pUv%UR z=j>={pBfpMjA)tg2l_X9* z5duEHP;NV=a9s<9DFC%ZM|{zAkItgc9JCE?yM!a^46e{L%t)+k@T$I4Ke3-%%d9&aWt8Q z+xoZN8XQ^rZXawqQDs52+bi!typ||C;`-(u3sH^I$6ZQd`7b-S_Y5|cGLPd^MZUk$ z&imktbcoaz4arx(=v-6XbLBB>NM(6q^hV;BsQ{qE^iobqmS%i}7EqOcZu$U})nLdP z4Xzlp;Zpynt)niA)8Kr{kZU<8=8ZP1Pa!C_S^-GU+Vof%psE_`JG8!CE;FiBD3j}E zaA*!h0f@ggOZB4F4`H&U?MB8KClYNB&NeQya5$IPyWKYpI3q}TdhH-{?>g~(Jll0e zfmjb&=fMY5uQ$6|5R0xPfxy$w+Tdhh#;DFb0KMCwyUab|J;IRgKSCgrWrV%`J(5#? zR&{cJYL4WPSQz0Oo`zg9h_+W4_SK8b%#nyavaJQ~GJB7dS>Gb?%QcbQxOm^~EzrM? zs?~b;Us{e3*7IGE($fM3Nb-JwdBU;dMKocC!h{um__eX;tlzEov@+#+Ak0$7M@@b2(c;^nW&vk5yqEzvZ z9DN_oLB`LXGyvR~78a|4R^v#0c9O^zNp`Jop-A4L-3-Ec_{b#f-}S4nvCQb%wGQGF zaZkPOAF3pG5KfAy*4&rfKVq`m>|@1Y6VI(%e)|px!)-RvkT(%-`_Fjj=ftwRvw3r% zbtiS63#Pq*!^h@8e)3{u|I7|${aCDY;$NojK)t9j;~aP4C>l)$$u~>8y}>U5?Kw@e zX8t!AVPBu9cC#{u=08r*Wfl$D)zQoH8Y=G9R7}JpQ}4Mtf$3iPsXjvw$&E~=!*@hj z0o_kj_np7?xj&NfIB6~N@zbNS7VeB#C+coS)9$$<4}9M7RYA$#Y|9F+XeX8FPs`=S zBg!wMJ8);cQ$zG4X37R$bH=`j8!LM3_G*x9_PYt|ydKaUesy*KQ2JZB-0yhNXGK+)ey%32}(EfqwKbJo5=!tWejx+kMGqqX35lN zPSexfWA|@upv*s3i+lpXEDTUV3*#SjMJhWu zXzA;1Uhc$ET!paqh+a;^fO`rOW8^l~H@p(i0!eJyT+Uyf7pI~I<@j$A06?3jc73EC z8+yvR=(CRlWc%`Q_N>LE&*4$Y?Rnvmf#&5eGf%*u{$y^<&GXa8u$i#K|2#QaZea&K z68EKiA87vbDyZzx(?_DX6qXp5SctP5&{1*AseIrfWY#Jv*B;9ed51J$`L&WXPW2$( z_ANF&Dj=`!!f@!`Z;AhBpWX8Aiz4P3*V&T8Z?c(C68twbkNW(r?Vs?iW6_WiC}6-Z zM(SF%?zFNEd3)?9?tIWsr)TQI{yJpNV7YxoN1Y~U4` z$A3rG*Sl%kCPf^+k==KB6b4^FoC4jF>rTQfZ#INY^>z}Nv+xgULsQ$7-gNAqe{>ir zafvCs`JFI@5r{`r(4wvMb%Je;>@501bT4k>8`N`>nnhGwLw&-Z4iLEBJ`DS6BpsKZ z*@Xfa&5P6=nPi%Zt`(z49awK&!=v~=^Qg4Vl!S0seKl!45Gf8^GI1s=GXS3>VO z-Fok|8ecY7Y|60!_+^Rx4`Y57UXNs^X9WQ_j3w!4am3r((1`tlU=`b?LWz4ZeM9Rh zDsGj4hmeaP7_-#7D0=i;HN>p%COITSlO5%r(+Sw2!)%=GiXw60CN&+7GG8 zW-N>}=fl!~oeT*Cf-#hvG_1brm+{cVODA=$E-w_d%-}1LxMbsx*I{8BBU|dwcLZ+U zJ7gf@3l>V;>1&jz!3F#(QA21Mt=fAbVdDQDYs$647Na1Zd+b^_or^|qJ*QCoUb1KV z;UQbF8%wa>Hxi9RH{1)*{cR02y+r z3)vh59OtV_68p`N3)Tb8=jKZFQAKObO%P>X-U2w_6R=?Wj z18&t@k^)kMJGZ|W>9(_#Pp2pq&o7gXDoG%impT#QnHZc?&BCcyMU+8GOtDncgzJ=b~hJF_C9ibtu9WvkWNW6_34 zbxbb6h5K3Ys*P2UfnEuB`e^cT1VcR=pz23ynYtt5w{ou|4>CZ;d{48?LTR%Bf5bUS zuIN&8N8syjV!J3cSSa?kr-S^>mq<+SNG?LaunitP)0~y7zU^>Kz21U9%g zAS%3)2*(^ASknFw|YT;I#EO2H0nwCB#!`|E*GH9G2eM)qXEY8TG!CCTEU4lF4fovdLC zuRzAxd&Sp}2Ors>UUM#ZS>EMV6z0}rBpFr|N!PU-2s9N}?^f@>Akcz+U2Ht?AwPC0 ze|hehh3t;LmLfhGH9+Ig$Ki(JODtGb+hk9h zphWjHV73C^qglb8%r;38zX6ZYFtLM<$nYY*3W7MtdqzCwwE|U{fUcXga$v_&Kcq z&j{;B>cwdbU&yy}ztE$-S@DZbgzJ9D?`)klcVL3U=YULcRFrCHWxhM)V%+$W*oA~@ z@3;vM&hfWk0Yk?JrS5`ZKjVc}kiytwGB9}kQ}SPr4ceJiHWH^ly)L-*3*U?BS>~)@ z5B{S!DZh@p7|9z8vXwct`1S>DU_!`a!#9n``PrN)*`AtqmUbJZz-TB{O^Lc|L@99a z(aLcT+*G^WM(#ODWDJ~n{Q4OZ;cnppBayiuFFtdnkfCSNpMQCnX+M8}jYX%P^IX8P z@GSuadLRIR{G*M6z2{u>GRGbB-b%>1i^cPI4Ic6RD+}otu|h87&g}z%%@9O1=c3HoASSq%WriyA(&9m3rfIv%(G%N&?|0;JfTsU-LXP zkBhqH!Gg{s8zOeEK=q}-qF`~0K{frHs~V^nSMPVJMT;YJftebP?fggsHdzE+!)agN zJb?fEq3?1j3CdrOTt&@H!+mwfs9p<|#bQNG;%$Wa|8&$^6ckDAO>q|X{J8b6oaz}? zbV`@PSsI(Wd&{n^iBHWWcXNCi$5BISqKjb?V7!(q$C-Mi5%rryh~nmuj# z5NU*$Gh$5Yuu}w_o|+W!NhVYp7FCXO;}P@v z7y}AbpMYl2acO1=b&YmQ+iF6iAe=cMZm&(A8N-cNc+#%LcCw0PUy!N*U7VZ3*v_#} z+!@P3o^#@TNjY+LAgLIz=vKMaz))kC&*;Y!)?~Ws#C5Xdt;kH@(akiX-p?(>@87e? z)d*f=3(cf(nT z{}#ne8&V*Y&}WQQk4+X-PiH)G5I7lW;DQ#`D{WqewBLpaBvXE{Eg<^Kcm(!Uk3o>r zedNKzV$5ykA;d$2EyWplOaLK?;a$-W|Cdx;KG`+vs#ejcB{FNgda6$-nq z*GlnjYD%O7(PN>1DqCR<-=)Svk^_Y6$Z?exu*ql8H`A}#epDk8(0!+TfO{W$yhqn{ z``}=Dmxp7~IlFQ2w_VbDw^Kysti8DBB|pq_F(ynj(2;Agn7BNa`U8Jv&a)IWK8fhl zLn)4KEp7U(Sk>EF&1K_yDq~>Ixd~_6RgP&k3Ae>bd&3UGK|(TKb^RpLNy;-{;gzSb ze3&t-x)5q^yYfEUrg^TG#h53|Jx``>GV4-gH7c{AQbi8DSGrFw#-|dYI%(m3lpc0? z!|9%9D3a2Am+rTDkrnnlfKnb4OfpkQC7^PuwJkkF!*=}%1pu&T|GG|DsZv+ZZ}98K z7L5qU}H9ZUB@ce(s9JAd9ZcF9E~G&D$?LE@^Nym)?K=AAM(AR_r1vsd(h{@ zj1=;!VE#&o!oL2SHs^3Cn73`PfQX@LT;GVpFu*ZWQ8R0ml{#p~t-x#fvM+h2W5{bU zBHY$cF12pF` zXv{oN!#KlUZqclRS&&t7)Qq) zjht$Ee|KJIEiV;&($&0@x9Aw;AN{pOT!1)@@C_ghTjMQ0c`U7Fr-YCD`nmbVWOngg z8}9sky>R3g48@qutJ(7xI8X2W+38~l$qbz`2C67ynr`;zk^y$@JdY<)UIIYNaVZi2 zz=n@K!1g?`&ZWARH(pJbL<<`}6mhS$m zRF3~6)=q}!Wajdxt4moAmk=5}AU*}q5HjiokH^~*g1$H2sR&u((WIb%uL+wBTtCDj z(>QCY3r*UGksPBnMQ&e67nsFHCm;jDE2zWJmKytV>zVBdSrN^rEfrtBCZYrQD7xci zqmY4$J*Ib23F!Ro-)B=cmk4k!DyJA)uu{U*~4QO$n5 z&zPs{eW2S4-HoBe?%2<|tWpkDME&~72>V(kR4#lVbp{>q#I#z(^OS|}64xxeAS`U) z)M81>#k|ei#r)VPdTs>q-)v>xE$ow5I~jw#eEqiZG+*eSG0!8fUa_khuX8sMQS$WN zy{dO7&07mHZp&;bSCe&av7d38j$*20j_@hma=LUH*sXgOMO;Y!JsB>)%6DCeDmY9S z@#xy)Ol2P+@EjrxVq4>KL%DaJuY`kggJFT4VZx#c-(sL>JRc=!Gq(hRSZBr9nn}s( zKiGf$!q9qyh^I=%gWo);{eFI1E8N^{(6Tf_D3JKM6q|#d9`WU?TEwN{SGE>H5#z%W zdpU8~9xtv-JnUn{Lim=l#eS1t!`v?$5q=wrwsg*ui{OXN{LO!_-TGj6$8^|!azwMN z4-{VuB5cFmi@Cg?rrg7h+!EE0DJ%otsQZ!(NnY%OFY;x2ch}BC9}YI5HA>!XT*#Qz z>*DUqj77F_eGhZ@>3iFquR|*aRaZCCI%T|?n{_gD@!mG0m&W=1)-nB*TaA4`dz4)S z_|UOh`(KuP4lC&3L);=_GoLYAowK zcaSwZ^H;C*iU16RXKjHE>(A+0i3c@`0^Z(d7_@+zjkjd%**nv@OOcTa7Sc?RjxXSc z55Jr~53+G}ku-U3$vBDlq`qU0G)3G$#BV+<@GfG^r>pWDVI#o5g~3|=f^UanKG6Uy zGiH7wBcqC<@Lj^Lm7m)~!mjQC;qP==F=g%b0Mt3G)OfC})S-VHs2~qRzh=e%5-54M zVaHhex@KOW`L*+pSj~<*y}2oO;LG&orfRQ04`; z41wp$^gYgn5D%;n0ConLh!S;e>gjzY^FW>)6h2~>I9t}8kdAX!6*7P#V4V2`2yic< z^+O;v*(9M<;Hy=sUoycj)5SlN6!&R@@=lyh+u0wr#CD$U*Y8x8c;4mO%4Mx$|Mw1$ zv&oM^mJE@=enmK8XGlX^C~*66UaT}!Cw#Sfl}$6i(b`VGo4>9?3xWS(1?m1v z95zRxJ`hQOucmnXNoz9i4PKfRRzXYG2b`qB0IreLjy0P!0G2oT5$4OMDQXo3=7(0@ zai>ZboRQ8}^DV;1pFJO+=tQ1wH)789pstuH1eE!rOQ|L6HoD0BX(I+PB|_f}C$!j@ zZ|%5rL&67MSq%_-V3I}Z;EYmk4W}lvhgYoQ_YggV-SN=DmkKQcr_n%CFWYuzGgZTi zG2(_`#_N79;DL^)+9Mh4a_CKo*xU0G*~j5_=x>7o+xM;!V)icop4+?z1IVU&I?||I zJsW>p?+ZSMx8c^h>jHt3t-};ce5h>|S8tu!N3Wh$S%8^eZ`aP&INU$NC+@>u5)k+< zs9)+=iyMo)@7FIy?ovDcY0>Yan4qlz|MHl^k?nq@7O9EGCB zUcez<8xqouZvQI3jJQ^PjtBux>fcqVf(v=_W`Z@&B056dm8$ z6ATwif&7km*CB`Ryb|iTnTbo)HcXKADH{~@wAm}BPyFAz+9w;$V4s=xLw@w)s5&xV zFN1wF^{UqnXg*6FCs$a%=~X$da^6lN+Rs>&Tkh_*N81rDT4BPZ56Gg*EYJr^{{shy zz29(u z*}q6gwiquD7$SWqj4!8X7(7An5gze{UneJUDv2VzO-V#0crh-zcU!9l10+A*ClhR( zMjP0nPwSMZI4&pd82e#!L>pjn78JMtekjz-wNfW`M5&}JB;qG>`LH=8H+j0&fy@mm zLMCzkImIq>d534?)jwPHykwn(hV6rb^tr7cgU>=(xr=5P!SiV>1;-0q#OyJ}Z|fiD zzRdYZN@#b<#wkic$pp;A%uHQ zZ`%f)SMBeV^!@t-x47K8pZm5RF8%fqWzt&$-@GB`MJCjH42KIP$bp@Wz)>^o64>|y z;b=K7tQpJqxO7jSsh*F@zlA=3;|`f%W|it*oHt~|`d)j36LSL1!>@D3c1AW!o2y-m z`itePq38{2FGhodXi9j)X%iSYv|K8OX)8W#=(i?-f&p*OW7#dSN<Y4WaJ63$Z?m<)UaUS-vo;;%1zw)42woVk@x0DddB~`%oInj*<`$`yY|Hb} z6x$ll6JC5Njeq|8tN3}5>cv-rlIv1cv?3+2KnzcZ;BB3Ht@PLKA}?e)OaRItyUhYW zVCX~L-(=+B%tww%M+g}`=pE#^|-s2J|8_>V|tgKy|hGB5DPm-|`BUN++Qv(&`E z&H%fiszILub16wOlc?;X!GY((bq$0GNK zvHN|Z&#H3Z(Sk)+xjC*13*5E|eG=oZRa=(L*|l3?Bsld)<5gss^`cHe*R;%nVUtyS z`)!f;Q^i**5>@uxtq8Ol4Rw(Xz>YDk(1r$M%?eY`*tc z=!^`no9D& zD^S6#lm~lwXb(wb?r&~SW@uf{INhOp87x*5>Ro5&I-wd;7`OLy5Xy6wGV&-n0zE(2 zB{;BB!hb@7Z^B-tl(IEKhgCzr%W8ijg7LOnuxT0*8*}l)TW4zg#s15LrKd@nr$p;#+EHZ@k++qb>#Ld6zN2vn z62xY~`mWM`%MW)(AVBBRfaJN_E9=I=7>&u*5E_I`B__^Wx^E)n(o3H6jIT-pcaGX{ zP_3d$*w?Cx-^f@)U`4DwC>QHoB>yT`?YN!%2_dU!O#%qt@=Y^V)tZh7eGA*su<$=m zfy*bj0rVb;I%Oz|EHGT6DrG+S@sB%^KQ8}y)GY_Fe~We^bO9$WliJ(3fM3V-gk2YE zSp=RU(D@kj&F>~B8%8HY&n@Il%pqka97vAVN44y*cw?Ma(t z6EkK{W(=2lZO8(W-u1%`!snEZaL3Kb0s`Vz+1^Wq>|jqCr=0NjT2$t-bmZX=vi(Yf z{}_$x;94rkc#S9G-NhL0qZF{fzRc7%$dy10xX1ejmPDKJ3w_$yg0J^L?uJaro}o}= zv`GqrgIgr>FRHBDGpEgoNpkcX__T`4K6{TXA>owPHto%8KPmypG#fqFyIYTgL5=;V zu&wStU-xPJ0>`%egc05gMYyV}c2BuQE7tc_$F~cs8B+7ia8(dkOr60+XcVA+)1}7x z3zw3XvPX9{U6G3TJmP>^$LCt!COgs~nDtJgTF3wMu44waEz1+$d*9Y-N;PI`{Be^n zXGvVe^_42z9iJE7_}PIm@qGDmPS+!Bb~7mD@^0|St>@zWXRF*fWTY8Pj4zT#nI`F& zc5+}Txb*_QfUZ^F4AvvyJK-C0Bz!bAU4Y1D*i;y7HNVLBXrwW0Jt3KjdU-F#yxKzD zcTVgp(I-PdXGFpn#D(Po1}&nKsO>Y7-j zFDpOgw2N%dAubn{wU+$F;Tl9#g`3@V)#(l^RfJn`=wXn<9%$2 zKCfCSM_Sn4NVK@UY|y&KGw(vP#rzR$kCZ?U5NWi%q_{RZ$|3a&LsS!KcqnD-GV1u{ zmJ0GO$Km;Rz-(5c%-b86H@$!8ZOX;>{w-F@%n@*ZQtRJZ(ZRUILG0fI+(y=&Z9;`U zPpzzimu1FZNMAe1N=Wao6CU$Uupb+%$D3$NakH0Z8NQj@b5Y;-zI5SgPKyu0qpE4r zE6ZgURpsuOHB))eMl&md-tPsu{jbyIOkM^c7qpJ6pYy!~YHXRouZlYT>d<9ddD5d; z$eA=gVv73R1FsUAKac=`^ac+}Qw8~}JidC)vi=6XD#yUqeD zpZ}{x8W%f?s}6*4O_C22WI0 zCMLBEpN;l6$}c^H%*gugT8r74v_R+si5;uUPaPfOmJR5VqnmX;U2*-~!lylUre8gl zzLfd+Jh9Q)v+>nh?}mn>@}$A?4TV27HF^Q^*9w9$1V=G`v+~5tvRNml%*>^p`A)ly zDv$gY2MnaVl3B$#@N^dwO^mORR#bVYMDRBW7(JdBjmD5EVQ+<6kHM$4-V09n9-D!E2vz2ciH9$ev_O$Qjfk1 zdaPxifoarEGnUVx8_8Lh<0;8I^foW0s(U9jtl}8fV`)$yuI?>-?^fVc6xX+u<=rM` zVkACNJDnA0O%V$sf@Kts(yis3I>w@u>LBhXNncx{KvfY*_sy#&thv!VqcxjkfFfpG z-PNu((V`t(4v-{7lp}t)Gh&?3b%b<38nP_@v6)#2wWde^y# z2A7LaS4=3A^*kz-A2H~zcr|BNo9|u1{2zY*k2`;6?Pb>Etstj;IkeN1vY3GyZ?8RE zwI*IwZX)+Kt}UKuz9N~pOf=mdC)9l{+POUD&|nDWR`LpqqV`bQzvrIr>upC-EK8z- zm;T#F7o5=34BQch$(t!n>19HyYPJPFU;WoP`wL}!E*mL!aV+-a81%zZJDw~Z)D(O~ z;R{P?wgxF?de$p1uDyonKaBIabI_23&J~m^mgR}ySJk_ieERQ7%70I0zUU!^^WkLh z9g9ni@q!Z#oShkULSS|{lb=g^Wok}vfP!{nRkz1Yv}1L6nR1>M3Zc8OC>{yCXX`MY z0OzWksgxn*5%N#j%Z+7(3ES8|`Mp(w#A26HmJjrtmdJ_#{miftKE#n?7uPPV?@>nr z<+;x}){SHDXdfBKy0Tc6K|{@$m&C1V0@rprLh0nKqK*s&^S^SMvN#}lJE)BJi4*}2 z_Q(=QwrRa2&n)Fnn`%yoKNjx>wZ1oSY-}cdtgSl4hJ3c;gc_p-j-lguq4$NR@TH`t z#v^Z_7UW?+tM{hOtK8s3AwsmKEcp}9$l;u}#S)gW&^5Y;chuzI`t~HC95G8ZzAO*K z(ADgF4$0VnP^ASz9U&Vt1WZisKwtTMn~v2J#kT{KR85h{`Kz}Lz}+ycYVU&?y7+Kf|k+^S|*YEB(K_tW?xAhR#^9}X8s0rn^ho~)HYz#VMEGKC{*e8WO%cY7tUqmbkI!fwF~Elc zL6lpt`+(R~2*oKeU$;U^lcRkq0hNHZxad)kDM3nlY

;BfunhK?jSyyWp+a_hH_Kq6S&_sAaR( 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 Y_vhyAWb~iGGfkYLUfeoW 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 W4ut+*1*Vt)0000 Date: Fri, 7 Jun 2019 18:28:11 +0200 Subject: [PATCH 327/445] Fixes #4996: Fix metadata when exporting multiple tracks (#5005) Co-Authored-By: Hyunjin Song --- include/Mixer.h | 4 ++++ src/core/Mixer.cpp | 46 +++++++++++++++++++++++++--------------------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/include/Mixer.h b/include/Mixer.h index 757a08d49..79fbf7db3 100644 --- a/include/Mixer.h +++ b/include/Mixer.h @@ -171,7 +171,10 @@ public: return m_audioDevStartFailed; } + //! Set new audio device. Old device will be deleted, + //! unless it's stored using storeAudioDevice void setAudioDevice( AudioDevice * _dev , bool startNow ); + //! See overloaded function void setAudioDevice( AudioDevice * _dev, const struct qualitySettings & _qs, bool _needs_fifo, @@ -396,6 +399,7 @@ private: bool m_isProcessing; // audio device stuff + void doSetAudioDevice( AudioDevice *_dev ); AudioDevice * m_audioDev; AudioDevice * m_oldAudioDev; QString m_audioDevName; diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index c87305641..ac1aa2564 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -575,21 +575,35 @@ void Mixer::changeQuality( const struct qualitySettings & _qs ) -void Mixer::setAudioDevice( AudioDevice * _dev, - bool startNow ) +void Mixer::doSetAudioDevice( AudioDevice * _dev ) { - stopProcessing(); + // TODO: Use shared_ptr here in the future. + // Currently, this is safe, because this is only called by + // ProjectRenderer, and after ProjectRenderer calls this function, + // it does not access the old device anymore. + if( m_audioDev != m_oldAudioDev ) {delete m_audioDev;} - if( _dev == NULL ) + if( _dev ) + { + m_audioDev = _dev; + } + else { printf( "param _dev == NULL in Mixer::setAudioDevice(...). " "Trying any working audio-device\n" ); m_audioDev = tryAudioDevices(); } - else - { - m_audioDev = _dev; - } +} + + + + +void Mixer::setAudioDevice( AudioDevice * _dev, + bool startNow ) +{ + stopProcessing(); + + doSetAudioDevice( _dev ); emit sampleRateChanged(); @@ -599,26 +613,16 @@ void Mixer::setAudioDevice( AudioDevice * _dev, -void Mixer::setAudioDevice( AudioDevice * _dev, +void Mixer::setAudioDevice(AudioDevice * _dev, const struct qualitySettings & _qs, bool _needs_fifo, - bool startNow ) + bool startNow) { - // don't delete the audio-device stopProcessing(); m_qualitySettings = _qs; - if( _dev == NULL ) - { - printf( "param _dev == NULL in Mixer::setAudioDevice(...). " - "Trying any working audio-device\n" ); - m_audioDev = tryAudioDevices(); - } - else - { - m_audioDev = _dev; - } + doSetAudioDevice( _dev ); emit qualitySettingsChanged(); emit sampleRateChanged(); From 457f2c67126bf070bb3fdd7fcb84514f0ba7a530 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Thu, 6 Jun 2019 19:40:42 +0200 Subject: [PATCH 328/445] Fix German translation * Fix "Export Tracks" * Add "Export MIDI" [ci skip] --- data/locale/de.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/data/locale/de.ts b/data/locale/de.ts index 16f3d2873..0c34877b0 100644 --- a/data/locale/de.ts +++ b/data/locale/de.ts @@ -3885,7 +3885,11 @@ Bitte besuchen Sie http://lmms.sf.net/wiki für Dokumentationen über LMMS. E&xport Tracks... - E&xport Tracks... + Tracks e&xportieren... + + + Export &MIDI... + &MIDI exportieren... Online Help From ca06b886f525c35e35326784fe59aee4f32bc8fa Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Sat, 8 Jun 2019 01:17:15 -0400 Subject: [PATCH 329/445] DMG rebranding (#5013) Rebrand macOS DMG background - Design and artwork courtesy @RebeccaDeField - Closes #4289 --- cmake/apple/dmg_branding.png | Bin 18099 -> 50759 bytes cmake/apple/dmg_branding@2x.png | Bin 0 -> 115793 bytes cmake/apple/package_apple.json.in | 6 +++--- 3 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 cmake/apple/dmg_branding@2x.png diff --git a/cmake/apple/dmg_branding.png b/cmake/apple/dmg_branding.png index c1469720775a5c39e1211a2413316da69500a18a..2c6481ecb71c888b6bba30412892d2c1bc23a21b 100644 GIT binary patch literal 50759 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 literal 18099 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 NMR`@ZA{hg}{|iOySpfh5 diff --git a/cmake/apple/dmg_branding@2x.png b/cmake/apple/dmg_branding@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7af39fecd471847c6d7bb272050eed151003f150 GIT binary patch literal 115793 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

&vY2oq4mDp~DO~sE{$uAiQAS7R+u3nQ{<8ynz=Z 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

;BfunhK?jSyyWp+a_hH_Kq6S&_sAaR( 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 Y_vhyAWb~iGGfkYLUfeoW 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 Date: Sun, 9 Jun 2019 20:28:34 +0900 Subject: [PATCH 331/445] Bump version to 1.2.0 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e186fa61c..057cfa281 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 "rc8") +SET(VERSION_STAGE "") SET(VERSION_BUILD "0") SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE}") IF(VERSION_STAGE) From 723a451ebcab717ebc4746a3481c71a87c9921a8 Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Sun, 9 Jun 2019 15:44:32 +0300 Subject: [PATCH 332/445] Add a save option to discard MIDI connections (#5021) * Song: add isSavingProject. * VersionedSaveDialog: Add support for a custom option dialog. * AutomatableModel: Support the discardMIDIConnections save option. * InstrumentTrack: Support the discardMIDIConnections save option. * SaveOptions: Show the save option dialog on "save as". --- include/Song.h | 19 +++++++++++++++++ include/VersionedSaveDialog.h | 10 +++++++++ src/core/AutomatableModel.cpp | 12 +++++++++-- src/core/Song.cpp | 13 +++++++++++- src/gui/MainWindow.cpp | 3 ++- src/gui/dialogs/VersionedSaveDialog.cpp | 28 +++++++++++++++++++++++-- src/tracks/InstrumentTrack.cpp | 9 +++++++- 7 files changed, 87 insertions(+), 7 deletions(-) diff --git a/include/Song.h b/include/Song.h index d88a59e2b..32ead7181 100644 --- a/include/Song.h +++ b/include/Song.h @@ -65,6 +65,17 @@ public: Mode_Count } ; + struct SaveOptions { + /** + * Should we discard MIDI ControllerConnections from project files? + */ + BoolModel discardMIDIConnections{false}; + + void setDefaultOptions() { + discardMIDIConnections.setValue(false); + } + }; + void clearErrors(); void collectError( const QString error ); bool hasErrors(); @@ -322,6 +333,11 @@ public: void exportProjectMidi(QString const & exportFileName) const; inline void setLoadOnLauch(bool value) { m_loadOnLaunch = value; } + SaveOptions &getSaveOptions() { + return m_saveOptions; + } + + bool isSavingProject() const; public slots: void playSong(); @@ -419,9 +435,12 @@ private: volatile bool m_playing; volatile bool m_paused; + bool m_savingProject; bool m_loadingProject; bool m_isCancelled; + SaveOptions m_saveOptions; + QStringList m_errors; PlayModes m_playMode; diff --git a/include/VersionedSaveDialog.h b/include/VersionedSaveDialog.h index 781c6b71c..2e30e9f09 100644 --- a/include/VersionedSaveDialog.h +++ b/include/VersionedSaveDialog.h @@ -29,15 +29,25 @@ #define VERSIONEDSAVEDIALOG_H #include "FileDialog.h" +#include "Song.h" class QLineEdit; +class LedCheckBox; +class SaveOptionsWidget : public QWidget { +public: + SaveOptionsWidget(Song::SaveOptions &saveOptions); + +private: + LedCheckBox *m_discardMIDIConnectionsCheckbox; +}; class VersionedSaveDialog : public FileDialog { Q_OBJECT public: explicit VersionedSaveDialog( QWidget *parent = 0, + QWidget *saveOptionsWidget = nullptr, const QString &caption = QString(), const QString &directory = QString(), const QString &filter = QString() ); diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index 1780da5e1..9b52ce8fe 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -31,6 +31,7 @@ #include "LocaleHelper.h" #include "Mixer.h" #include "ProjectJournal.h" +#include "Song.h" long AutomatableModel::s_periodCounter = 0; @@ -131,8 +132,15 @@ void AutomatableModel::saveSettings( QDomDocument& doc, QDomElement& element, co } } - if( m_controllerConnection && m_controllerConnection->getController()->type() - != Controller::DummyController ) + // Skip saving MIDI connections if we're saving project and + // the discardMIDIConnections option is true. + auto controllerType = m_controllerConnection + ? m_controllerConnection->getController()->type() + : Controller::DummyController; + bool skipMidiController = Engine::getSong()->isSavingProject() + && Engine::getSong()->getSaveOptions().discardMIDIConnections.value(); + if (m_controllerConnection && controllerType != Controller::DummyController + && !(skipMidiController && controllerType == Controller::MidiController)) { QDomElement controllerElement; diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 2809c61ad..336aa3df2 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -1212,6 +1212,7 @@ void Song::loadProject( const QString & fileName ) bool Song::saveProjectFile( const QString & filename ) { DataFile dataFile( DataFile::SongProject ); + m_savingProject = true; m_tempoModel.saveSettings( dataFile, dataFile.head(), "bpm" ); m_timeSigModel.saveSettings( dataFile, dataFile.head(), "timesig" ); @@ -1233,6 +1234,8 @@ bool Song::saveProjectFile( const QString & filename ) saveControllerStates( dataFile, dataFile.content() ); + m_savingProject = false; + return dataFile.writeFile( filename ); } @@ -1265,7 +1268,11 @@ bool Song::guiSaveProjectAs( const QString & _file_name ) m_oldFileName = m_fileName; setProjectFileName(_file_name); - if(!guiSaveProject()) + bool saveResult = guiSaveProject(); + // After saving as, restore default save options. + m_saveOptions.setDefaultOptions(); + + if(!saveResult) { // Saving failed. Restore old filenames. setProjectFileName(m_oldFileName); @@ -1434,3 +1441,7 @@ QString Song::errorSummary() return errors; } + +bool Song::isSavingProject() const { + return m_savingProject; +} diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 424c23d26..5d1dbf666 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -922,7 +922,8 @@ bool MainWindow::saveProject() bool MainWindow::saveProjectAs() { - VersionedSaveDialog sfd( this, tr( "Save Project" ), "", + auto optionsWidget = new SaveOptionsWidget(Engine::getSong()->getSaveOptions()); + VersionedSaveDialog sfd( this, optionsWidget, tr( "Save Project" ), "", tr( "LMMS Project" ) + " (*.mmpz *.mmp);;" + tr( "LMMS Project Template" ) + " (*.mpt)" ); QString f = Engine::getSong()->projectFileName(); diff --git a/src/gui/dialogs/VersionedSaveDialog.cpp b/src/gui/dialogs/VersionedSaveDialog.cpp index e2acff590..18993c23b 100644 --- a/src/gui/dialogs/VersionedSaveDialog.cpp +++ b/src/gui/dialogs/VersionedSaveDialog.cpp @@ -28,13 +28,15 @@ #include #include #include +#include +#include #include "VersionedSaveDialog.h" - - +#include "LedCheckbox.h" VersionedSaveDialog::VersionedSaveDialog( QWidget *parent, + QWidget *saveOptionsWidget, const QString &caption, const QString &directory, const QString &filter ) : @@ -63,6 +65,17 @@ VersionedSaveDialog::VersionedSaveDialog( QWidget *parent, hLayout->addWidget( minusButton ); layout->addLayout( hLayout, 2, 1 ); + if (saveOptionsWidget) { + auto groupBox = new QGroupBox(tr("Save Options")); + auto optionsLayout = new QGridLayout; + + optionsLayout->addWidget(saveOptionsWidget, 0, 0, Qt::AlignLeft); + + groupBox->setLayout(optionsLayout); + + layout->addWidget(groupBox, layout->rowCount() + 1, 0, 1, -1); + } + // Connect + and - buttons connect( plusButton, SIGNAL( clicked() ), this, SLOT( incrementVersion() )); connect( minusButton, SIGNAL( clicked() ), this, SLOT( decrementVersion() )); @@ -160,3 +173,14 @@ bool VersionedSaveDialog::fileExistsQuery( QString FileName, QString WindowTitle } return fileExists; } + +SaveOptionsWidget::SaveOptionsWidget(Song::SaveOptions &saveOptions) { + auto *layout = new QVBoxLayout(); + + m_discardMIDIConnectionsCheckbox = new LedCheckBox(nullptr); + m_discardMIDIConnectionsCheckbox->setText(tr("Discard MIDI connections")); + m_discardMIDIConnectionsCheckbox->setModel(&saveOptions.discardMIDIConnections); + layout->addWidget(m_discardMIDIConnectionsCheckbox); + + setLayout(layout); +} diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 6c95f3c9a..a7809a077 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -749,7 +749,14 @@ void InstrumentTrack::saveTrackSpecificSettings( QDomDocument& doc, QDomElement m_soundShaping.saveState( doc, thisElement ); m_noteStacking.saveState( doc, thisElement ); m_arpeggio.saveState( doc, thisElement ); - m_midiPort.saveState( doc, thisElement ); + + // Don't save midi port info if the user chose to. + if (Engine::getSong()->isSavingProject() + && !Engine::getSong()->getSaveOptions().discardMIDIConnections.value()) + { + m_midiPort.saveState( doc, thisElement ); + } + m_audioPort.effects()->saveState( doc, thisElement ); } From df79f8c1be78e6eb7382ba326119023748b5ac0c Mon Sep 17 00:00:00 2001 From: tresf Date: Tue, 11 Jun 2019 22:57:01 -0400 Subject: [PATCH 333/445] Enable dark title bar on macOS Closes #5031 --- cmake/apple/lmms.plist.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/apple/lmms.plist.in b/cmake/apple/lmms.plist.in index 10ff7a996..88fe0b0bf 100644 --- a/cmake/apple/lmms.plist.in +++ b/cmake/apple/lmms.plist.in @@ -147,5 +147,7 @@ NSApplication NSHighResolutionCapable True + NSRequiresAquaSystemAppearance + False From 4cb243b0ef03dd74df36739fa2206c16e4ed42d7 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 12 Jun 2019 17:38:53 +0900 Subject: [PATCH 334/445] Travis: drop unneeded prefix setting for npm --- .travis/osx..before_install.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.travis/osx..before_install.sh b/.travis/osx..before_install.sh index f9481c496..1c3b43298 100644 --- a/.travis/osx..before_install.sh +++ b/.travis/osx..before_install.sh @@ -4,9 +4,3 @@ brew update # appdmg doesn't work with old versions of Node.js nvm install --lts - -# Avoid permission issues with npm and node-gyp -# https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally -mkdir ~/.npm-global -npm config set prefix '~/.npm-global' -export PATH=~/.npm-global/bin:$PATH From f141ae68e02ffade3c15c6729e53602d0fa81b53 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Wed, 12 Jun 2019 17:42:24 +0900 Subject: [PATCH 335/445] Fix macOS builds --- .travis.yml | 3 +++ .travis/osx..before_install.sh | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 66563786f..b3cb8aa7c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,9 @@ matrix: depth: false - os: osx osx_image: xcode8.3 +before_install: + # appdmg doesn't work with old Node.js + - if [ "$TRAVIS_OS_NAME" = osx ]; then nvm install 10; fi install: ${TRAVIS_BUILD_DIR}/.travis/install.sh script: ${TRAVIS_BUILD_DIR}/.travis/script.sh after_script: ${TRAVIS_BUILD_DIR}/.travis/after_script.sh diff --git a/.travis/osx..before_install.sh b/.travis/osx..before_install.sh index 5e2853375..b59920a5e 100755 --- a/.travis/osx..before_install.sh +++ b/.travis/osx..before_install.sh @@ -3,6 +3,3 @@ set -e brew update - -# appdmg doesn't work with old versions of Node.js -nvm install --lts From 3ada5b8a126b529c94cbe0c01b60a11ecb08dec8 Mon Sep 17 00:00:00 2001 From: Olivier Humbert Date: Fri, 14 Jun 2019 21:07:14 +0200 Subject: [PATCH 336/445] Update .mailmap (#5037) --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 71b6697c8..896202c5a 100644 --- a/.mailmap +++ b/.mailmap @@ -29,3 +29,4 @@ grejppi Johannes Lorenz Johannes Lorenz <1042576+JohannesLorenz@users.noreply.github.com> Noah Brecht +Olivier Humbert From 499d425b4b9ebe0d1c13038cd9acf4777af94320 Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+DouglasDGI@users.noreply.github.com> Date: Fri, 14 Jun 2019 18:38:56 -0600 Subject: [PATCH 337/445] Increase Mixer fader falloff speed This also fixes a display bug that is present with large fader falloff speeds. --- src/gui/FxMixerView.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/gui/FxMixerView.cpp b/src/gui/FxMixerView.cpp index 90cd1dbf3..4ae2a630a 100644 --- a/src/gui/FxMixerView.cpp +++ b/src/gui/FxMixerView.cpp @@ -599,23 +599,25 @@ void FxMixerView::updateFaders() { const float opl = m_fxChannelViews[i]->m_fader->getPeak_L(); const float opr = m_fxChannelViews[i]->m_fader->getPeak_R(); - const float fallOff = 1.07; - if( m->effectChannel(i)->m_peakLeft > opl ) + const float fallOff = 1.25; + if( m->effectChannel(i)->m_peakLeft >= opl/fallOff ) { m_fxChannelViews[i]->m_fader->setPeak_L( m->effectChannel(i)->m_peakLeft ); - m->effectChannel(i)->m_peakLeft = 0; + // Set to -1 so later we'll know if this value has been refreshed yet. + m->effectChannel(i)->m_peakLeft = -1; } - else + else if( m->effectChannel(i)->m_peakLeft != -1 ) { m_fxChannelViews[i]->m_fader->setPeak_L( opl/fallOff ); } - if( m->effectChannel(i)->m_peakRight > opr ) + if( m->effectChannel(i)->m_peakRight >= opr/fallOff ) { m_fxChannelViews[i]->m_fader->setPeak_R( m->effectChannel(i)->m_peakRight ); - m->effectChannel(i)->m_peakRight = 0; + // Set to -1 so later we'll know if this value has been refreshed yet. + m->effectChannel(i)->m_peakRight = -1; } - else + else if( m->effectChannel(i)->m_peakRight != -1 ) { m_fxChannelViews[i]->m_fader->setPeak_R( opr/fallOff ); } From 5431cc7942dc9ad3a7923546a50a6951f0a942a0 Mon Sep 17 00:00:00 2001 From: Hussam al-Homsi Date: Sat, 15 Jun 2019 23:33:29 +0300 Subject: [PATCH 338/445] Replace tLimit() with qBound() and remove templates.h (#5040) * Replace tLimit() with qBound() * Remove templates.h --- include/BasicFilters.h | 1 - include/Controller.h | 3 +-- include/DspEffectLibrary.h | 1 - include/Knob.h | 1 - include/panning.h | 1 - include/templates.h | 39 ----------------------------- plugins/bit_invader/bit_invader.cpp | 1 - plugins/lb302/lb302.cpp | 1 - plugins/monstro/Monstro.cpp | 1 - plugins/nes/Nes.cpp | 1 - plugins/organic/organic.cpp | 1 - plugins/sfxr/sfxr.cpp | 1 - plugins/vibed/vibed.cpp | 1 - plugins/vibed/vibrating_string.cpp | 7 +++--- plugins/vst_base/VstPlugin.cpp | 1 - plugins/watsyn/Watsyn.cpp | 1 - src/core/AutomatableModel.cpp | 2 +- src/core/SampleBuffer.cpp | 2 +- src/core/audio/AudioAlsa.cpp | 6 ++--- src/core/audio/AudioJack.cpp | 9 +++---- src/core/audio/AudioOss.cpp | 6 ++--- src/core/audio/AudioPortAudio.cpp | 7 +++--- src/core/audio/AudioPulseAudio.cpp | 6 ++--- src/core/audio/AudioSndio.cpp | 10 ++++---- src/core/audio/AudioSoundIo.cpp | 8 +++--- src/gui/PianoView.cpp | 2 +- src/gui/PluginBrowser.cpp | 3 +-- src/gui/editors/PianoRoll.cpp | 20 ++++++++------- src/tracks/InstrumentTrack.cpp | 2 +- 29 files changed, 45 insertions(+), 100 deletions(-) delete mode 100644 include/templates.h diff --git a/include/BasicFilters.h b/include/BasicFilters.h index 684596c4d..c3a76d36e 100644 --- a/include/BasicFilters.h +++ b/include/BasicFilters.h @@ -39,7 +39,6 @@ #include #include "lmms_basics.h" -#include "templates.h" #include "lmms_constants.h" #include "interpolation.h" #include "MemoryManager.h" diff --git a/include/Controller.h b/include/Controller.h index d4fb94731..f1e71ad8f 100644 --- a/include/Controller.h +++ b/include/Controller.h @@ -31,7 +31,6 @@ #include "Engine.h" #include "Model.h" #include "JournallingObject.h" -#include "templates.h" #include "ValueBuffer.h" class ControllerDialog; @@ -112,7 +111,7 @@ public: inline static float fittedValue( float _val ) { - return tLimit( _val, 0.0f, 1.0f ); + return qBound( 0.0f, _val, 1.0f ); } static long runningPeriods() diff --git a/include/DspEffectLibrary.h b/include/DspEffectLibrary.h index 76296da0b..bf175df6d 100644 --- a/include/DspEffectLibrary.h +++ b/include/DspEffectLibrary.h @@ -27,7 +27,6 @@ #define DSP_EFFECT_LIBRARY_H #include "lmms_math.h" -#include "templates.h" #include "lmms_constants.h" #include "lmms_basics.h" diff --git a/include/Knob.h b/include/Knob.h index 245963ce2..b8d460f45 100644 --- a/include/Knob.h +++ b/include/Knob.h @@ -30,7 +30,6 @@ #include #include "AutomatableModelView.h" -#include "templates.h" class QPixmap; diff --git a/include/panning.h b/include/panning.h index 5f10433ce..8668ddf88 100644 --- a/include/panning.h +++ b/include/panning.h @@ -28,7 +28,6 @@ #include "lmms_basics.h" #include "volume.h" -#include "templates.h" #include "panning_constants.h" #include "Midi.h" diff --git a/include/templates.h b/include/templates.h deleted file mode 100644 index 50a14a6b8..000000000 --- a/include/templates.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * templates.h - miscellanous templates and algorithms - * - * Copyright (c) 2004-2008 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 TEMPLATES_H -#define TEMPLATES_H - -#include - - -template -inline T tLimit( const T x, const T x1, const T x2 ) -{ - return qBound( x1, x, x2 ); -} - - -#endif diff --git a/plugins/bit_invader/bit_invader.cpp b/plugins/bit_invader/bit_invader.cpp index 9b0b63635..0d62bc2e6 100644 --- a/plugins/bit_invader/bit_invader.cpp +++ b/plugins/bit_invader/bit_invader.cpp @@ -36,7 +36,6 @@ #include "NotePlayHandle.h" #include "Oscillator.h" #include "PixmapButton.h" -#include "templates.h" #include "ToolTip.h" #include "Song.h" #include "interpolation.h" diff --git a/plugins/lb302/lb302.cpp b/plugins/lb302/lb302.cpp index e556e42bf..91e811276 100644 --- a/plugins/lb302/lb302.cpp +++ b/plugins/lb302/lb302.cpp @@ -41,7 +41,6 @@ #include "NotePlayHandle.h" #include "Oscillator.h" #include "PixmapButton.h" -#include "templates.h" #include "ToolTip.h" #include "BandLimitedWave.h" diff --git a/plugins/monstro/Monstro.cpp b/plugins/monstro/Monstro.cpp index fb089aa0c..4ea679347 100644 --- a/plugins/monstro/Monstro.cpp +++ b/plugins/monstro/Monstro.cpp @@ -28,7 +28,6 @@ #include "Monstro.h" #include "Engine.h" #include "InstrumentTrack.h" -#include "templates.h" #include "gui_templates.h" #include "ToolTip.h" #include "Song.h" diff --git a/plugins/nes/Nes.cpp b/plugins/nes/Nes.cpp index c44f01bad..b973f4356 100644 --- a/plugins/nes/Nes.cpp +++ b/plugins/nes/Nes.cpp @@ -27,7 +27,6 @@ #include "Nes.h" #include "Engine.h" #include "InstrumentTrack.h" -#include "templates.h" #include "ToolTip.h" #include "Song.h" #include "lmms_math.h" diff --git a/plugins/organic/organic.cpp b/plugins/organic/organic.cpp index 63aee0dc6..de5f08ff7 100644 --- a/plugins/organic/organic.cpp +++ b/plugins/organic/organic.cpp @@ -37,7 +37,6 @@ #include "NotePlayHandle.h" #include "Oscillator.h" #include "PixmapButton.h" -#include "templates.h" #include "ToolTip.h" #include "embed.h" diff --git a/plugins/sfxr/sfxr.cpp b/plugins/sfxr/sfxr.cpp index 2718d66d7..cdace1a30 100644 --- a/plugins/sfxr/sfxr.cpp +++ b/plugins/sfxr/sfxr.cpp @@ -45,7 +45,6 @@ float frnd(float range) #include "Knob.h" #include "NotePlayHandle.h" #include "PixmapButton.h" -#include "templates.h" #include "ToolTip.h" #include "Song.h" #include "MidiEvent.h" diff --git a/plugins/vibed/vibed.cpp b/plugins/vibed/vibed.cpp index bde5c8917..94f640ff3 100644 --- a/plugins/vibed/vibed.cpp +++ b/plugins/vibed/vibed.cpp @@ -35,7 +35,6 @@ #include "CaptionMenu.h" #include "Oscillator.h" #include "string_container.h" -#include "templates.h" #include "volume.h" #include "Song.h" diff --git a/plugins/vibed/vibrating_string.cpp b/plugins/vibed/vibrating_string.cpp index c32202717..14a666bbd 100644 --- a/plugins/vibed/vibrating_string.cpp +++ b/plugins/vibed/vibrating_string.cpp @@ -24,7 +24,6 @@ #include #include "vibrating_string.h" -#include "templates.h" #include "interpolation.h" #include "Mixer.h" #include "Engine.h" @@ -145,9 +144,9 @@ void vibratingString::resample( float *_src, f_cnt_t _src_frames, _dst_frames; const float frac_pos = src_frame_float - static_cast( src_frame_float ); - const f_cnt_t src_frame = tLimit( - static_cast( src_frame_float ), - 1, _src_frames - 3 ); + const f_cnt_t src_frame = qBound( + 1, static_cast( src_frame_float ), + _src_frames - 3 ); m_impulse[frame] = cubicInterpolate( _src[src_frame - 1], _src[src_frame + 0], diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index f224f092d..8d86f576f 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -60,7 +60,6 @@ #include "MainWindow.h" #include "Mixer.h" #include "Song.h" -#include "templates.h" #include "FileDialog.h" #ifdef LMMS_BUILD_LINUX diff --git a/plugins/watsyn/Watsyn.cpp b/plugins/watsyn/Watsyn.cpp index 2787e39b7..5c47b7a7a 100644 --- a/plugins/watsyn/Watsyn.cpp +++ b/plugins/watsyn/Watsyn.cpp @@ -28,7 +28,6 @@ #include "base64.h" #include "Engine.h" #include "InstrumentTrack.h" -#include "templates.h" #include "ToolTip.h" #include "Song.h" #include "lmms_math.h" diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index 9b52ce8fe..6055598f7 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -439,7 +439,7 @@ void AutomatableModel::setStep( const float step ) float AutomatableModel::fittedValue( float value ) const { - value = tLimit( value, m_minValue, m_maxValue ); + value = qBound( m_minValue, value, m_maxValue ); if( m_step != 0 && m_hasStrictStepSize ) { diff --git a/src/core/SampleBuffer.cpp b/src/core/SampleBuffer.cpp index 47f432a8f..779592529 100644 --- a/src/core/SampleBuffer.cpp +++ b/src/core/SampleBuffer.cpp @@ -936,7 +936,7 @@ void SampleBuffer::visualize( QPainter & _p, const QRect & _dr, const float y_space = h*0.5f; const int nb_frames = focus_on_range ? _to_frame - _from_frame : m_frames; - const int fpp = tLimit( nb_frames / w, 1, 20 ); + const int fpp = qBound( 1, nb_frames / w, 20 ); QPointF * l = new QPointF[nb_frames / fpp + 1]; QPointF * r = new QPointF[nb_frames / fpp + 1]; int n = 0; diff --git a/src/core/audio/AudioAlsa.cpp b/src/core/audio/AudioAlsa.cpp index 45abe6776..b86675706 100644 --- a/src/core/audio/AudioAlsa.cpp +++ b/src/core/audio/AudioAlsa.cpp @@ -37,10 +37,10 @@ AudioAlsa::AudioAlsa( bool & _success_ful, Mixer* _mixer ) : - AudioDevice( tLimit( + AudioDevice( qBound( + DEFAULT_CHANNELS, ConfigManager::inst()->value( "audioalsa", "channels" ).toInt(), - DEFAULT_CHANNELS, SURROUND_CHANNELS ), - _mixer ), + SURROUND_CHANNELS ), _mixer ), m_handle( NULL ), m_hwParams( NULL ), m_swParams( NULL ), diff --git a/src/core/audio/AudioJack.cpp b/src/core/audio/AudioJack.cpp index bca41356b..e149f5cbd 100644 --- a/src/core/audio/AudioJack.cpp +++ b/src/core/audio/AudioJack.cpp @@ -32,7 +32,6 @@ #include "Engine.h" #include "GuiApplication.h" -#include "templates.h" #include "gui_templates.h" #include "ConfigManager.h" #include "LcdSpinBox.h" @@ -44,10 +43,10 @@ AudioJack::AudioJack( bool & _success_ful, Mixer* _mixer ) : - AudioDevice( tLimit( ConfigManager::inst()->value( - "audiojack", "channels" ).toInt(), - DEFAULT_CHANNELS, SURROUND_CHANNELS ), - _mixer ), + AudioDevice( qBound( + DEFAULT_CHANNELS, + ConfigManager::inst()->value( "audiojack", "channels" ).toInt(), + SURROUND_CHANNELS ), _mixer ), m_client( NULL ), m_active( false ), m_midiClient( NULL ), diff --git a/src/core/audio/AudioOss.cpp b/src/core/audio/AudioOss.cpp index 21f495dca..c9ad01801 100644 --- a/src/core/audio/AudioOss.cpp +++ b/src/core/audio/AudioOss.cpp @@ -69,10 +69,10 @@ AudioOss::AudioOss( bool & _success_ful, Mixer* _mixer ) : - AudioDevice( tLimit( + AudioDevice( qBound( + DEFAULT_CHANNELS, ConfigManager::inst()->value( "audiooss", "channels" ).toInt(), - DEFAULT_CHANNELS, SURROUND_CHANNELS ), - _mixer ), + SURROUND_CHANNELS ), _mixer ), m_convertEndian( false ) { _success_ful = false; diff --git a/src/core/audio/AudioPortAudio.cpp b/src/core/audio/AudioPortAudio.cpp index 5566d7a36..61dca4a22 100644 --- a/src/core/audio/AudioPortAudio.cpp +++ b/src/core/audio/AudioPortAudio.cpp @@ -48,16 +48,15 @@ void AudioPortAudioSetupUtil::updateChannels() #include "Engine.h" #include "ConfigManager.h" #include "gui_templates.h" -#include "templates.h" #include "ComboBox.h" #include "Mixer.h" AudioPortAudio::AudioPortAudio( bool & _success_ful, Mixer * _mixer ) : - AudioDevice( tLimit( + AudioDevice( qBound( + DEFAULT_CHANNELS, ConfigManager::inst()->value( "audioportaudio", "channels" ).toInt(), - DEFAULT_CHANNELS, SURROUND_CHANNELS ), - _mixer ), + SURROUND_CHANNELS ), _mixer ), m_paStream( NULL ), m_wasPAInitError( false ), m_outBuf( new surroundSampleFrame[mixer()->framesPerPeriod()] ), diff --git a/src/core/audio/AudioPulseAudio.cpp b/src/core/audio/AudioPulseAudio.cpp index 20a106ed1..050086c60 100644 --- a/src/core/audio/AudioPulseAudio.cpp +++ b/src/core/audio/AudioPulseAudio.cpp @@ -45,10 +45,10 @@ static void stream_write_callback(pa_stream *s, size_t length, void *userdata) AudioPulseAudio::AudioPulseAudio( bool & _success_ful, Mixer* _mixer ) : - AudioDevice( tLimit( + AudioDevice( qBound( + DEFAULT_CHANNELS, ConfigManager::inst()->value( "audiopa", "channels" ).toInt(), - DEFAULT_CHANNELS, SURROUND_CHANNELS ), - _mixer ), + SURROUND_CHANNELS ), _mixer ), m_s( NULL ), m_quit( false ), m_convertEndian( false ) diff --git a/src/core/audio/AudioSndio.cpp b/src/core/audio/AudioSndio.cpp index 3145eb218..853d734d5 100644 --- a/src/core/audio/AudioSndio.cpp +++ b/src/core/audio/AudioSndio.cpp @@ -36,7 +36,6 @@ #include "Mixer.h" #include "Engine.h" #include "gui_templates.h" -#include "templates.h" #ifdef LMMS_HAVE_UNISTD_H #include @@ -50,10 +49,11 @@ AudioSndio::AudioSndio(bool & _success_ful, Mixer * _mixer) : - AudioDevice( tLimit( - ConfigManager::inst()->value( "audiosndio", "channels" ).toInt(), - DEFAULT_CHANNELS, SURROUND_CHANNELS ), _mixer ), - m_convertEndian ( false ) + AudioDevice( qBound( + DEFAULT_CHANNELS, + ConfigManager::inst()->value( "audiosndio", "channels" ).toInt(), + SURROUND_CHANNELS ), _mixer ), + m_convertEndian ( false ) { _success_ful = false; diff --git a/src/core/audio/AudioSoundIo.cpp b/src/core/audio/AudioSoundIo.cpp index f6c624127..cde14a1c5 100644 --- a/src/core/audio/AudioSoundIo.cpp +++ b/src/core/audio/AudioSoundIo.cpp @@ -33,14 +33,14 @@ #include "debug.h" #include "ConfigManager.h" #include "gui_templates.h" -#include "templates.h" #include "ComboBox.h" #include "Mixer.h" AudioSoundIo::AudioSoundIo( bool & outSuccessful, Mixer * _mixer ) : - AudioDevice( tLimit( - ConfigManager::inst()->value( "audiosoundio", "channels" ).toInt(), DEFAULT_CHANNELS, SURROUND_CHANNELS ), - _mixer ) + AudioDevice( qBound( + DEFAULT_CHANNELS, + ConfigManager::inst()->value( "audiosoundio", "channels" ).toInt(), + SURROUND_CHANNELS ), _mixer ) { outSuccessful = false; m_soundio = NULL; diff --git a/src/gui/PianoView.cpp b/src/gui/PianoView.cpp index 6e8464dd4..c1be922c6 100644 --- a/src/gui/PianoView.cpp +++ b/src/gui/PianoView.cpp @@ -355,7 +355,7 @@ int PianoView::getKeyFromMouse( const QPoint & _p ) const } // some range-checking-stuff - return tLimit( key_num, 0, NumKeys - 1 ); + return qBound( 0, key_num, NumKeys - 1 ); } diff --git a/src/gui/PluginBrowser.cpp b/src/gui/PluginBrowser.cpp index 1e73b7cdc..671b58381 100644 --- a/src/gui/PluginBrowser.cpp +++ b/src/gui/PluginBrowser.cpp @@ -34,7 +34,6 @@ #include "embed.h" #include "Engine.h" -#include "templates.h" #include "gui_templates.h" #include "StringPairDrag.h" #include "PluginFactory.h" @@ -231,7 +230,7 @@ void PluginDescWidget::paintEvent( QPaintEvent * ) style()->drawPrimitive( QStyle::PE_Widget, &o, &p, this ); // Draw the rest - const int s = 16 + ( 32 * ( tLimit( height(), 24, 60 ) - 24 ) ) / + const int s = 16 + ( 32 * ( qBound( 24, height(), 60 ) - 24 ) ) / ( 60 - 24 ); const QSize logo_size( s, s ); QPixmap logo = m_logo.scaled( logo_size, Qt::KeepAspectRatio, diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 440da2595..5edc5d47c 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -709,7 +709,7 @@ void PianoRoll::setCurrentPattern( Pattern* newPattern ) { central_key = central_key / total_notes - ( KeysPerOctave * NumOctaves - m_totalKeysToScroll ) / 2; - m_startKey = tLimit( central_key, 0, NumOctaves * KeysPerOctave ); + m_startKey = qBound( 0, central_key, NumOctaves * KeysPerOctave ); } // resizeEvent() does the rest for us (scrolling, range-checking @@ -2215,9 +2215,9 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) else if( m_action == ActionResizeNoteEditArea ) { // change m_notesEditHeight and then repaint - m_notesEditHeight = tLimit( - m_oldNotesEditHeight - ( me->y() - m_moveStartY ), + m_notesEditHeight = qBound( NOTE_EDIT_MIN_HEIGHT, + m_oldNotesEditHeight - ( me->y() - m_moveStartY ), height() - PR_TOP_MARGIN - NOTE_EDIT_RESIZE_BAR - PR_BOTTOM_MARGIN - KEY_AREA_MIN_HEIGHT ); @@ -2299,16 +2299,18 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) if( me->buttons() & Qt::LeftButton ) { - vol = tLimit( MinVolume + + vol = qBound( MinVolume, + MinVolume + ( ( (float)noteEditBottom() ) - ( (float)me->y() ) ) / ( (float)( noteEditBottom() - noteEditTop() ) ) * ( MaxVolume - MinVolume ), - MinVolume, MaxVolume ); - pan = tLimit( PanningLeft + + MaxVolume ); + pan = qBound( PanningLeft, + PanningLeft + ( (float)( noteEditBottom() - me->y() ) ) / ( (float)( noteEditBottom() - noteEditTop() ) ) * ( (float)( PanningRight - PanningLeft ) ), - PanningLeft, PanningRight); + PanningRight); } if( m_noteEditMode == NoteEditVolume ) @@ -3513,7 +3515,7 @@ void PianoRoll::wheelEvent(QWheelEvent * we ) { for ( Note * n : nv ) { - volume_t vol = tLimit( n->getVolume() + step, MinVolume, MaxVolume ); + volume_t vol = qBound( MinVolume, n->getVolume() + step, MaxVolume ); n->setVolume( vol ); } bool allVolumesEqual = std::all_of( nv.begin(), nv.end(), @@ -3532,7 +3534,7 @@ void PianoRoll::wheelEvent(QWheelEvent * we ) { for ( Note * n : nv ) { - panning_t pan = tLimit( n->getPanning() + step, PanningLeft, PanningRight ); + panning_t pan = qBound( PanningLeft, n->getPanning() + step, PanningRight ); n->setPanning( pan ); } bool allPansEqual = std::all_of( nv.begin(), nv.end(), diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index a7809a077..093632831 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -592,7 +592,7 @@ int InstrumentTrack::masterKey( int _midi_key ) const { int key = baseNote(); - return tLimit( _midi_key - ( key - DefaultKey ), 0, NumKeys ); + return qBound( 0, _midi_key - ( key - DefaultKey ), NumKeys ); } From a0c2a62c270511b0e74c35b59162a6384b0d456d Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sun, 16 Jun 2019 02:08:48 +0200 Subject: [PATCH 339/445] Add .editorconfig This file tells the github online editor to use tabs of width 4 instead of 8. Open [this](https://github.com/JohannesLorenz/github_test/blob/master/test.cpp) test file in your browser to see how it works (the width is 5 in the example). Actually, it also tells many other editors... --- .editorconfig | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..2d4a9f975 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,5 @@ +root = true + +[*] +indent_style = tab +tab_width = 4 From 7834e10bc763e20cc7547f94564422b07ae4f1b9 Mon Sep 17 00:00:00 2001 From: Noah Brecht Date: Tue, 25 Jun 2019 07:26:57 -0400 Subject: [PATCH 340/445] FadeButtons now remain partially lit as a note plays out (#4969) --- include/FadeButton.h | 16 ++++- include/InstrumentTrack.h | 1 + src/gui/widgets/FadeButton.cpp | 124 ++++++++++++++++++++++----------- src/tracks/InstrumentTrack.cpp | 5 ++ 4 files changed, 104 insertions(+), 42 deletions(-) diff --git a/include/FadeButton.h b/include/FadeButton.h index 95753ecea..8f56a77b2 100644 --- a/include/FadeButton.h +++ b/include/FadeButton.h @@ -35,8 +35,10 @@ class FadeButton : public QAbstractButton { Q_OBJECT public: - FadeButton( const QColor & _normal_color, const QColor & - _activated_color, QWidget * _parent ); + FadeButton( const QColor & _normal_color, + const QColor & _activated_color, + const QColor & _hold_color, + QWidget * _parent ); virtual ~FadeButton(); void setActiveColor( const QColor & activated_color ); @@ -44,6 +46,7 @@ public: public slots: void activate(); + void noteEnd(); protected: @@ -53,13 +56,20 @@ protected: private: QTime m_stateTimer; + QTime m_releaseTimer; + + // the default color of the widget QColor m_normalColor; + // the color on note play QColor m_activatedColor; + // the color after the "play" fade is done but a note is still playing + QColor m_holdColor; + int activeNotes; void signalUpdate(); + QColor fadeToColor(QColor, QColor, QTime, float); } ; #endif - diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index c487438d0..72e0d04cc 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -221,6 +221,7 @@ signals: void midiNoteOff( const Note& ); void nameChanged(); void newNote(); + void endNote(); protected: diff --git a/src/gui/widgets/FadeButton.cpp b/src/gui/widgets/FadeButton.cpp index d4244701a..b633286b1 100644 --- a/src/gui/widgets/FadeButton.cpp +++ b/src/gui/widgets/FadeButton.cpp @@ -35,16 +35,21 @@ const float FadeDuration = 300; -FadeButton::FadeButton( const QColor & _normal_color, - const QColor & _activated_color, QWidget * _parent ) : +FadeButton::FadeButton(const QColor & _normal_color, + const QColor & _activated_color, + const QColor & holdColor, + QWidget * _parent) : QAbstractButton( _parent ), m_stateTimer(), + m_releaseTimer(), m_normalColor( _normal_color ), - m_activatedColor( _activated_color ) + m_activatedColor( _activated_color ), + m_holdColor( holdColor ) { - setAttribute( Qt::WA_OpaquePaintEvent, true ); - setCursor( QCursor( embed::getIconPixmap( "hand" ), 3, 3 ) ); - setFocusPolicy( Qt::NoFocus ); + setAttribute(Qt::WA_OpaquePaintEvent, true); + setCursor(QCursor(embed::getIconPixmap("hand"), 3, 3)); + setFocusPolicy(Qt::NoFocus); + activeNotes = 0; } @@ -54,7 +59,7 @@ FadeButton::~FadeButton() { } -void FadeButton::setActiveColor( const QColor & activated_color ) +void FadeButton::setActiveColor(const QColor & activated_color) { m_activatedColor = activated_color; } @@ -65,63 +70,104 @@ void FadeButton::setActiveColor( const QColor & activated_color ) void FadeButton::activate() { m_stateTimer.restart(); + activeNotes++; signalUpdate(); } -void FadeButton::customEvent( QEvent * ) +void FadeButton::noteEnd() +{ + if (activeNotes <= 0) + { + qWarning("noteEnd() triggered without a corresponding activate()!"); + activeNotes = 0; + } + else + { + activeNotes--; + } + + if (activeNotes == 0) + { + m_releaseTimer.restart(); + } + + signalUpdate(); +} + + + + +void FadeButton::customEvent(QEvent *) { update(); } - -void FadeButton::paintEvent( QPaintEvent * _pe ) +void FadeButton::paintEvent(QPaintEvent * _pe) { QColor col = m_normalColor; - if( ! m_stateTimer.isNull() && m_stateTimer.elapsed() < FadeDuration ) + + if(!m_stateTimer.isNull() && m_stateTimer.elapsed() < FadeDuration) { - const float state = 1 - m_stateTimer.elapsed() / FadeDuration; - const int r = (int)( m_normalColor.red() * - ( 1.0f - state ) + - m_activatedColor.red() * state ); - const int g = (int)( m_normalColor.green() * - ( 1.0f - state ) + - m_activatedColor.green() * state ); - const int b = (int)( m_normalColor.blue() * - ( 1.0f - state ) + - m_activatedColor.blue() * state ); - col.setRgb( r, g, b ); - QTimer::singleShot( 20, this, SLOT( update() ) ); + // The first part of the fade, when a note is triggered. + col = fadeToColor(m_activatedColor, m_holdColor, m_stateTimer, FadeDuration); + QTimer::singleShot(20, this, SLOT(update())); + } + else if (!m_stateTimer.isNull() + && m_stateTimer.elapsed() >= FadeDuration + && activeNotes > 0) + { + // The fade is done, but at least one note is still held. + col = m_holdColor; + } + else if (!m_releaseTimer.isNull() && m_releaseTimer.elapsed() < FadeDuration) + { + // Last note just ended. Fade to default color. + col = fadeToColor(m_holdColor, m_normalColor, m_releaseTimer, FadeDuration); + QTimer::singleShot(20, this, SLOT(update())); + } + else + { + // No fade, no notes. Set to default color. + col = m_normalColor; } - QPainter p( this ); - p.fillRect( rect(), col ); + QPainter p(this); + p.fillRect(rect(), col); int w = rect().right(); int h = rect().bottom(); - p.setPen( m_normalColor.darker(130) ); - p.drawLine( w, 1, w, h ); - p.drawLine( 1, h, w, h ); - p.setPen( m_normalColor.lighter(130) ); - p.drawLine( 0, 0, 0, h-1 ); - p.drawLine( 0, 0, w, 0 ); + p.setPen(m_normalColor.darker(130)); + p.drawLine(w, 1, w, h); + p.drawLine(1, h, w, h); + p.setPen(m_normalColor.lighter(130)); + p.drawLine(0, 0, 0, h-1); + p.drawLine(0, 0, w, 0); } +QColor FadeButton::fadeToColor(QColor startCol, QColor endCol, QTime timer, float duration) +{ + QColor col; + + const float state = 1 - timer.elapsed() / duration; + const int r = (int)(endCol.red() * (1.0f - state) + + startCol.red() * state); + const int g = (int)(endCol.green() * (1.0f - state) + + startCol.green() * state); + const int b = (int)(endCol.blue() * (1.0f - state) + + startCol.blue() * state); + col.setRgb(r, g, b); + + return col; +} void FadeButton::signalUpdate() { - QApplication::postEvent( this, new updateEvent() ); + QApplication::postEvent(this, new updateEvent()); } - - - - - - - diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 093632831..607131be0 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -422,6 +422,7 @@ void InstrumentTrack::processOutEvent( const MidiEvent& event, const MidiTime& t m_instrument->handleMidiEvent( MidiEvent( MidiNoteOff, midiPort()->realOutputChannel(), key, 0 ), time, offset ); } m_midiNotesMutex.unlock(); + emit endNote(); break; default: @@ -976,6 +977,8 @@ InstrumentTrackView::InstrumentTrackView( InstrumentTrack * _it, TrackContainerV QPalette::Background), QApplication::palette().color( QPalette::Active, QPalette::BrightText ), + QApplication::palette().color( QPalette::Active, + QPalette::BrightText).darker(), getTrackSettingsWidget() ); m_activityIndicator->setGeometry( widgetWidth-2*24-11, 2, 8, 28 ); @@ -986,6 +989,8 @@ InstrumentTrackView::InstrumentTrackView( InstrumentTrack * _it, TrackContainerV this, SLOT( activityIndicatorReleased() ) ); connect( _it, SIGNAL( newNote() ), m_activityIndicator, SLOT( activate() ) ); + connect( _it, SIGNAL( endNote() ), + m_activityIndicator, SLOT( noteEnd() ) ); connect( &_it->m_mutedModel, SIGNAL( dataChanged() ), this, SLOT( muteChanged() ) ); setModel( _it ); From 68cb91726a9373ee9929529c276ffe417275a0e8 Mon Sep 17 00:00:00 2001 From: Steffen Baranowsky Date: Wed, 26 Jun 2019 13:34:13 +0200 Subject: [PATCH 341/445] MDI Subwindow Decoration for VeSTige instruments closes #2824 (#2826) * MDI Subwindow Decoration for VeSTige instruments closes #2824 * revert changes * change QMdiSubWindow to our SubWindow in Vestige --- plugins/vestige/vestige.cpp | 4 ++-- plugins/vestige/vestige.h | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index 1d54538b6..82d4d0407 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -82,11 +82,11 @@ Plugin::Descriptor Q_DECL_EXPORT vestige_plugin_descriptor = } -class vstSubWin : public QMdiSubWindow +class vstSubWin : public SubWindow { public: vstSubWin( QWidget * _parent ) : - QMdiSubWindow( _parent ) + SubWindow( _parent ) { setAttribute( Qt::WA_DeleteOnClose, false ); setWindowFlags( Qt::WindowCloseButtonHint ); diff --git a/plugins/vestige/vestige.h b/plugins/vestige/vestige.h index 3b92eea8f..e4ef11fce 100644 --- a/plugins/vestige/vestige.h +++ b/plugins/vestige/vestige.h @@ -29,14 +29,13 @@ #include #include -#include #include #include "Instrument.h" #include "InstrumentView.h" #include "Note.h" #include "Knob.h" - +#include "SubWindow.h" #include "AutomatableModel.h" From d766b876884fe0c51cfce587d84c279bf990c548 Mon Sep 17 00:00:00 2001 From: Steffen Baranowsky Date: Fri, 28 Jun 2019 02:26:27 +0200 Subject: [PATCH 342/445] Drop sample on sampletracks (#5043) * implements drag and drop samples to sampletracks * clean up / take care of timeLineWidget heigth in songeditor * unused memeber removed * clean up * Update include/TrackContainerView.h Co-Authored-By: Spekular * Update src/gui/TrackContainerView.cpp Co-Authored-By: Spekular * Update src/gui/TrackContainerView.cpp Co-Authored-By: Spekular * Update src/gui/editors/SongEditor.cpp Co-Authored-By: Spekular * load AFP if we don't drop on a sample track * take care of timeLineWidget size changes * clean up * consolidate some code * requested changes by code review * move logic to SampleTrackView * clean up * clean up * clean up --- include/SampleTrack.h | 4 +++- src/tracks/SampleTrack.cpp | 45 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/include/SampleTrack.h b/include/SampleTrack.h index ccb5a020e..9469669a1 100644 --- a/include/SampleTrack.h +++ b/include/SampleTrack.h @@ -139,7 +139,7 @@ public: virtual bool play( const MidiTime & _start, const fpp_t _frames, const f_cnt_t _frame_base, int _tco_num = -1 ); virtual TrackView * createView( TrackContainerView* tcv ); - virtual TrackContentObject * createTCO( const MidiTime & _pos ); + virtual TrackContentObject * createTCO(const MidiTime & pos); virtual void saveTrackSpecificSettings( QDomDocument & _doc, @@ -218,6 +218,8 @@ protected: return "SampleTrackView"; } + void dragEnterEvent(QDragEnterEvent *dee); + void dropEvent(QDropEvent *de); private slots: void assignFxLine( int channelIndex ); diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 3edbc2239..ea3c53602 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -710,9 +710,11 @@ TrackView * SampleTrack::createView( TrackContainerView* tcv ) -TrackContentObject * SampleTrack::createTCO( const MidiTime & ) +TrackContentObject * SampleTrack::createTCO(const MidiTime & pos) { - return new SampleTCO( this ); + SampleTCO * sTco = new SampleTCO(this); + sTco->movePosition(pos); + return sTco; } @@ -901,6 +903,45 @@ void SampleTrackView::modelChanged() + +void SampleTrackView::dragEnterEvent(QDragEnterEvent *dee) +{ + StringPairDrag::processDragEnterEvent(dee, QString("samplefile")); +} + + + + +void SampleTrackView::dropEvent(QDropEvent *de) +{ + QString type = StringPairDrag::decodeKey(de); + QString value = StringPairDrag::decodeValue(de); + + if (type == "samplefile") + { + int trackHeadWidth = ConfigManager::inst()->value("ui", "compacttrackbuttons").toInt()==1 + ? DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT + : DEFAULT_SETTINGS_WIDGET_WIDTH + TRACK_OP_WIDTH; + + int xPos = de->pos().x() < trackHeadWidth + ? trackHeadWidth + : de->pos().x(); + + MidiTime tcoPos = trackContainerView()->fixedTCOs() + ? MidiTime(0) + : MidiTime(((xPos - trackHeadWidth) / trackContainerView()->pixelsPerTact() + * MidiTime::ticksPerTact()) + trackContainerView()->currentPosition() + ).toNearestTact(); + + SampleTCO * sTco = static_cast(getTrack()->createTCO(tcoPos)); + if (sTco) { sTco->setSampleFile(value); } + } + +} + + + + SampleTrackWindow::SampleTrackWindow(SampleTrackView * tv) : QWidget(), ModelView(NULL, this), From 59e186d208e500f469791c66798337d6c00df08b Mon Sep 17 00:00:00 2001 From: Johannes Lorenz <1042576+JohannesLorenz@users.noreply.github.com> Date: Thu, 11 Jul 2019 18:22:41 +0200 Subject: [PATCH 343/445] Closes #5050: Add Mixer threading comments (#5069) [ci skip] --- include/Mixer.h | 3 +++ src/core/Mixer.cpp | 2 ++ 2 files changed, 5 insertions(+) diff --git a/include/Mixer.h b/include/Mixer.h index cea592905..69ea0d12d 100644 --- a/include/Mixer.h +++ b/include/Mixer.h @@ -315,6 +315,7 @@ public: inline bool isMetronomeActive() const { return m_metronomeActive; } inline void setMetronomeActive(bool value = true) { m_metronomeActive = value; } + //! Block until a change in model can be done (i.e. wait for audio thread) void requestChangeInModel(); void doneChangeInModel(); @@ -366,6 +367,8 @@ private: void clearInternal(); + //! Called by the audio thread to give control to other threads, + //! such that they can do changes in the model (like e.g. removing effects) void runChangesInModel(); bool m_renderOnly; diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index 7e41f2097..2550b072e 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -831,7 +831,9 @@ void Mixer::runChangesInModel() if( m_changesSignal ) { m_waitChangesMutex.lock(); + // allow changes in the model from other threads ... m_changesRequestCondition.wakeOne(); + // ... and wait until they are done m_changesMixerCondition.wait( &m_waitChangesMutex ); m_waitChangesMutex.unlock(); } From f5db88086754e80b9a9bc56ef6502b6052afa3bf Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 13 Jul 2019 22:09:36 +0200 Subject: [PATCH 344/445] SubWindow.cpp: Fix comment --- src/gui/SubWindow.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index 7340d428c..1c3f26e59 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -1,4 +1,4 @@ -/* +/* * SubWindow.cpp - Implementation of QMdiSubWindow that correctly tracks * the geometry that windows should be restored to. * Workaround for https://bugreports.qt.io/browse/QTBUG-256 @@ -375,10 +375,10 @@ void SubWindow::focusChanged( QMdiSubWindow *subWindow ) /** * @brief SubWindow::resizeEvent * - * On every rezise event we have to adjust our title label. - * - * At next we give the event to QMdiSubWindow::resizeEvent() which handles + * At first we give the event to QMdiSubWindow::resizeEvent() which handles * the event on its behavior. + * + * On every resize event we have to adjust our title label. * * At last we store the current size into m_trackedNormalGeom. This size * will be saved with the project because of an Qt bug wich doesn't From 3585b14b98a45db2dd7a944f4b211111363e6e83 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 13 Jul 2019 22:14:55 +0200 Subject: [PATCH 345/445] Instrument view: Add missing size hints Those are needed for the case when an instrument is being resized manually. --- include/InstrumentView.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/InstrumentView.h b/include/InstrumentView.h index 9c6081a77..06a1a0277 100644 --- a/include/InstrumentView.h +++ b/include/InstrumentView.h @@ -34,9 +34,12 @@ class InstrumentTrackWindow; class LMMS_EXPORT InstrumentView : public PluginView { + QSize sizeHint() const override { return QSize(250, 250); } + QSize minimumSizeHint() const override { return sizeHint(); } + public: InstrumentView( Instrument * _instrument, QWidget * _parent ); - virtual ~InstrumentView(); + ~InstrumentView() override; Instrument * model() { @@ -48,7 +51,7 @@ public: return( castModel() ); } - virtual void setModel( Model * _model, bool = false ); + void setModel( Model * _model, bool = false ) override; InstrumentTrackWindow * instrumentTrackWindow(); From a4b801fe1b7bb55f5770033a950b4cce3468dd45 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 13 Jul 2019 22:15:56 +0200 Subject: [PATCH 346/445] TabWidget: Add missing size hints This is mostly for completeness, it does not fix any known issues. --- include/TabWidget.h | 1 + src/gui/widgets/TabWidget.cpp | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/include/TabWidget.h b/include/TabWidget.h index 11e4da40a..88ecf9034 100644 --- a/include/TabWidget.h +++ b/include/TabWidget.h @@ -78,6 +78,7 @@ protected: virtual void resizeEvent( QResizeEvent * _re ); virtual void wheelEvent( QWheelEvent * _we ); virtual QSize minimumSizeHint() const; + virtual QSize sizeHint() const; private: struct widgetDesc diff --git a/src/gui/widgets/TabWidget.cpp b/src/gui/widgets/TabWidget.cpp index 9bdbec2e0..125bbbd74 100644 --- a/src/gui/widgets/TabWidget.cpp +++ b/src/gui/widgets/TabWidget.cpp @@ -333,6 +333,14 @@ QSize TabWidget::minimumSizeHint() const +QSize TabWidget::sizeHint() const +{ + return minimumSizeHint(); +} + + + + // Return the color to be used to draw a TabWidget's title text (if any) QColor TabWidget::tabTitleText() const { From 4f3ed9f9e145d4daafc37c77eeaa04a112dee1da Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 13 Jul 2019 22:17:33 +0200 Subject: [PATCH 347/445] EffectControlDialog: Use 'Preferred' size policy This does not have any effect, as the surrounding MDI sub window always uses the minimumSizHint. It's just preparation. --- src/gui/EffectControlDialog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/EffectControlDialog.cpp b/src/gui/EffectControlDialog.cpp index c43f451aa..dc273a6a3 100644 --- a/src/gui/EffectControlDialog.cpp +++ b/src/gui/EffectControlDialog.cpp @@ -36,6 +36,7 @@ EffectControlDialog::EffectControlDialog( EffectControls * _controls ) : m_effectControls( _controls ) { setWindowTitle( m_effectControls->effect()->displayName() ); + setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ); } From a4df7a976507108fab3c2a70958ce2631d54e742 Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sun, 14 Jul 2019 10:20:54 +0200 Subject: [PATCH 348/445] Split InstrumentView into itself and InstrumentView250 --- include/DummyInstrument.h | 2 +- include/InstrumentView.h | 18 +++++++++++++++--- plugins/FreeBoy/FreeBoy.cpp | 2 +- plugins/FreeBoy/FreeBoy.h | 2 +- plugins/GigPlayer/GigPlayer.cpp | 2 +- plugins/GigPlayer/GigPlayer.h | 2 +- plugins/OpulenZ/OpulenZ.cpp | 2 +- plugins/OpulenZ/OpulenZ.h | 2 +- plugins/Xpressive/Xpressive.cpp | 2 +- plugins/Xpressive/Xpressive.h | 2 +- .../audio_file_processor.cpp | 2 +- .../audio_file_processor.h | 2 +- plugins/bit_invader/bit_invader.cpp | 2 +- plugins/bit_invader/bit_invader.h | 2 +- plugins/carlabase/carla.cpp | 2 +- plugins/carlabase/carla.h | 2 +- plugins/kicker/kicker.cpp | 2 +- plugins/kicker/kicker.h | 2 +- plugins/lb302/lb302.cpp | 2 +- plugins/lb302/lb302.h | 2 +- plugins/monstro/Monstro.cpp | 2 +- plugins/monstro/Monstro.h | 2 +- plugins/nes/Nes.cpp | 2 +- plugins/nes/Nes.h | 2 +- plugins/organic/organic.cpp | 2 +- plugins/organic/organic.h | 2 +- plugins/patman/patman.cpp | 2 +- plugins/patman/patman.h | 2 +- plugins/sf2_player/sf2_player.cpp | 2 +- plugins/sf2_player/sf2_player.h | 2 +- plugins/sfxr/sfxr.cpp | 2 +- plugins/sfxr/sfxr.h | 2 +- plugins/sid/sid_instrument.cpp | 2 +- plugins/sid/sid_instrument.h | 2 +- plugins/stk/mallets/mallets.cpp | 2 +- plugins/stk/mallets/mallets.h | 2 +- plugins/triple_oscillator/TripleOscillator.cpp | 2 +- plugins/triple_oscillator/TripleOscillator.h | 2 +- plugins/vestige/vestige.cpp | 4 ++-- plugins/vestige/vestige.h | 4 ++-- plugins/vibed/vibed.cpp | 2 +- plugins/vibed/vibed.h | 2 +- plugins/watsyn/Watsyn.cpp | 2 +- plugins/watsyn/Watsyn.h | 2 +- plugins/zynaddsubfx/ZynAddSubFx.cpp | 2 +- plugins/zynaddsubfx/ZynAddSubFx.h | 2 +- src/gui/InstrumentView.cpp | 7 +++++++ 47 files changed, 69 insertions(+), 50 deletions(-) diff --git a/include/DummyInstrument.h b/include/DummyInstrument.h index b69594b00..436b23c6f 100644 --- a/include/DummyInstrument.h +++ b/include/DummyInstrument.h @@ -68,7 +68,7 @@ public: virtual PluginView * instantiateView( QWidget * _parent ) { - return new InstrumentView( this, _parent ); + return new InstrumentView250( this, _parent ); } } ; diff --git a/include/InstrumentView.h b/include/InstrumentView.h index 06a1a0277..bb1bc766b 100644 --- a/include/InstrumentView.h +++ b/include/InstrumentView.h @@ -32,11 +32,9 @@ class InstrumentTrackWindow; +//! Instrument view with variable size class LMMS_EXPORT InstrumentView : public PluginView { - QSize sizeHint() const override { return QSize(250, 250); } - QSize minimumSizeHint() const override { return sizeHint(); } - public: InstrumentView( Instrument * _instrument, QWidget * _parent ); ~InstrumentView() override; @@ -58,4 +56,18 @@ public: } ; + + +//! Instrument view with fixed LMMS-default size +class LMMS_EXPORT InstrumentView250 : public InstrumentView +{ + QSize sizeHint() const override { return QSize(250, 250); } + QSize minimumSizeHint() const override { return sizeHint(); } + +public: + using InstrumentView::InstrumentView; + ~InstrumentView250() override; +} ; + + #endif diff --git a/plugins/FreeBoy/FreeBoy.cpp b/plugins/FreeBoy/FreeBoy.cpp index dd05444a6..d503d135c 100644 --- a/plugins/FreeBoy/FreeBoy.cpp +++ b/plugins/FreeBoy/FreeBoy.cpp @@ -457,7 +457,7 @@ public: FreeBoyInstrumentView::FreeBoyInstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { setAutoFillBackground( true ); diff --git a/plugins/FreeBoy/FreeBoy.h b/plugins/FreeBoy/FreeBoy.h index 69c478505..84d2fd2e6 100644 --- a/plugins/FreeBoy/FreeBoy.h +++ b/plugins/FreeBoy/FreeBoy.h @@ -111,7 +111,7 @@ private: } ; -class FreeBoyInstrumentView : public InstrumentView +class FreeBoyInstrumentView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/GigPlayer/GigPlayer.cpp b/plugins/GigPlayer/GigPlayer.cpp index bf5990252..695378ab1 100644 --- a/plugins/GigPlayer/GigPlayer.cpp +++ b/plugins/GigPlayer/GigPlayer.cpp @@ -922,7 +922,7 @@ public: GigInstrumentView::GigInstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { GigInstrument * k = castModel(); diff --git a/plugins/GigPlayer/GigPlayer.h b/plugins/GigPlayer/GigPlayer.h index 0a5e023f9..8232d7a97 100644 --- a/plugins/GigPlayer/GigPlayer.h +++ b/plugins/GigPlayer/GigPlayer.h @@ -334,7 +334,7 @@ signals: -class GigInstrumentView : public InstrumentView +class GigInstrumentView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/OpulenZ/OpulenZ.cpp b/plugins/OpulenZ/OpulenZ.cpp index d8d5f3e26..ce85e064d 100644 --- a/plugins/OpulenZ/OpulenZ.cpp +++ b/plugins/OpulenZ/OpulenZ.cpp @@ -681,7 +681,7 @@ void OpulenzInstrument::loadFile( const QString& file ) { OpulenzInstrumentView::OpulenzInstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { #define KNOB_GEN(knobname, hinttext, hintunit,xpos,ypos) \ diff --git a/plugins/OpulenZ/OpulenZ.h b/plugins/OpulenZ/OpulenZ.h index e69c278ef..a986c9f21 100644 --- a/plugins/OpulenZ/OpulenZ.h +++ b/plugins/OpulenZ/OpulenZ.h @@ -142,7 +142,7 @@ private: -class OpulenzInstrumentView : public InstrumentView +class OpulenzInstrumentView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/Xpressive/Xpressive.cpp b/plugins/Xpressive/Xpressive.cpp index cb0293710..929a1c631 100644 --- a/plugins/Xpressive/Xpressive.cpp +++ b/plugins/Xpressive/Xpressive.cpp @@ -274,7 +274,7 @@ public: XpressiveView::XpressiveView(Instrument * _instrument, QWidget * _parent) : - InstrumentView(_instrument, _parent) + InstrumentView250(_instrument, _parent) { const int COL_KNOBS = 194; diff --git a/plugins/Xpressive/Xpressive.h b/plugins/Xpressive/Xpressive.h index ca80f2b78..422002aa8 100644 --- a/plugins/Xpressive/Xpressive.h +++ b/plugins/Xpressive/Xpressive.h @@ -139,7 +139,7 @@ private: } ; -class XpressiveView : public InstrumentView +class XpressiveView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/audio_file_processor/audio_file_processor.cpp b/plugins/audio_file_processor/audio_file_processor.cpp index 6c080f7c9..16c190170 100644 --- a/plugins/audio_file_processor/audio_file_processor.cpp +++ b/plugins/audio_file_processor/audio_file_processor.cpp @@ -449,7 +449,7 @@ QPixmap * AudioFileProcessorView::s_artwork = NULL; AudioFileProcessorView::AudioFileProcessorView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { if( s_artwork == NULL ) { diff --git a/plugins/audio_file_processor/audio_file_processor.h b/plugins/audio_file_processor/audio_file_processor.h index 150807686..854c2b7cd 100644 --- a/plugins/audio_file_processor/audio_file_processor.h +++ b/plugins/audio_file_processor/audio_file_processor.h @@ -111,7 +111,7 @@ private: class AudioFileProcessorWaveView; -class AudioFileProcessorView : public InstrumentView +class AudioFileProcessorView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/bit_invader/bit_invader.cpp b/plugins/bit_invader/bit_invader.cpp index ecc77be0b..563e0e2eb 100644 --- a/plugins/bit_invader/bit_invader.cpp +++ b/plugins/bit_invader/bit_invader.cpp @@ -327,7 +327,7 @@ PluginView * bitInvader::instantiateView( QWidget * _parent ) bitInvaderView::bitInvaderView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { setAutoFillBackground( true ); QPalette pal; diff --git a/plugins/bit_invader/bit_invader.h b/plugins/bit_invader/bit_invader.h index 1489ab104..60b468683 100644 --- a/plugins/bit_invader/bit_invader.h +++ b/plugins/bit_invader/bit_invader.h @@ -108,7 +108,7 @@ private: -class bitInvaderView : public InstrumentView +class bitInvaderView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/carlabase/carla.cpp b/plugins/carlabase/carla.cpp index 578c3ac65..7ab862957 100644 --- a/plugins/carlabase/carla.cpp +++ b/plugins/carlabase/carla.cpp @@ -460,7 +460,7 @@ void CarlaInstrument::sampleRateChanged() // ------------------------------------------------------------------- CarlaInstrumentView::CarlaInstrumentView(CarlaInstrument* const instrument, QWidget* const parent) - : InstrumentView(instrument, parent), + : InstrumentView250(instrument, parent), fHandle(instrument->fHandle), fDescriptor(instrument->fDescriptor), fTimerId(fHandle != NULL && fDescriptor->ui_idle != NULL ? startTimer(30) : 0) diff --git a/plugins/carlabase/carla.h b/plugins/carlabase/carla.h index a4efb67e0..8a169e4db 100644 --- a/plugins/carlabase/carla.h +++ b/plugins/carlabase/carla.h @@ -99,7 +99,7 @@ private: friend class CarlaInstrumentView; }; -class CarlaInstrumentView : public InstrumentView +class CarlaInstrumentView : public InstrumentView250 { Q_OBJECT diff --git a/plugins/kicker/kicker.cpp b/plugins/kicker/kicker.cpp index 2087cf880..62e46b8b5 100644 --- a/plugins/kicker/kicker.cpp +++ b/plugins/kicker/kicker.cpp @@ -267,7 +267,7 @@ public: kickerInstrumentView::kickerInstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { const int ROW1 = 14; const int ROW2 = ROW1 + 56; diff --git a/plugins/kicker/kicker.h b/plugins/kicker/kicker.h index 295887c2f..f2dabd1fd 100644 --- a/plugins/kicker/kicker.h +++ b/plugins/kicker/kicker.h @@ -94,7 +94,7 @@ private: -class kickerInstrumentView : public InstrumentView +class kickerInstrumentView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/lb302/lb302.cpp b/plugins/lb302/lb302.cpp index d32f14e88..dc630ee92 100644 --- a/plugins/lb302/lb302.cpp +++ b/plugins/lb302/lb302.cpp @@ -804,7 +804,7 @@ PluginView * lb302Synth::instantiateView( QWidget * _parent ) lb302SynthView::lb302SynthView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { // GUI m_vcfCutKnob = new Knob( knobBright_26, this ); diff --git a/plugins/lb302/lb302.h b/plugins/lb302/lb302.h index 3ca22c78b..2d70ccee1 100644 --- a/plugins/lb302/lb302.h +++ b/plugins/lb302/lb302.h @@ -256,7 +256,7 @@ private: } ; -class lb302SynthView : public InstrumentView +class lb302SynthView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/monstro/Monstro.cpp b/plugins/monstro/Monstro.cpp index baee242bb..231517abb 100644 --- a/plugins/monstro/Monstro.cpp +++ b/plugins/monstro/Monstro.cpp @@ -1448,7 +1448,7 @@ void MonstroInstrument::updateSlope2() MonstroView::MonstroView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { m_operatorsView = setupOperatorsView( this ); setWidgetBackground( m_operatorsView, "artwork_op" ); diff --git a/plugins/monstro/Monstro.h b/plugins/monstro/Monstro.h index a8b186904..18cce7ad1 100644 --- a/plugins/monstro/Monstro.h +++ b/plugins/monstro/Monstro.h @@ -569,7 +569,7 @@ private: }; -class MonstroView : public InstrumentView +class MonstroView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/nes/Nes.cpp b/plugins/nes/Nes.cpp index 5b34dcb1f..345f94249 100644 --- a/plugins/nes/Nes.cpp +++ b/plugins/nes/Nes.cpp @@ -732,7 +732,7 @@ QPixmap * NesInstrumentView::s_artwork = NULL; NesInstrumentView::NesInstrumentView( Instrument * instrument, QWidget * parent ) : - InstrumentView( instrument, parent ) + InstrumentView250( instrument, parent ) { setAutoFillBackground( true ); QPalette pal; diff --git a/plugins/nes/Nes.h b/plugins/nes/Nes.h index 20f703739..855cab710 100644 --- a/plugins/nes/Nes.h +++ b/plugins/nes/Nes.h @@ -294,7 +294,7 @@ private: }; -class NesInstrumentView : public InstrumentView +class NesInstrumentView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/organic/organic.cpp b/plugins/organic/organic.cpp index b6d45c8d3..1c9aa5ab0 100644 --- a/plugins/organic/organic.cpp +++ b/plugins/organic/organic.cpp @@ -418,7 +418,7 @@ public: organicInstrumentView::organicInstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ), + InstrumentView250( _instrument, _parent ), m_oscKnobs( NULL ) { organicInstrument * oi = castModel(); diff --git a/plugins/organic/organic.h b/plugins/organic/organic.h index 86b25ea77..083fa6333 100644 --- a/plugins/organic/organic.h +++ b/plugins/organic/organic.h @@ -173,7 +173,7 @@ private slots: } ; -class organicInstrumentView : public InstrumentView +class organicInstrumentView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/patman/patman.cpp b/plugins/patman/patman.cpp index 6ab7adce7..61368a575 100644 --- a/plugins/patman/patman.cpp +++ b/plugins/patman/patman.cpp @@ -443,7 +443,7 @@ PluginView * patmanInstrument::instantiateView( QWidget * _parent ) PatmanView::PatmanView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ), + InstrumentView250( _instrument, _parent ), m_pi( NULL ) { setAutoFillBackground( true ); diff --git a/plugins/patman/patman.h b/plugins/patman/patman.h index a3b5a39b8..014a7d63c 100644 --- a/plugins/patman/patman.h +++ b/plugins/patman/patman.h @@ -116,7 +116,7 @@ signals: -class PatmanView : public InstrumentView +class PatmanView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index 4bf75777c..f0676dc8c 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -859,7 +859,7 @@ public: sf2InstrumentView::sf2InstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { // QVBoxLayout * vl = new QVBoxLayout( this ); // QHBoxLayout * hl = new QHBoxLayout(); diff --git a/plugins/sf2_player/sf2_player.h b/plugins/sf2_player/sf2_player.h index eed7e24ab..20da89adb 100644 --- a/plugins/sf2_player/sf2_player.h +++ b/plugins/sf2_player/sf2_player.h @@ -187,7 +187,7 @@ public: -class sf2InstrumentView : public InstrumentView +class sf2InstrumentView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/sfxr/sfxr.cpp b/plugins/sfxr/sfxr.cpp index c99f46f88..c954e72a0 100644 --- a/plugins/sfxr/sfxr.cpp +++ b/plugins/sfxr/sfxr.cpp @@ -601,7 +601,7 @@ public: sfxrInstrumentView::sfxrInstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { srand(time(NULL)); setAutoFillBackground( true ); diff --git a/plugins/sfxr/sfxr.h b/plugins/sfxr/sfxr.h index 27246a1b8..dc601d322 100644 --- a/plugins/sfxr/sfxr.h +++ b/plugins/sfxr/sfxr.h @@ -223,7 +223,7 @@ private: -class sfxrInstrumentView : public InstrumentView +class sfxrInstrumentView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/sid/sid_instrument.cpp b/plugins/sid/sid_instrument.cpp index 2eb46be56..2df551f20 100644 --- a/plugins/sid/sid_instrument.cpp +++ b/plugins/sid/sid_instrument.cpp @@ -481,7 +481,7 @@ public: sidInstrumentView::sidInstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { setAutoFillBackground( true ); diff --git a/plugins/sid/sid_instrument.h b/plugins/sid/sid_instrument.h index 6128bf91c..2649b9cba 100644 --- a/plugins/sid/sid_instrument.h +++ b/plugins/sid/sid_instrument.h @@ -132,7 +132,7 @@ private: -class sidInstrumentView : public InstrumentView +class sidInstrumentView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/stk/mallets/mallets.cpp b/plugins/stk/mallets/mallets.cpp index 7111bcdaa..a39cd689c 100644 --- a/plugins/stk/mallets/mallets.cpp +++ b/plugins/stk/mallets/mallets.cpp @@ -384,7 +384,7 @@ PluginView * malletsInstrument::instantiateView( QWidget * _parent ) malletsInstrumentView::malletsInstrumentView( malletsInstrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { m_modalBarWidget = setupModalBarControls( this ); setWidgetBackground( m_modalBarWidget, "artwork" ); diff --git a/plugins/stk/mallets/mallets.h b/plugins/stk/mallets/mallets.h index 3928c531c..ec13f5eb9 100644 --- a/plugins/stk/mallets/mallets.h +++ b/plugins/stk/mallets/mallets.h @@ -187,7 +187,7 @@ private: } ; -class malletsInstrumentView: public InstrumentView +class malletsInstrumentView: public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/triple_oscillator/TripleOscillator.cpp b/plugins/triple_oscillator/TripleOscillator.cpp index 6b644fd46..fa4f3b4ae 100644 --- a/plugins/triple_oscillator/TripleOscillator.cpp +++ b/plugins/triple_oscillator/TripleOscillator.cpp @@ -419,7 +419,7 @@ public: TripleOscillatorView::TripleOscillatorView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { setAutoFillBackground( true ); QPalette pal; diff --git a/plugins/triple_oscillator/TripleOscillator.h b/plugins/triple_oscillator/TripleOscillator.h index fb2b48a41..b45fea1f3 100644 --- a/plugins/triple_oscillator/TripleOscillator.h +++ b/plugins/triple_oscillator/TripleOscillator.h @@ -136,7 +136,7 @@ private: -class TripleOscillatorView : public InstrumentView +class TripleOscillatorView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index 73ea33a51..c06a771d3 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -460,7 +460,7 @@ PluginView * vestigeInstrument::instantiateView( QWidget * _parent ) VestigeInstrumentView::VestigeInstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ), + InstrumentView250( _instrument, _parent ), lastPosInMenu (0) { if( s_artwork == NULL ) @@ -892,7 +892,7 @@ void VestigeInstrumentView::paintEvent( QPaintEvent * ) manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrument, QWidget * _parent, vestigeInstrument * m_vi2 ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { m_vi = m_vi2; m_vi->m_scrollArea = new QScrollArea( this ); diff --git a/plugins/vestige/vestige.h b/plugins/vestige/vestige.h index 2c007efc0..423146497 100644 --- a/plugins/vestige/vestige.h +++ b/plugins/vestige/vestige.h @@ -98,7 +98,7 @@ private: } ; -class manageVestigeInstrumentView : public InstrumentView +class manageVestigeInstrumentView : public InstrumentView250 { Q_OBJECT public: @@ -134,7 +134,7 @@ private: } ; -class VestigeInstrumentView : public InstrumentView +class VestigeInstrumentView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/vibed/vibed.cpp b/plugins/vibed/vibed.cpp index f33a90428..f0c347b7c 100644 --- a/plugins/vibed/vibed.cpp +++ b/plugins/vibed/vibed.cpp @@ -350,7 +350,7 @@ PluginView * vibed::instantiateView( QWidget * _parent ) vibedView::vibedView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { setAutoFillBackground( true ); QPalette pal; diff --git a/plugins/vibed/vibed.h b/plugins/vibed/vibed.h index 9e175c4cc..039b88d24 100644 --- a/plugins/vibed/vibed.h +++ b/plugins/vibed/vibed.h @@ -82,7 +82,7 @@ private: -class vibedView : public InstrumentView +class vibedView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/watsyn/Watsyn.cpp b/plugins/watsyn/Watsyn.cpp index 0122b293a..9d45531d5 100644 --- a/plugins/watsyn/Watsyn.cpp +++ b/plugins/watsyn/Watsyn.cpp @@ -667,7 +667,7 @@ void WatsynInstrument::updateWaveB2() WatsynView::WatsynView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { setAutoFillBackground( true ); QPalette pal; diff --git a/plugins/watsyn/Watsyn.h b/plugins/watsyn/Watsyn.h index e52b7bb75..27cd65e47 100644 --- a/plugins/watsyn/Watsyn.h +++ b/plugins/watsyn/Watsyn.h @@ -293,7 +293,7 @@ private: }; -class WatsynView : public InstrumentView +class WatsynView : public InstrumentView250 { Q_OBJECT public: diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index ad8d9a78c..42340ab62 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -488,7 +488,7 @@ PluginView * ZynAddSubFxInstrument::instantiateView( QWidget * _parent ) ZynAddSubFxView::ZynAddSubFxView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView( _instrument, _parent ) + InstrumentView250( _instrument, _parent ) { setAutoFillBackground( true ); QPalette pal; diff --git a/plugins/zynaddsubfx/ZynAddSubFx.h b/plugins/zynaddsubfx/ZynAddSubFx.h index e8974d149..88d70d83b 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.h +++ b/plugins/zynaddsubfx/ZynAddSubFx.h @@ -132,7 +132,7 @@ signals: -class ZynAddSubFxView : public InstrumentView +class ZynAddSubFxView : public InstrumentView250 { Q_OBJECT public: diff --git a/src/gui/InstrumentView.cpp b/src/gui/InstrumentView.cpp index d2a7483e4..86b2fcc91 100644 --- a/src/gui/InstrumentView.cpp +++ b/src/gui/InstrumentView.cpp @@ -70,3 +70,10 @@ InstrumentTrackWindow * InstrumentView::instrumentTrackWindow( void ) parentWidget()->parentWidget() ) ); } + + + +InstrumentView250::~InstrumentView250() +{ +} + From aa8f9361c6b1be8a6fd0b15f2d411240ee8eeaba Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Wed, 17 Jul 2019 22:20:25 +0200 Subject: [PATCH 349/445] Rename InstrumentView250 to InstrumentViewFixedSize --- include/DummyInstrument.h | 2 +- include/InstrumentView.h | 4 ++-- plugins/FreeBoy/FreeBoy.cpp | 2 +- plugins/FreeBoy/FreeBoy.h | 2 +- plugins/GigPlayer/GigPlayer.cpp | 2 +- plugins/GigPlayer/GigPlayer.h | 2 +- plugins/OpulenZ/OpulenZ.cpp | 2 +- plugins/OpulenZ/OpulenZ.h | 2 +- plugins/Xpressive/Xpressive.cpp | 2 +- plugins/Xpressive/Xpressive.h | 2 +- plugins/audio_file_processor/audio_file_processor.cpp | 2 +- plugins/audio_file_processor/audio_file_processor.h | 2 +- plugins/bit_invader/bit_invader.cpp | 2 +- plugins/bit_invader/bit_invader.h | 2 +- plugins/carlabase/carla.cpp | 2 +- plugins/carlabase/carla.h | 2 +- plugins/kicker/kicker.cpp | 2 +- plugins/kicker/kicker.h | 2 +- plugins/lb302/lb302.cpp | 2 +- plugins/lb302/lb302.h | 2 +- plugins/monstro/Monstro.cpp | 2 +- plugins/monstro/Monstro.h | 2 +- plugins/nes/Nes.cpp | 2 +- plugins/nes/Nes.h | 2 +- plugins/organic/organic.cpp | 2 +- plugins/organic/organic.h | 2 +- plugins/patman/patman.cpp | 2 +- plugins/patman/patman.h | 2 +- plugins/sf2_player/sf2_player.cpp | 2 +- plugins/sf2_player/sf2_player.h | 2 +- plugins/sfxr/sfxr.cpp | 2 +- plugins/sfxr/sfxr.h | 2 +- plugins/sid/sid_instrument.cpp | 2 +- plugins/sid/sid_instrument.h | 2 +- plugins/stk/mallets/mallets.cpp | 2 +- plugins/stk/mallets/mallets.h | 2 +- plugins/triple_oscillator/TripleOscillator.cpp | 2 +- plugins/triple_oscillator/TripleOscillator.h | 2 +- plugins/vestige/vestige.cpp | 4 ++-- plugins/vestige/vestige.h | 4 ++-- plugins/vibed/vibed.cpp | 2 +- plugins/vibed/vibed.h | 2 +- plugins/watsyn/Watsyn.cpp | 2 +- plugins/watsyn/Watsyn.h | 2 +- plugins/zynaddsubfx/ZynAddSubFx.cpp | 2 +- plugins/zynaddsubfx/ZynAddSubFx.h | 2 +- src/gui/InstrumentView.cpp | 2 +- 47 files changed, 50 insertions(+), 50 deletions(-) diff --git a/include/DummyInstrument.h b/include/DummyInstrument.h index 436b23c6f..87083f262 100644 --- a/include/DummyInstrument.h +++ b/include/DummyInstrument.h @@ -68,7 +68,7 @@ public: virtual PluginView * instantiateView( QWidget * _parent ) { - return new InstrumentView250( this, _parent ); + return new InstrumentViewFixedSize( this, _parent ); } } ; diff --git a/include/InstrumentView.h b/include/InstrumentView.h index bb1bc766b..838ed2d91 100644 --- a/include/InstrumentView.h +++ b/include/InstrumentView.h @@ -59,14 +59,14 @@ public: //! Instrument view with fixed LMMS-default size -class LMMS_EXPORT InstrumentView250 : public InstrumentView +class LMMS_EXPORT InstrumentViewFixedSize : public InstrumentView { QSize sizeHint() const override { return QSize(250, 250); } QSize minimumSizeHint() const override { return sizeHint(); } public: using InstrumentView::InstrumentView; - ~InstrumentView250() override; + ~InstrumentViewFixedSize() override; } ; diff --git a/plugins/FreeBoy/FreeBoy.cpp b/plugins/FreeBoy/FreeBoy.cpp index d503d135c..b9428c5af 100644 --- a/plugins/FreeBoy/FreeBoy.cpp +++ b/plugins/FreeBoy/FreeBoy.cpp @@ -457,7 +457,7 @@ public: FreeBoyInstrumentView::FreeBoyInstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { setAutoFillBackground( true ); diff --git a/plugins/FreeBoy/FreeBoy.h b/plugins/FreeBoy/FreeBoy.h index 84d2fd2e6..9ceb27966 100644 --- a/plugins/FreeBoy/FreeBoy.h +++ b/plugins/FreeBoy/FreeBoy.h @@ -111,7 +111,7 @@ private: } ; -class FreeBoyInstrumentView : public InstrumentView250 +class FreeBoyInstrumentView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/GigPlayer/GigPlayer.cpp b/plugins/GigPlayer/GigPlayer.cpp index 695378ab1..336922e28 100644 --- a/plugins/GigPlayer/GigPlayer.cpp +++ b/plugins/GigPlayer/GigPlayer.cpp @@ -922,7 +922,7 @@ public: GigInstrumentView::GigInstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { GigInstrument * k = castModel(); diff --git a/plugins/GigPlayer/GigPlayer.h b/plugins/GigPlayer/GigPlayer.h index 8232d7a97..b9467b91b 100644 --- a/plugins/GigPlayer/GigPlayer.h +++ b/plugins/GigPlayer/GigPlayer.h @@ -334,7 +334,7 @@ signals: -class GigInstrumentView : public InstrumentView250 +class GigInstrumentView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/OpulenZ/OpulenZ.cpp b/plugins/OpulenZ/OpulenZ.cpp index ce85e064d..54b518dd8 100644 --- a/plugins/OpulenZ/OpulenZ.cpp +++ b/plugins/OpulenZ/OpulenZ.cpp @@ -681,7 +681,7 @@ void OpulenzInstrument::loadFile( const QString& file ) { OpulenzInstrumentView::OpulenzInstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { #define KNOB_GEN(knobname, hinttext, hintunit,xpos,ypos) \ diff --git a/plugins/OpulenZ/OpulenZ.h b/plugins/OpulenZ/OpulenZ.h index a986c9f21..2273b355a 100644 --- a/plugins/OpulenZ/OpulenZ.h +++ b/plugins/OpulenZ/OpulenZ.h @@ -142,7 +142,7 @@ private: -class OpulenzInstrumentView : public InstrumentView250 +class OpulenzInstrumentView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/Xpressive/Xpressive.cpp b/plugins/Xpressive/Xpressive.cpp index 929a1c631..7dc26dd03 100644 --- a/plugins/Xpressive/Xpressive.cpp +++ b/plugins/Xpressive/Xpressive.cpp @@ -274,7 +274,7 @@ public: XpressiveView::XpressiveView(Instrument * _instrument, QWidget * _parent) : - InstrumentView250(_instrument, _parent) + InstrumentViewFixedSize(_instrument, _parent) { const int COL_KNOBS = 194; diff --git a/plugins/Xpressive/Xpressive.h b/plugins/Xpressive/Xpressive.h index 422002aa8..5abee2691 100644 --- a/plugins/Xpressive/Xpressive.h +++ b/plugins/Xpressive/Xpressive.h @@ -139,7 +139,7 @@ private: } ; -class XpressiveView : public InstrumentView250 +class XpressiveView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/audio_file_processor/audio_file_processor.cpp b/plugins/audio_file_processor/audio_file_processor.cpp index 16c190170..58fa990a7 100644 --- a/plugins/audio_file_processor/audio_file_processor.cpp +++ b/plugins/audio_file_processor/audio_file_processor.cpp @@ -449,7 +449,7 @@ QPixmap * AudioFileProcessorView::s_artwork = NULL; AudioFileProcessorView::AudioFileProcessorView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { if( s_artwork == NULL ) { diff --git a/plugins/audio_file_processor/audio_file_processor.h b/plugins/audio_file_processor/audio_file_processor.h index 854c2b7cd..43ab0149c 100644 --- a/plugins/audio_file_processor/audio_file_processor.h +++ b/plugins/audio_file_processor/audio_file_processor.h @@ -111,7 +111,7 @@ private: class AudioFileProcessorWaveView; -class AudioFileProcessorView : public InstrumentView250 +class AudioFileProcessorView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/bit_invader/bit_invader.cpp b/plugins/bit_invader/bit_invader.cpp index 563e0e2eb..bb4b4ffb1 100644 --- a/plugins/bit_invader/bit_invader.cpp +++ b/plugins/bit_invader/bit_invader.cpp @@ -327,7 +327,7 @@ PluginView * bitInvader::instantiateView( QWidget * _parent ) bitInvaderView::bitInvaderView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { setAutoFillBackground( true ); QPalette pal; diff --git a/plugins/bit_invader/bit_invader.h b/plugins/bit_invader/bit_invader.h index 60b468683..793831e4a 100644 --- a/plugins/bit_invader/bit_invader.h +++ b/plugins/bit_invader/bit_invader.h @@ -108,7 +108,7 @@ private: -class bitInvaderView : public InstrumentView250 +class bitInvaderView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/carlabase/carla.cpp b/plugins/carlabase/carla.cpp index 7ab862957..3df97ce40 100644 --- a/plugins/carlabase/carla.cpp +++ b/plugins/carlabase/carla.cpp @@ -460,7 +460,7 @@ void CarlaInstrument::sampleRateChanged() // ------------------------------------------------------------------- CarlaInstrumentView::CarlaInstrumentView(CarlaInstrument* const instrument, QWidget* const parent) - : InstrumentView250(instrument, parent), + : InstrumentViewFixedSize(instrument, parent), fHandle(instrument->fHandle), fDescriptor(instrument->fDescriptor), fTimerId(fHandle != NULL && fDescriptor->ui_idle != NULL ? startTimer(30) : 0) diff --git a/plugins/carlabase/carla.h b/plugins/carlabase/carla.h index 8a169e4db..393912a50 100644 --- a/plugins/carlabase/carla.h +++ b/plugins/carlabase/carla.h @@ -99,7 +99,7 @@ private: friend class CarlaInstrumentView; }; -class CarlaInstrumentView : public InstrumentView250 +class CarlaInstrumentView : public InstrumentViewFixedSize { Q_OBJECT diff --git a/plugins/kicker/kicker.cpp b/plugins/kicker/kicker.cpp index 62e46b8b5..dbdb94a2a 100644 --- a/plugins/kicker/kicker.cpp +++ b/plugins/kicker/kicker.cpp @@ -267,7 +267,7 @@ public: kickerInstrumentView::kickerInstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { const int ROW1 = 14; const int ROW2 = ROW1 + 56; diff --git a/plugins/kicker/kicker.h b/plugins/kicker/kicker.h index f2dabd1fd..22b2b854f 100644 --- a/plugins/kicker/kicker.h +++ b/plugins/kicker/kicker.h @@ -94,7 +94,7 @@ private: -class kickerInstrumentView : public InstrumentView250 +class kickerInstrumentView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/lb302/lb302.cpp b/plugins/lb302/lb302.cpp index dc630ee92..f2f5b2399 100644 --- a/plugins/lb302/lb302.cpp +++ b/plugins/lb302/lb302.cpp @@ -804,7 +804,7 @@ PluginView * lb302Synth::instantiateView( QWidget * _parent ) lb302SynthView::lb302SynthView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { // GUI m_vcfCutKnob = new Knob( knobBright_26, this ); diff --git a/plugins/lb302/lb302.h b/plugins/lb302/lb302.h index 2d70ccee1..557d958d4 100644 --- a/plugins/lb302/lb302.h +++ b/plugins/lb302/lb302.h @@ -256,7 +256,7 @@ private: } ; -class lb302SynthView : public InstrumentView250 +class lb302SynthView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/monstro/Monstro.cpp b/plugins/monstro/Monstro.cpp index 231517abb..f462fe108 100644 --- a/plugins/monstro/Monstro.cpp +++ b/plugins/monstro/Monstro.cpp @@ -1448,7 +1448,7 @@ void MonstroInstrument::updateSlope2() MonstroView::MonstroView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { m_operatorsView = setupOperatorsView( this ); setWidgetBackground( m_operatorsView, "artwork_op" ); diff --git a/plugins/monstro/Monstro.h b/plugins/monstro/Monstro.h index 18cce7ad1..fc0cc13b0 100644 --- a/plugins/monstro/Monstro.h +++ b/plugins/monstro/Monstro.h @@ -569,7 +569,7 @@ private: }; -class MonstroView : public InstrumentView250 +class MonstroView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/nes/Nes.cpp b/plugins/nes/Nes.cpp index 345f94249..9f74883a3 100644 --- a/plugins/nes/Nes.cpp +++ b/plugins/nes/Nes.cpp @@ -732,7 +732,7 @@ QPixmap * NesInstrumentView::s_artwork = NULL; NesInstrumentView::NesInstrumentView( Instrument * instrument, QWidget * parent ) : - InstrumentView250( instrument, parent ) + InstrumentViewFixedSize( instrument, parent ) { setAutoFillBackground( true ); QPalette pal; diff --git a/plugins/nes/Nes.h b/plugins/nes/Nes.h index 855cab710..bbf326d32 100644 --- a/plugins/nes/Nes.h +++ b/plugins/nes/Nes.h @@ -294,7 +294,7 @@ private: }; -class NesInstrumentView : public InstrumentView250 +class NesInstrumentView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/organic/organic.cpp b/plugins/organic/organic.cpp index 1c9aa5ab0..3aa0d0c67 100644 --- a/plugins/organic/organic.cpp +++ b/plugins/organic/organic.cpp @@ -418,7 +418,7 @@ public: organicInstrumentView::organicInstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ), + InstrumentViewFixedSize( _instrument, _parent ), m_oscKnobs( NULL ) { organicInstrument * oi = castModel(); diff --git a/plugins/organic/organic.h b/plugins/organic/organic.h index 083fa6333..c0bc29f16 100644 --- a/plugins/organic/organic.h +++ b/plugins/organic/organic.h @@ -173,7 +173,7 @@ private slots: } ; -class organicInstrumentView : public InstrumentView250 +class organicInstrumentView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/patman/patman.cpp b/plugins/patman/patman.cpp index 61368a575..1402de306 100644 --- a/plugins/patman/patman.cpp +++ b/plugins/patman/patman.cpp @@ -443,7 +443,7 @@ PluginView * patmanInstrument::instantiateView( QWidget * _parent ) PatmanView::PatmanView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ), + InstrumentViewFixedSize( _instrument, _parent ), m_pi( NULL ) { setAutoFillBackground( true ); diff --git a/plugins/patman/patman.h b/plugins/patman/patman.h index 014a7d63c..8d5689b73 100644 --- a/plugins/patman/patman.h +++ b/plugins/patman/patman.h @@ -116,7 +116,7 @@ signals: -class PatmanView : public InstrumentView250 +class PatmanView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index f0676dc8c..b10a5d9a4 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -859,7 +859,7 @@ public: sf2InstrumentView::sf2InstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { // QVBoxLayout * vl = new QVBoxLayout( this ); // QHBoxLayout * hl = new QHBoxLayout(); diff --git a/plugins/sf2_player/sf2_player.h b/plugins/sf2_player/sf2_player.h index 20da89adb..1dde587ad 100644 --- a/plugins/sf2_player/sf2_player.h +++ b/plugins/sf2_player/sf2_player.h @@ -187,7 +187,7 @@ public: -class sf2InstrumentView : public InstrumentView250 +class sf2InstrumentView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/sfxr/sfxr.cpp b/plugins/sfxr/sfxr.cpp index c954e72a0..1fd0be9de 100644 --- a/plugins/sfxr/sfxr.cpp +++ b/plugins/sfxr/sfxr.cpp @@ -601,7 +601,7 @@ public: sfxrInstrumentView::sfxrInstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { srand(time(NULL)); setAutoFillBackground( true ); diff --git a/plugins/sfxr/sfxr.h b/plugins/sfxr/sfxr.h index dc601d322..20ae54c96 100644 --- a/plugins/sfxr/sfxr.h +++ b/plugins/sfxr/sfxr.h @@ -223,7 +223,7 @@ private: -class sfxrInstrumentView : public InstrumentView250 +class sfxrInstrumentView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/sid/sid_instrument.cpp b/plugins/sid/sid_instrument.cpp index 2df551f20..edb3181a6 100644 --- a/plugins/sid/sid_instrument.cpp +++ b/plugins/sid/sid_instrument.cpp @@ -481,7 +481,7 @@ public: sidInstrumentView::sidInstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { setAutoFillBackground( true ); diff --git a/plugins/sid/sid_instrument.h b/plugins/sid/sid_instrument.h index 2649b9cba..479d09c5d 100644 --- a/plugins/sid/sid_instrument.h +++ b/plugins/sid/sid_instrument.h @@ -132,7 +132,7 @@ private: -class sidInstrumentView : public InstrumentView250 +class sidInstrumentView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/stk/mallets/mallets.cpp b/plugins/stk/mallets/mallets.cpp index a39cd689c..2d7163975 100644 --- a/plugins/stk/mallets/mallets.cpp +++ b/plugins/stk/mallets/mallets.cpp @@ -384,7 +384,7 @@ PluginView * malletsInstrument::instantiateView( QWidget * _parent ) malletsInstrumentView::malletsInstrumentView( malletsInstrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { m_modalBarWidget = setupModalBarControls( this ); setWidgetBackground( m_modalBarWidget, "artwork" ); diff --git a/plugins/stk/mallets/mallets.h b/plugins/stk/mallets/mallets.h index ec13f5eb9..6fd28d41c 100644 --- a/plugins/stk/mallets/mallets.h +++ b/plugins/stk/mallets/mallets.h @@ -187,7 +187,7 @@ private: } ; -class malletsInstrumentView: public InstrumentView250 +class malletsInstrumentView: public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/triple_oscillator/TripleOscillator.cpp b/plugins/triple_oscillator/TripleOscillator.cpp index fa4f3b4ae..e8d8547d9 100644 --- a/plugins/triple_oscillator/TripleOscillator.cpp +++ b/plugins/triple_oscillator/TripleOscillator.cpp @@ -419,7 +419,7 @@ public: TripleOscillatorView::TripleOscillatorView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { setAutoFillBackground( true ); QPalette pal; diff --git a/plugins/triple_oscillator/TripleOscillator.h b/plugins/triple_oscillator/TripleOscillator.h index b45fea1f3..815fa3505 100644 --- a/plugins/triple_oscillator/TripleOscillator.h +++ b/plugins/triple_oscillator/TripleOscillator.h @@ -136,7 +136,7 @@ private: -class TripleOscillatorView : public InstrumentView250 +class TripleOscillatorView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index c06a771d3..10a156185 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -460,7 +460,7 @@ PluginView * vestigeInstrument::instantiateView( QWidget * _parent ) VestigeInstrumentView::VestigeInstrumentView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ), + InstrumentViewFixedSize( _instrument, _parent ), lastPosInMenu (0) { if( s_artwork == NULL ) @@ -892,7 +892,7 @@ void VestigeInstrumentView::paintEvent( QPaintEvent * ) manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrument, QWidget * _parent, vestigeInstrument * m_vi2 ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { m_vi = m_vi2; m_vi->m_scrollArea = new QScrollArea( this ); diff --git a/plugins/vestige/vestige.h b/plugins/vestige/vestige.h index 423146497..9d74918fd 100644 --- a/plugins/vestige/vestige.h +++ b/plugins/vestige/vestige.h @@ -98,7 +98,7 @@ private: } ; -class manageVestigeInstrumentView : public InstrumentView250 +class manageVestigeInstrumentView : public InstrumentViewFixedSize { Q_OBJECT public: @@ -134,7 +134,7 @@ private: } ; -class VestigeInstrumentView : public InstrumentView250 +class VestigeInstrumentView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/vibed/vibed.cpp b/plugins/vibed/vibed.cpp index f0c347b7c..e560b692b 100644 --- a/plugins/vibed/vibed.cpp +++ b/plugins/vibed/vibed.cpp @@ -350,7 +350,7 @@ PluginView * vibed::instantiateView( QWidget * _parent ) vibedView::vibedView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { setAutoFillBackground( true ); QPalette pal; diff --git a/plugins/vibed/vibed.h b/plugins/vibed/vibed.h index 039b88d24..b1c33f4b7 100644 --- a/plugins/vibed/vibed.h +++ b/plugins/vibed/vibed.h @@ -82,7 +82,7 @@ private: -class vibedView : public InstrumentView250 +class vibedView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/watsyn/Watsyn.cpp b/plugins/watsyn/Watsyn.cpp index 9d45531d5..332e34117 100644 --- a/plugins/watsyn/Watsyn.cpp +++ b/plugins/watsyn/Watsyn.cpp @@ -667,7 +667,7 @@ void WatsynInstrument::updateWaveB2() WatsynView::WatsynView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { setAutoFillBackground( true ); QPalette pal; diff --git a/plugins/watsyn/Watsyn.h b/plugins/watsyn/Watsyn.h index 27cd65e47..079e532e4 100644 --- a/plugins/watsyn/Watsyn.h +++ b/plugins/watsyn/Watsyn.h @@ -293,7 +293,7 @@ private: }; -class WatsynView : public InstrumentView250 +class WatsynView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index 42340ab62..214896a9c 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -488,7 +488,7 @@ PluginView * ZynAddSubFxInstrument::instantiateView( QWidget * _parent ) ZynAddSubFxView::ZynAddSubFxView( Instrument * _instrument, QWidget * _parent ) : - InstrumentView250( _instrument, _parent ) + InstrumentViewFixedSize( _instrument, _parent ) { setAutoFillBackground( true ); QPalette pal; diff --git a/plugins/zynaddsubfx/ZynAddSubFx.h b/plugins/zynaddsubfx/ZynAddSubFx.h index 88d70d83b..6f5bc754d 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.h +++ b/plugins/zynaddsubfx/ZynAddSubFx.h @@ -132,7 +132,7 @@ signals: -class ZynAddSubFxView : public InstrumentView250 +class ZynAddSubFxView : public InstrumentViewFixedSize { Q_OBJECT public: diff --git a/src/gui/InstrumentView.cpp b/src/gui/InstrumentView.cpp index 86b2fcc91..44fcc2a8a 100644 --- a/src/gui/InstrumentView.cpp +++ b/src/gui/InstrumentView.cpp @@ -73,7 +73,7 @@ InstrumentTrackWindow * InstrumentView::instrumentTrackWindow( void ) -InstrumentView250::~InstrumentView250() +InstrumentViewFixedSize::~InstrumentViewFixedSize() { } From c3b4d5188aadd3b149e10beacf213ec209c63da5 Mon Sep 17 00:00:00 2001 From: Martin Pavelek Date: Wed, 17 Jul 2019 22:45:26 +0200 Subject: [PATCH 350/445] New Spectrum Analyzer (#4950) Replace old spectrum analyzer by new one with higher resolution and many new features. Resolves #2847. --- include/EffectControlDialog.h | 2 + include/SubWindow.h | 1 - include/fft_helpers.h | 96 ++- plugins/SpectrumAnalyzer/Analyzer.cpp | 75 ++ ...trumAnalyzerControlDialog.h => Analyzer.h} | 46 +- plugins/SpectrumAnalyzer/CMakeLists.txt | 3 +- plugins/SpectrumAnalyzer/README.md | 19 + plugins/SpectrumAnalyzer/SaControls.cpp | 144 ++++ plugins/SpectrumAnalyzer/SaControls.h | 126 +++ plugins/SpectrumAnalyzer/SaControlsDialog.cpp | 227 +++++ plugins/SpectrumAnalyzer/SaControlsDialog.h | 57 ++ plugins/SpectrumAnalyzer/SaProcessor.cpp | 571 +++++++++++++ plugins/SpectrumAnalyzer/SaProcessor.h | 122 +++ plugins/SpectrumAnalyzer/SaSpectrumView.cpp | 796 ++++++++++++++++++ plugins/SpectrumAnalyzer/SaSpectrumView.h | 126 +++ plugins/SpectrumAnalyzer/SaWaterfallView.cpp | 230 +++++ plugins/SpectrumAnalyzer/SaWaterfallView.h | 66 ++ plugins/SpectrumAnalyzer/SpectrumAnalyzer.cpp | 172 ---- plugins/SpectrumAnalyzer/SpectrumAnalyzer.h | 78 -- .../SpectrumAnalyzerControlDialog.cpp | 194 ----- .../SpectrumAnalyzerControls.cpp | 61 -- .../SpectrumAnalyzerControls.h | 75 -- plugins/SpectrumAnalyzer/background.png | Bin 859 -> 0 bytes plugins/SpectrumAnalyzer/block_size.svg | 273 ++++++ plugins/SpectrumAnalyzer/freeze.svg | 296 +++++++ plugins/SpectrumAnalyzer/freeze_off.svg | 297 +++++++ plugins/SpectrumAnalyzer/log_x_axis.png | Bin 1293 -> 0 bytes plugins/SpectrumAnalyzer/log_y_axis.png | Bin 734 -> 0 bytes plugins/SpectrumAnalyzer/pause.svg | 220 +++++ plugins/SpectrumAnalyzer/play.svg | 219 +++++ .../SpectrumAnalyzer/spectrum_background.png | Bin 1849 -> 0 bytes .../spectrum_background_plain.png | Bin 819 -> 0 bytes plugins/SpectrumAnalyzer/window.svg | 232 +++++ plugins/SpectrumAnalyzer/x_linear.svg | 242 ++++++ plugins/SpectrumAnalyzer/x_log.svg | 240 ++++++ plugins/SpectrumAnalyzer/y_linear.svg | 240 ++++++ plugins/SpectrumAnalyzer/y_log.svg | 240 ++++++ src/core/fft_helpers.cpp | 277 +++--- src/gui/MainWindow.cpp | 1 + src/gui/SubWindow.cpp | 1 + src/gui/widgets/EffectView.cpp | 11 +- src/gui/widgets/PixmapButton.cpp | 4 +- 42 files changed, 5329 insertions(+), 751 deletions(-) create mode 100644 plugins/SpectrumAnalyzer/Analyzer.cpp rename plugins/SpectrumAnalyzer/{SpectrumAnalyzerControlDialog.h => Analyzer.h} (50%) create mode 100644 plugins/SpectrumAnalyzer/README.md create mode 100644 plugins/SpectrumAnalyzer/SaControls.cpp create mode 100644 plugins/SpectrumAnalyzer/SaControls.h create mode 100644 plugins/SpectrumAnalyzer/SaControlsDialog.cpp create mode 100644 plugins/SpectrumAnalyzer/SaControlsDialog.h create mode 100644 plugins/SpectrumAnalyzer/SaProcessor.cpp create mode 100644 plugins/SpectrumAnalyzer/SaProcessor.h create mode 100644 plugins/SpectrumAnalyzer/SaSpectrumView.cpp create mode 100644 plugins/SpectrumAnalyzer/SaSpectrumView.h create mode 100644 plugins/SpectrumAnalyzer/SaWaterfallView.cpp create mode 100644 plugins/SpectrumAnalyzer/SaWaterfallView.h delete mode 100644 plugins/SpectrumAnalyzer/SpectrumAnalyzer.cpp delete mode 100644 plugins/SpectrumAnalyzer/SpectrumAnalyzer.h delete mode 100644 plugins/SpectrumAnalyzer/SpectrumAnalyzerControlDialog.cpp delete mode 100644 plugins/SpectrumAnalyzer/SpectrumAnalyzerControls.cpp delete mode 100644 plugins/SpectrumAnalyzer/SpectrumAnalyzerControls.h delete mode 100644 plugins/SpectrumAnalyzer/background.png create mode 100644 plugins/SpectrumAnalyzer/block_size.svg create mode 100644 plugins/SpectrumAnalyzer/freeze.svg create mode 100644 plugins/SpectrumAnalyzer/freeze_off.svg delete mode 100644 plugins/SpectrumAnalyzer/log_x_axis.png delete mode 100644 plugins/SpectrumAnalyzer/log_y_axis.png create mode 100644 plugins/SpectrumAnalyzer/pause.svg create mode 100644 plugins/SpectrumAnalyzer/play.svg delete mode 100644 plugins/SpectrumAnalyzer/spectrum_background.png delete mode 100644 plugins/SpectrumAnalyzer/spectrum_background_plain.png create mode 100644 plugins/SpectrumAnalyzer/window.svg create mode 100644 plugins/SpectrumAnalyzer/x_linear.svg create mode 100644 plugins/SpectrumAnalyzer/x_log.svg create mode 100644 plugins/SpectrumAnalyzer/y_linear.svg create mode 100644 plugins/SpectrumAnalyzer/y_log.svg diff --git a/include/EffectControlDialog.h b/include/EffectControlDialog.h index 712f31217..c0a60cfa6 100644 --- a/include/EffectControlDialog.h +++ b/include/EffectControlDialog.h @@ -40,6 +40,8 @@ public: EffectControlDialog( EffectControls * _controls ); virtual ~EffectControlDialog(); + virtual bool isResizable() const {return false;} + signals: void closed(); diff --git a/include/SubWindow.h b/include/SubWindow.h index f6247d061..5d7a810c2 100644 --- a/include/SubWindow.h +++ b/include/SubWindow.h @@ -30,7 +30,6 @@ #include #include #include -#include #include #include diff --git a/include/fft_helpers.h b/include/fft_helpers.h index 23450d2ca..876510f8b 100644 --- a/include/fft_helpers.h +++ b/include/fft_helpers.h @@ -2,6 +2,7 @@ * fft_helpers.h - some functions around FFT analysis * * Copyright (c) 2008-2012 Tobias Doerffel + * Copyright (c) 2019 Martin Pavelek * * This file is part of LMMS - https://lmms.io * @@ -28,57 +29,90 @@ #include "lmms_export.h" +#include #include -const int FFT_BUFFER_SIZE = 2048; +// NOTE: FFT_BUFFER_SIZE should be considered deprecated! +// It is used by Eq plugin and some older code here, but this should be a user +// switchable parameter, not a constant. Use a value from FFT_BLOCK_SIZES +const unsigned int FFT_BUFFER_SIZE = 2048; -enum WINDOWS +// Allowed FFT block sizes. Ranging from barely useful to barely acceptable +// because of performance and latency reasons. +const std::vector FFT_BLOCK_SIZES = {256, 512, 1024, 2048, 4096, 8192, 16384}; + +// List of FFT window functions supported by precomputeWindow() +enum FFT_WINDOWS { - KAISER=1, - RECTANGLE, - HANNING, - HAMMING + RECTANGULAR = 0, + BLACKMAN_HARRIS, + HAMMING, + HANNING }; -/* returns biggest value from abs_spectrum[spec_size] array + +/** Returns biggest value from abs_spectrum[spec_size] array. * - * returns -1 on error + * @return -1 on error, 0 on success */ -float LMMS_EXPORT maximum( float * _abs_spectrum, unsigned int _spec_size ); +float LMMS_EXPORT maximum(const float *abs_spectrum, unsigned int spec_size); +float LMMS_EXPORT maximum(const std::vector &abs_spectrum); -/* apply hanning or hamming window to channel + +/** Normalize the abs_spectrum array of absolute values to a 0..1 range + * based on supplied energy and stores it in the norm_spectrum array. * - * returns -1 on error + * @return -1 on error */ -int LMMS_EXPORT hanming( float * _timebuffer, int _length, WINDOWS _type ); +int LMMS_EXPORT normalize(const float *abs_spectrum, float *norm_spectrum, unsigned int bin_count, unsigned int block_size); +int LMMS_EXPORT normalize(const std::vector &abs_spectrum, std::vector &norm_spectrum, unsigned int block_size); -/* compute absolute values of complex_buffer, save to absspec_buffer - * take care that - compl_len is not bigger than complex_buffer! - * - absspec buffer is big enough! + +/** Check if the spectrum contains any non-zero value. * - * returns 0 on success, else -1 + * @return 1 if spectrum contains any non-zero value + * @return 0 otherwise */ -int LMMS_EXPORT absspec( fftwf_complex * _complex_buffer, float * _absspec_buffer, - int _compl_length ); +int LMMS_EXPORT notEmpty(const std::vector &spectrum); -/* build fewer subbands from many absolute spectrum values - * take care that - compressedbands[] array num_new elements long - * - num_old > num_new + +/** Precompute a window function for later real-time use. + * Set normalized to false if you do not want to apply amplitude correction. * - * returns 0 on success, else -1 + * @return -1 on error */ -int LMMS_EXPORT compressbands( float * _absspec_buffer, float * _compressedband, - int _num_old, int _num_new, int _bottom, int _top ); +int LMMS_EXPORT precomputeWindow(float *window, unsigned int length, FFT_WINDOWS type, bool normalized = true); -int LMMS_EXPORT calc13octaveband31( float * _absspec_buffer, float * _subbands, - int _num_spec, float _max_frequency ); - -/* compute power of finite time sequence - * take care num_values is length of timesignal[] +/** Compute absolute values of complex_buffer, save to absspec_buffer. + * Take care that - compl_len is not bigger than complex_buffer! + * - absspec buffer is big enough! * - * returns power on success, else -1 + * @return 0 on success, else -1 */ -float LMMS_EXPORT signalpower(float *timesignal, int num_values); +int LMMS_EXPORT absspec(const fftwf_complex *complex_buffer, float *absspec_buffer, + unsigned int compl_length); + + +/** Build fewer subbands from many absolute spectrum values. + * Take care that - compressedbands[] array num_new elements long + * - num_old > num_new + * + * @return 0 on success, else -1 + */ +int LMMS_EXPORT compressbands(const float * _absspec_buffer, float * _compressedband, + int _num_old, int _num_new, int _bottom, int _top); + + +int LMMS_EXPORT calc13octaveband31(float * _absspec_buffer, float * _subbands, + int _num_spec, float _max_frequency); + + +/** Compute power of finite time sequence. + * Take care num_values is length of timesignal[]. + * + * @return power on success, else -1 + */ +float LMMS_EXPORT signalpower(const float *timesignal, int num_values); #endif diff --git a/plugins/SpectrumAnalyzer/Analyzer.cpp b/plugins/SpectrumAnalyzer/Analyzer.cpp new file mode 100644 index 000000000..9c3fe0814 --- /dev/null +++ b/plugins/SpectrumAnalyzer/Analyzer.cpp @@ -0,0 +1,75 @@ +/* + * Analyzer.cpp - definition of Analyzer class. + * + * Copyright (c) 2019 Martin Pavelek + * + * Based partially on Eq plugin code, + * Copyright (c) 2014-2017, David French + * + * 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 "Analyzer.h" + +#include "embed.h" +#include "plugin_export.h" + + +extern "C" { + Plugin::Descriptor PLUGIN_EXPORT analyzer_plugin_descriptor = + { + "spectrumanalyzer", + "Spectrum Analyzer", + QT_TRANSLATE_NOOP("pluginBrowser", "A graphical spectrum analyzer."), + "Martin Pavelek ", + 0x0100, + Plugin::Effect, + new PluginPixmapLoader("logo"), + NULL, + NULL + }; +} + + +Analyzer::Analyzer(Model *parent, const Plugin::Descriptor::SubPluginFeatures::Key *key) : + Effect(&analyzer_plugin_descriptor, parent, key), + m_processor(&m_controls), + m_controls(this) +{ +} + + +// Take audio data and pass them to the spectrum processor. +// Skip processing if the controls dialog isn't visible, it would only waste CPU cycles. +bool Analyzer::processAudioBuffer(sampleFrame *buffer, const fpp_t frame_count) +{ + if (!isEnabled() || !isRunning ()) {return false;} + if (m_controls.isViewVisible()) {m_processor.analyse(buffer, frame_count);} + return isRunning(); +} + + +extern "C" { + // needed for getting plugin out of shared lib + PLUGIN_EXPORT Plugin *lmms_plugin_main(Model *parent, void *data) + { + return new Analyzer(parent, static_cast(data)); + } +} + diff --git a/plugins/SpectrumAnalyzer/SpectrumAnalyzerControlDialog.h b/plugins/SpectrumAnalyzer/Analyzer.h similarity index 50% rename from plugins/SpectrumAnalyzer/SpectrumAnalyzerControlDialog.h rename to plugins/SpectrumAnalyzer/Analyzer.h index 17e2f7724..157cc1eae 100644 --- a/plugins/SpectrumAnalyzer/SpectrumAnalyzerControlDialog.h +++ b/plugins/SpectrumAnalyzer/Analyzer.h @@ -1,7 +1,9 @@ -/* - * SpectrumAnalyzerControlDialog.h - view for spectrum analyzer +/* Analyzer.h - declaration of Analyzer class. * - * Copyright (c) 2008-2014 Tobias Doerffel + * Copyright (c) 2019 Martin Pavelek + * + * Based partially on Eq plugin code, + * Copyright (c) 2014-2017, David French * * This file is part of LMMS - https://lmms.io * @@ -22,32 +24,30 @@ * */ -#ifndef _SPECTRUM_ANALYZER_CONTROL_DIALOG_H -#define _SPECTRUM_ANALYZER_CONTROL_DIALOG_H +#ifndef ANALYZER_H +#define ANALYZER_H -#include "EffectControlDialog.h" +#include "Effect.h" +#include "SaControls.h" +#include "SaProcessor.h" -class SpectrumAnalyzerControls; - - -class SpectrumAnalyzerControlDialog : public EffectControlDialog +//! Top level class; handles LMMS interface and feeds data to the data processor. +class Analyzer : public Effect { - Q_OBJECT public: - SpectrumAnalyzerControlDialog( SpectrumAnalyzerControls* controls ); - virtual ~SpectrumAnalyzerControlDialog() - { - } + Analyzer(Model *parent, const Descriptor::SubPluginFeatures::Key *key); + virtual ~Analyzer() {}; + + bool processAudioBuffer(sampleFrame *buffer, const fpp_t frame_count) override; + EffectControls *controls() override {return &m_controls;} + + SaProcessor *getProcessor() {return &m_processor;} private: - virtual void paintEvent( QPaintEvent* event ); + SaProcessor m_processor; + SaControls m_controls; +}; - SpectrumAnalyzerControls* m_controls; +#endif // ANALYZER_H - QPixmap m_logXAxis; - QPixmap m_logYAxis; - -} ; - -#endif diff --git a/plugins/SpectrumAnalyzer/CMakeLists.txt b/plugins/SpectrumAnalyzer/CMakeLists.txt index 29187b39d..630fbf1be 100644 --- a/plugins/SpectrumAnalyzer/CMakeLists.txt +++ b/plugins/SpectrumAnalyzer/CMakeLists.txt @@ -1,4 +1,5 @@ INCLUDE(BuildPlugin) INCLUDE_DIRECTORIES(${FFTW3F_INCLUDE_DIRS}) LINK_LIBRARIES(${FFTW3F_LIBRARIES}) -BUILD_PLUGIN(spectrumanalyzer SpectrumAnalyzer.cpp SpectrumAnalyzerControls.cpp SpectrumAnalyzerControlDialog.cpp SpectrumAnalyzer.h SpectrumAnalyzerControls.h SpectrumAnalyzerControlDialog.h MOCFILES SpectrumAnalyzerControlDialog.h SpectrumAnalyzerControls.h EMBEDDED_RESOURCES *.png) +BUILD_PLUGIN(analyzer Analyzer.cpp SaProcessor.cpp SaControls.cpp SaControlsDialog.cpp SaSpectrumView.cpp SaWaterfallView.cpp +MOCFILES SaProcessor.h SaControls.h SaControlsDialog.h SaSpectrumView.h SaWaterfallView.h EMBEDDED_RESOURCES *.svg logo.png) diff --git a/plugins/SpectrumAnalyzer/README.md b/plugins/SpectrumAnalyzer/README.md new file mode 100644 index 000000000..3d3506d65 --- /dev/null +++ b/plugins/SpectrumAnalyzer/README.md @@ -0,0 +1,19 @@ +# Spectrum Analyzer plugin + +## Overview + +This plugin consists of three widgets and back-end code to provide them with required data. + +The top-level widget is SaControlDialog. It populates a configuration widget (created dynamically) and instantiates spectrum display widgets. Its main back-end class is SaControls, which holds all configuration values and globally valid constants (e.g. range definitions). + +SaSpectrumDisplay and SaWaterfallDisplay show the result of spectrum analysis. Their main back-end class is SaProcessor, which performs FFT analysis on data received from the Analyzer class, which in turn handles the interface with LMMS. + + +## Changelog + + 1.0.1 2019-06-02 + - code style changes + - added tool-tips + - use const for unmodified arrays passed to fft_helpers + 1.0.0 2019-04-07 + - initial release diff --git a/plugins/SpectrumAnalyzer/SaControls.cpp b/plugins/SpectrumAnalyzer/SaControls.cpp new file mode 100644 index 000000000..5691c0ae4 --- /dev/null +++ b/plugins/SpectrumAnalyzer/SaControls.cpp @@ -0,0 +1,144 @@ +/* + * SaControls.cpp - definition of SaControls class. + * + * Copyright (c) 2019 Martin Pavelek + * + * 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 "SaControls.h" + +#include + +#include "Analyzer.h" +#include "SaControlsDialog.h" + + +SaControls::SaControls(Analyzer *effect) : + EffectControls(effect), + m_effect(effect), + + // initialize bool models and set default values + m_pauseModel(false, this, tr("Pause")), + m_refFreezeModel(false, this, tr("Reference freeze")), + + m_waterfallModel(false, this, tr("Waterfall")), + m_smoothModel(false, this, tr("Averaging")), + m_stereoModel(false, this, tr("Stereo")), + m_peakHoldModel(false, this, tr("Peak hold")), + + m_logXModel(true, this, tr("Logarithmic frequency")), + m_logYModel(true, this, tr("Logarithmic amplitude")), + + // default values of combo boxes are set after they are populated + m_freqRangeModel(this, tr("Frequency range")), + m_ampRangeModel(this, tr("Amplitude range")), + m_blockSizeModel(this, tr("FFT block size")), + m_windowModel(this, tr("FFT window type")) +{ + // Frequency and amplitude ranges; order must match + // FREQUENCY_RANGES and AMPLITUDE_RANGES defined in SaControls.h + m_freqRangeModel.addItem(tr("Full (auto)")); + m_freqRangeModel.addItem(tr("Audible")); + m_freqRangeModel.addItem(tr("Bass")); + m_freqRangeModel.addItem(tr("Mids")); + m_freqRangeModel.addItem(tr("High")); + m_freqRangeModel.setValue(m_freqRangeModel.findText(tr("Full (auto)"))); + + m_ampRangeModel.addItem(tr("Extended")); + m_ampRangeModel.addItem(tr("Default")); + m_ampRangeModel.addItem(tr("Audible")); + m_ampRangeModel.addItem(tr("Noise")); + m_ampRangeModel.setValue(m_ampRangeModel.findText(tr("Default"))); + + // FFT block size labels are generated automatically, based on + // FFT_BLOCK_SIZES vector defined in fft_helpers.h + for (unsigned int i = 0; i < FFT_BLOCK_SIZES.size(); i++) + { + if (i == 0) + { + m_blockSizeModel.addItem((std::to_string(FFT_BLOCK_SIZES[i]) + " ").c_str() + tr("(High time res.)")); + } + else if (i == FFT_BLOCK_SIZES.size() - 1) + { + m_blockSizeModel.addItem((std::to_string(FFT_BLOCK_SIZES[i]) + " ").c_str() + tr("(High freq. res.)")); + } + else + { + m_blockSizeModel.addItem(std::to_string(FFT_BLOCK_SIZES[i]).c_str()); + } + } + m_blockSizeModel.setValue(m_blockSizeModel.findText("2048")); + + // Window type order must match FFT_WINDOWS defined in fft_helpers.h + m_windowModel.addItem(tr("Rectangular (Off)")); + m_windowModel.addItem(tr("Blackman-Harris (Default)")); + m_windowModel.addItem(tr("Hamming")); + m_windowModel.addItem(tr("Hanning")); + m_windowModel.setValue(m_windowModel.findText(tr("Blackman-Harris (Default)"))); + + // Colors + // Background color is defined by Qt / theme. + // Make sure the sum of colors for L and R channel stays lower or equal + // to 255. Otherwise the Waterfall pixels may overflow back to 0 even when + // the input signal isn't clipping (over 1.0). + m_colorL = QColor(51, 148, 204, 135); + m_colorR = QColor(204, 107, 51, 135); + m_colorMono = QColor(51, 148, 204, 204); + m_colorBG = QColor(7, 7, 7, 255); // ~20 % gray (after gamma correction) + m_colorGrid = QColor(30, 34, 38, 255); // ~40 % gray (slightly cold / blue) + m_colorLabels = QColor(192, 202, 212, 255); // ~90 % gray (slightly cold / blue) +} + + +// Create the SaControlDialog widget which handles display of GUI elements. +EffectControlDialog* SaControls::createView() +{ + return new SaControlsDialog(this, m_effect->getProcessor()); +} + + +void SaControls::loadSettings(const QDomElement &_this) +{ + m_waterfallModel.loadSettings(_this, "Waterfall"); + m_smoothModel.loadSettings(_this, "Smooth"); + m_stereoModel.loadSettings(_this, "Stereo"); + m_peakHoldModel.loadSettings(_this, "PeakHold"); + m_logXModel.loadSettings(_this, "LogX"); + m_logYModel.loadSettings(_this, "LogY"); + m_freqRangeModel.loadSettings(_this, "RangeX"); + m_ampRangeModel.loadSettings(_this, "RangeY"); + m_blockSizeModel.loadSettings(_this, "BlockSize"); + m_windowModel.loadSettings(_this, "WindowType"); +} + + +void SaControls::saveSettings(QDomDocument &doc, QDomElement &parent) +{ + m_waterfallModel.saveSettings(doc, parent, "Waterfall"); + m_smoothModel.saveSettings(doc, parent, "Smooth"); + m_stereoModel.saveSettings(doc, parent, "Stereo"); + m_peakHoldModel.saveSettings(doc, parent, "PeakHold"); + m_logXModel.saveSettings(doc, parent, "LogX"); + m_logYModel.saveSettings(doc, parent, "LogY"); + m_freqRangeModel.saveSettings(doc, parent, "RangeX"); + m_ampRangeModel.saveSettings(doc, parent, "RangeY"); + m_blockSizeModel.saveSettings(doc, parent, "BlockSize"); + m_windowModel.saveSettings(doc, parent, "WindowType"); +} diff --git a/plugins/SpectrumAnalyzer/SaControls.h b/plugins/SpectrumAnalyzer/SaControls.h new file mode 100644 index 000000000..e0b54e6a2 --- /dev/null +++ b/plugins/SpectrumAnalyzer/SaControls.h @@ -0,0 +1,126 @@ +/* + * SaControls.h - declaration of SaControls class. + * + * Copyright (c) 2019 Martin Pavelek + * + * 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 SACONTROLS_H +#define SACONTROLS_H + +#include "ComboBoxModel.h" +#include "EffectControls.h" + +//#define SA_DEBUG 1 // define SA_DEBUG to enable performance measurements + +// Frequency ranges (in Hz). +// Full range is defined by LOWEST_LOG_FREQ and current sample rate. +const int LOWEST_LOG_FREQ = 10; // arbitrary low limit for log. scale, >1 + +enum FREQUENCY_RANGES +{ + FRANGE_FULL = 0, + FRANGE_AUDIBLE, + FRANGE_BASS, + FRANGE_MIDS, + FRANGE_HIGH +}; + +const int FRANGE_AUDIBLE_START = 20; +const int FRANGE_AUDIBLE_END = 20000; +const int FRANGE_BASS_START = 20; +const int FRANGE_BASS_END = 300; +const int FRANGE_MIDS_START = 200; +const int FRANGE_MIDS_END = 5000; +const int FRANGE_HIGH_START = 4000; +const int FRANGE_HIGH_END = 20000; + +// Amplitude ranges. +// Reference: sine wave from -1.0 to 1.0 = 0 dB. +// I.e. if master volume is 100 %, positive values signify clipping. +// Doubling or halving the amplitude produces 3 dB difference. +enum AMPLITUDE_RANGES +{ + ARANGE_EXTENDED = 0, + ARANGE_DEFAULT, + ARANGE_AUDIBLE, + ARANGE_NOISE +}; + +const int ARANGE_EXTENDED_START = -80; +const int ARANGE_EXTENDED_END = 20; +const int ARANGE_DEFAULT_START = -30; +const int ARANGE_DEFAULT_END = 0; +const int ARANGE_AUDIBLE_START = -50; +const int ARANGE_AUDIBLE_END = 10; +const int ARANGE_NOISE_START = -60; +const int ARANGE_NOISE_END = -20; + + +class Analyzer; + +// Holds all the configuration values +class SaControls : public EffectControls +{ + Q_OBJECT +public: + explicit SaControls(Analyzer* effect); + virtual ~SaControls() {} + + EffectControlDialog* createView() override; + + void saveSettings (QDomDocument& doc, QDomElement& parent) override; + void loadSettings (const QDomElement &_this) override; + + QString nodeName() const override {return "Analyzer";} + int controlCount() override {return 12;} + +private: + Analyzer *m_effect; + + BoolModel m_pauseModel; + BoolModel m_refFreezeModel; + + BoolModel m_waterfallModel; + BoolModel m_smoothModel; + BoolModel m_stereoModel; + BoolModel m_peakHoldModel; + + BoolModel m_logXModel; + BoolModel m_logYModel; + + ComboBoxModel m_freqRangeModel; + ComboBoxModel m_ampRangeModel; + ComboBoxModel m_blockSizeModel; + ComboBoxModel m_windowModel; + + QColor m_colorL; + QColor m_colorR; + QColor m_colorMono; + QColor m_colorBG; + QColor m_colorGrid; + QColor m_colorLabels; + + friend class SaControlsDialog; + friend class SaSpectrumView; + friend class SaWaterfallView; + friend class SaProcessor; +}; +#endif // SACONTROLS_H diff --git a/plugins/SpectrumAnalyzer/SaControlsDialog.cpp b/plugins/SpectrumAnalyzer/SaControlsDialog.cpp new file mode 100644 index 000000000..4ba307a4d --- /dev/null +++ b/plugins/SpectrumAnalyzer/SaControlsDialog.cpp @@ -0,0 +1,227 @@ +/* + * SaControlsDialog.cpp - definition of SaControlsDialog class. + * + * Copyright (c) 2019 Martin Pavelek + * + * 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 "SaControlsDialog.h" + +#include +#include +#include +#include +#include + +#include "ComboBox.h" +#include "ComboBoxModel.h" +#include "embed.h" +#include "Engine.h" +#include "LedCheckbox.h" +#include "PixmapButton.h" +#include "SaControls.h" +#include "SaProcessor.h" + + +// The entire GUI layout is built here. +SaControlsDialog::SaControlsDialog(SaControls *controls, SaProcessor *processor) : + EffectControlDialog(controls), + m_controls(controls), + m_processor(processor) +{ + // Top level placement of sections is handled by QSplitter widget. + QHBoxLayout *master_layout = new QHBoxLayout; + QSplitter *display_splitter = new QSplitter(Qt::Vertical); + master_layout->addWidget(display_splitter); + master_layout->setContentsMargins(2, 6, 2, 8); + setLayout(master_layout); + + // QSplitter top: configuration section + QWidget *config_widget = new QWidget; + QGridLayout *config_layout = new QGridLayout; + config_widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + config_widget->setMaximumHeight(m_configHeight); + config_widget->setLayout(config_layout); + display_splitter->addWidget(config_widget); + + // Pre-compute target pixmap size based on monitor DPI. + // Using setDevicePixelRatio() on pixmap allows the SVG image to be razor + // sharp on High-DPI screens, but the desired size must be manually + // enlarged. No idea how to make Qt do it in a more reasonable way. + QSize iconSize = QSize(22.0 * devicePixelRatio(), 22.0 * devicePixelRatio()); + QSize buttonSize = 1.2 * iconSize; + + // pause and freeze buttons + PixmapButton *pauseButton = new PixmapButton(this, tr("Pause")); + pauseButton->setToolTip(tr("Pause data acquisition")); + QPixmap *pauseOnPixmap = new QPixmap(PLUGIN_NAME::getIconPixmap("play").scaled(buttonSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + QPixmap *pauseOffPixmap = new QPixmap(PLUGIN_NAME::getIconPixmap("pause").scaled(buttonSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + pauseOnPixmap->setDevicePixelRatio(devicePixelRatio()); + pauseOffPixmap->setDevicePixelRatio(devicePixelRatio()); + pauseButton->setActiveGraphic(*pauseOnPixmap); + pauseButton->setInactiveGraphic(*pauseOffPixmap); + pauseButton->setCheckable(true); + pauseButton->setModel(&controls->m_pauseModel); + config_layout->addWidget(pauseButton, 0, 0, 2, 1); + + PixmapButton *refFreezeButton = new PixmapButton(this, tr("Reference freeze")); + refFreezeButton->setToolTip(tr("Freeze current input as a reference / disable falloff in peak-hold mode.")); + QPixmap *freezeOnPixmap = new QPixmap(PLUGIN_NAME::getIconPixmap("freeze").scaled(buttonSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + QPixmap *freezeOffPixmap = new QPixmap(PLUGIN_NAME::getIconPixmap("freeze_off").scaled(buttonSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + freezeOnPixmap->setDevicePixelRatio(devicePixelRatio()); + freezeOffPixmap->setDevicePixelRatio(devicePixelRatio()); + refFreezeButton->setActiveGraphic(*freezeOnPixmap); + refFreezeButton->setInactiveGraphic(*freezeOffPixmap); + refFreezeButton->setCheckable(true); + refFreezeButton->setModel(&controls->m_refFreezeModel); + config_layout->addWidget(refFreezeButton, 2, 0, 2, 1); + + // misc configuration switches + LedCheckBox *waterfallButton = new LedCheckBox(tr("Waterfall"), this); + waterfallButton->setToolTip(tr("Display real-time spectrogram")); + waterfallButton->setCheckable(true); + waterfallButton->setMinimumSize(70, 12); + waterfallButton->setModel(&controls->m_waterfallModel); + config_layout->addWidget(waterfallButton, 0, 1); + + LedCheckBox *smoothButton = new LedCheckBox(tr("Averaging"), this); + smoothButton->setToolTip(tr("Enable exponential moving average")); + smoothButton->setCheckable(true); + smoothButton->setMinimumSize(70, 12); + smoothButton->setModel(&controls->m_smoothModel); + config_layout->addWidget(smoothButton, 1, 1); + + LedCheckBox *stereoButton = new LedCheckBox(tr("Stereo"), this); + stereoButton->setToolTip(tr("Display stereo channels separately")); + stereoButton->setCheckable(true); + stereoButton->setMinimumSize(70, 12); + stereoButton->setModel(&controls->m_stereoModel); + config_layout->addWidget(stereoButton, 2, 1); + + LedCheckBox *peakHoldButton = new LedCheckBox(tr("Peak hold"), this); + peakHoldButton->setToolTip(tr("Display envelope of peak values")); + peakHoldButton->setCheckable(true); + peakHoldButton->setMinimumSize(70, 12); + peakHoldButton->setModel(&controls->m_peakHoldModel); + config_layout->addWidget(peakHoldButton, 3, 1); + + // frequency: linear / log. switch and range selector + PixmapButton *logXButton = new PixmapButton(this, tr("Logarithmic frequency")); + logXButton->setToolTip(tr("Switch between logarithmic and linear frequency scale")); + QPixmap *logXOnPixmap = new QPixmap(PLUGIN_NAME::getIconPixmap("x_log").scaled(iconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + QPixmap *logXOffPixmap = new QPixmap(PLUGIN_NAME::getIconPixmap("x_linear").scaled(iconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + logXOnPixmap->setDevicePixelRatio(devicePixelRatio()); + logXOffPixmap->setDevicePixelRatio(devicePixelRatio()); + logXButton->setActiveGraphic(*logXOnPixmap); + logXButton->setInactiveGraphic(*logXOffPixmap); + logXButton->setCheckable(true); + logXButton->setModel(&controls->m_logXModel); + config_layout->addWidget(logXButton, 0, 2, 2, 1, Qt::AlignRight); + + ComboBox *freqRangeCombo = new ComboBox(this, tr("Frequency range")); + freqRangeCombo->setToolTip(tr("Frequency range")); + freqRangeCombo->setMinimumSize(100, 22); + freqRangeCombo->setMaximumSize(200, 22); + freqRangeCombo->setModel(&controls->m_freqRangeModel); + config_layout->addWidget(freqRangeCombo, 0, 3, 2, 1); + + // amplitude: linear / log switch and range selector + PixmapButton *logYButton = new PixmapButton(this, tr("Logarithmic amplitude")); + logYButton->setToolTip(tr("Switch between logarithmic and linear amplitude scale")); + QPixmap *logYOnPixmap = new QPixmap(PLUGIN_NAME::getIconPixmap("y_log").scaled(iconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + QPixmap *logYOffPixmap = new QPixmap(PLUGIN_NAME::getIconPixmap("y_linear").scaled(iconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + logYOnPixmap->setDevicePixelRatio(devicePixelRatio()); + logYOffPixmap->setDevicePixelRatio(devicePixelRatio()); + logYButton->setActiveGraphic(*logYOnPixmap); + logYButton->setInactiveGraphic(*logYOffPixmap); + logYButton->setCheckable(true); + logYButton->setModel(&controls->m_logYModel); + config_layout->addWidget(logYButton, 2, 2, 2, 1, Qt::AlignRight); + + ComboBox *ampRangeCombo = new ComboBox(this, tr("Amplitude range")); + ampRangeCombo->setToolTip(tr("Amplitude range")); + ampRangeCombo->setMinimumSize(100, 22); + ampRangeCombo->setMaximumSize(200, 22); + ampRangeCombo->setModel(&controls->m_ampRangeModel); + config_layout->addWidget(ampRangeCombo, 2, 3, 2, 1); + + // FFT: block size: icon and selector + QLabel *blockSizeLabel = new QLabel("", this); + QPixmap *blockSizeIcon = new QPixmap(PLUGIN_NAME::getIconPixmap("block_size")); + blockSizeIcon->setDevicePixelRatio(devicePixelRatio()); + blockSizeLabel->setPixmap(blockSizeIcon->scaled(iconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + config_layout->addWidget(blockSizeLabel, 0, 4, 2, 1, Qt::AlignRight); + + ComboBox *blockSizeCombo = new ComboBox(this, tr("FFT block bize")); + blockSizeCombo->setToolTip(tr("FFT block size")); + blockSizeCombo->setMinimumSize(100, 22); + blockSizeCombo->setMaximumSize(200, 22); + blockSizeCombo->setModel(&controls->m_blockSizeModel); + config_layout->addWidget(blockSizeCombo, 0, 5, 2, 1); + processor->reallocateBuffers(); + connect(&controls->m_blockSizeModel, &ComboBoxModel::dataChanged, [=] {processor->reallocateBuffers();}); + + // FFT: window type: icon and selector + QLabel *windowLabel = new QLabel("", this); + QPixmap *windowIcon = new QPixmap(PLUGIN_NAME::getIconPixmap("window")); + windowIcon->setDevicePixelRatio(devicePixelRatio()); + windowLabel->setPixmap(windowIcon->scaled(iconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + config_layout->addWidget(windowLabel, 2, 4, 2, 1, Qt::AlignRight); + + ComboBox *windowCombo = new ComboBox(this, tr("FFT window type")); + windowCombo->setToolTip(tr("FFT window type")); + windowCombo->setMinimumSize(100, 22); + windowCombo->setMaximumSize(200, 22); + windowCombo->setModel(&controls->m_windowModel); + config_layout->addWidget(windowCombo, 2, 5, 2, 1); + processor->rebuildWindow(); + connect(&controls->m_windowModel, &ComboBoxModel::dataChanged, [=] {processor->rebuildWindow();}); + + + // QSplitter middle and bottom: spectrum display widgets + m_spectrum = new SaSpectrumView(controls, processor, this); + display_splitter->addWidget(m_spectrum); + + m_waterfall = new SaWaterfallView(controls, processor, this); + display_splitter->addWidget(m_waterfall); + m_waterfall->setVisible(m_controls->m_waterfallModel.value()); + connect(&controls->m_waterfallModel, &BoolModel::dataChanged, [=] {m_waterfall->updateVisibility();}); +} + + +// Suggest the best current widget size. +QSize SaControlsDialog::sizeHint() const +{ + // Best width is determined by spectrum display sizeHint. + // Best height depends on whether waterfall is visible and + // consists of heights of the config section, spectrum, waterfall + // and some reserve for margins. + if (m_waterfall->isVisible()) + { + return QSize(m_spectrum->sizeHint().width(), + m_configHeight + m_spectrum->sizeHint().height() + m_waterfall->sizeHint().height() + 50); + } + else + { + return QSize(m_spectrum->sizeHint().width(), + m_configHeight + m_spectrum->sizeHint().height() + 50); + } +} + diff --git a/plugins/SpectrumAnalyzer/SaControlsDialog.h b/plugins/SpectrumAnalyzer/SaControlsDialog.h new file mode 100644 index 000000000..e5a35f186 --- /dev/null +++ b/plugins/SpectrumAnalyzer/SaControlsDialog.h @@ -0,0 +1,57 @@ +/* + * SaControlsDialog.h - declatation of SaControlsDialog class. + * + * Copyright (c) 2019 Martin Pavelek + * + * 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 SACONTROLSDIALOG_H +#define SACONTROLSDIALOG_H + +#include "EffectControlDialog.h" +#include "SaControls.h" +#include "SaSpectrumView.h" +#include "SaProcessor.h" +#include "SaWaterfallView.h" + + +//! Top-level widget holding the configuration GUI and spectrum displays +class SaControlsDialog : public EffectControlDialog +{ + Q_OBJECT +public: + explicit SaControlsDialog(SaControls *controls, SaProcessor *processor); + virtual ~SaControlsDialog() {} + + bool isResizable() const override {return true;} + QSize sizeHint() const override; + +private: + SaControls *m_controls; + SaProcessor *m_processor; + + // Pointers to created widgets are needed to keep track of their sizeHint() changes. + // Config widget is a plain QWidget so it has just a fixed height instead. + const int m_configHeight = 75; + SaSpectrumView *m_spectrum; + SaWaterfallView *m_waterfall; +}; + +#endif // SACONTROLSDIALOG_H diff --git a/plugins/SpectrumAnalyzer/SaProcessor.cpp b/plugins/SpectrumAnalyzer/SaProcessor.cpp new file mode 100644 index 000000000..9261658aa --- /dev/null +++ b/plugins/SpectrumAnalyzer/SaProcessor.cpp @@ -0,0 +1,571 @@ +/* SaProcessor.cpp - implementation of SaProcessor class. + * + * Copyright (c) 2019 Martin Pavelek + * + * Based partially on Eq plugin code, + * Copyright (c) 2014-2017, David French + * + * 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 "SaProcessor.h" + +#include +#include +#include +#include + +#include "lmms_math.h" + + +SaProcessor::SaProcessor(SaControls *controls) : + m_controls(controls), + m_inBlockSize(FFT_BLOCK_SIZES[0]), + m_fftBlockSize(FFT_BLOCK_SIZES[0]), + m_sampleRate(Engine::mixer()->processingSampleRate()), + m_framesFilledUp(0), + m_spectrumActive(false), + m_waterfallActive(false), + m_waterfallNotEmpty(0), + m_reallocating(false) +{ + m_fftWindow.resize(m_inBlockSize, 1.0); + precomputeWindow(m_fftWindow.data(), m_inBlockSize, BLACKMAN_HARRIS); + + m_bufferL.resize(m_fftBlockSize, 0); + m_bufferR.resize(m_fftBlockSize, 0); + m_spectrumL = (fftwf_complex *) fftwf_malloc(binCount() * sizeof (fftwf_complex)); + m_spectrumR = (fftwf_complex *) fftwf_malloc(binCount() * sizeof (fftwf_complex)); + m_fftPlanL = fftwf_plan_dft_r2c_1d(m_fftBlockSize, m_bufferL.data(), m_spectrumL, FFTW_MEASURE); + m_fftPlanR = fftwf_plan_dft_r2c_1d(m_fftBlockSize, m_bufferR.data(), m_spectrumR, FFTW_MEASURE); + + m_absSpectrumL.resize(binCount(), 0); + m_absSpectrumR.resize(binCount(), 0); + m_normSpectrumL.resize(binCount(), 0); + m_normSpectrumR.resize(binCount(), 0); + + m_history.resize(binCount() * m_waterfallHeight * sizeof qRgb(0,0,0), 0); + + clear(); +} + + +SaProcessor::~SaProcessor() +{ + if (m_fftPlanL != NULL) {fftwf_destroy_plan(m_fftPlanL);} + if (m_fftPlanR != NULL) {fftwf_destroy_plan(m_fftPlanR);} + if (m_spectrumL != NULL) {fftwf_free(m_spectrumL);} + if (m_spectrumR != NULL) {fftwf_free(m_spectrumR);} + + m_fftPlanL = NULL; + m_fftPlanR = NULL; + m_spectrumL = NULL; + m_spectrumR = NULL; +} + + +// Load a batch of data from LMMS; run FFT analysis if buffer is full enough. +void SaProcessor::analyse(sampleFrame *in_buffer, const fpp_t frame_count) +{ + #ifdef SA_DEBUG + int start_time = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + #endif + // only take in data if any view is visible and not paused + if ((m_spectrumActive || m_waterfallActive) && !m_controls->m_pauseModel.value()) + { + const bool stereo = m_controls->m_stereoModel.value(); + fpp_t in_frame = 0; + while (in_frame < frame_count) + { + // fill sample buffers and check for zero input + bool block_empty = true; + for (; in_frame < frame_count && m_framesFilledUp < m_inBlockSize; in_frame++, m_framesFilledUp++) + { + if (stereo) + { + m_bufferL[m_framesFilledUp] = in_buffer[in_frame][0]; + m_bufferR[m_framesFilledUp] = in_buffer[in_frame][1]; + } + else + { + m_bufferL[m_framesFilledUp] = + m_bufferR[m_framesFilledUp] = (in_buffer[in_frame][0] + in_buffer[in_frame][1]) * 0.5f; + } + if (in_buffer[in_frame][0] != 0.f || in_buffer[in_frame][1] != 0.f) + { + block_empty = false; + } + } + + // Run analysis only if buffers contain enough data. + // Also, to prevent audio interruption and a momentary GUI freeze, + // skip analysis if buffers are being reallocated. + if (m_framesFilledUp < m_inBlockSize || m_reallocating) {return;} + + // update sample rate + m_sampleRate = Engine::mixer()->processingSampleRate(); + + // apply FFT window + for (unsigned int i = 0; i < m_inBlockSize; i++) + { + m_bufferL[i] = m_bufferL[i] * m_fftWindow[i]; + m_bufferR[i] = m_bufferR[i] * m_fftWindow[i]; + } + + // lock data shared with SaSpectrumView and SaWaterfallView + QMutexLocker lock(&m_dataAccess); + + // Run FFT on left channel, convert the result to absolute magnitude + // spectrum and normalize it. + fftwf_execute(m_fftPlanL); + absspec(m_spectrumL, m_absSpectrumL.data(), binCount()); + normalize(m_absSpectrumL, m_normSpectrumL, m_inBlockSize); + + // repeat analysis for right channel if stereo processing is enabled + if (stereo) + { + fftwf_execute(m_fftPlanR); + absspec(m_spectrumR, m_absSpectrumR.data(), binCount()); + normalize(m_absSpectrumR, m_normSpectrumR, m_inBlockSize); + } + + // count empty lines so that empty history does not have to update + if (block_empty && m_waterfallNotEmpty) + { + m_waterfallNotEmpty -= 1; + } + else if (!block_empty) + { + m_waterfallNotEmpty = m_waterfallHeight + 2; + } + + if (m_waterfallActive && m_waterfallNotEmpty) + { + // move waterfall history one line down and clear the top line + QRgb *pixel = (QRgb *)m_history.data(); + std::copy(pixel, + pixel + binCount() * m_waterfallHeight - binCount(), + pixel + binCount()); + memset(pixel, 0, binCount() * sizeof (QRgb)); + + // add newest result on top + int target; // pixel being constructed + float accL = 0; // accumulators for merging multiple bins + float accR = 0; + + for (unsigned int i = 0; i < binCount(); i++) + { + // Every frequency bin spans a frequency range that must be + // partially or fully mapped to a pixel. Any inconsistency + // may be seen in the spectrogram as dark or white lines -- + // play white noise to confirm your change did not break it. + float band_start = freqToXPixel(binToFreq(i) - binBandwidth() / 2.0, binCount()); + float band_end = freqToXPixel(binToFreq(i + 1) - binBandwidth() / 2.0, binCount()); + if (m_controls->m_logXModel.value()) + { + // Logarithmic scale + if (band_end - band_start > 1.0) + { + // band spans multiple pixels: draw all pixels it covers + for (target = (int)band_start; target < (int)band_end; target++) + { + if (target >= 0 && target < binCount()) + { + pixel[target] = makePixel(m_normSpectrumL[i], m_normSpectrumR[i]); + } + } + // save remaining portion of the band for the following band / pixel + // (in case the next band uses sub-pixel drawing) + accL = (band_end - (int)band_end) * m_normSpectrumL[i]; + accR = (band_end - (int)band_end) * m_normSpectrumR[i]; + } + else + { + // sub-pixel drawing; add contribution of current band + target = (int)band_start; + if ((int)band_start == (int)band_end) + { + // band ends within current target pixel, accumulate + accL += (band_end - band_start) * m_normSpectrumL[i]; + accR += (band_end - band_start) * m_normSpectrumR[i]; + } + else + { + // Band ends in the next pixel -- finalize the current pixel. + // Make sure contribution is split correctly on pixel boundary. + accL += ((int)band_end - band_start) * m_normSpectrumL[i]; + accR += ((int)band_end - band_start) * m_normSpectrumR[i]; + + if (target >= 0 && target < binCount()) {pixel[target] = makePixel(accL, accR);} + + // save remaining portion of the band for the following band / pixel + accL = (band_end - (int)band_end) * m_normSpectrumL[i]; + accR = (band_end - (int)band_end) * m_normSpectrumR[i]; + } + } + } + else + { + // Linear: always draws one or more pixels per band + for (target = (int)band_start; target < band_end; target++) + { + if (target >= 0 && target < binCount()) + { + pixel[target] = makePixel(m_normSpectrumL[i], m_normSpectrumR[i]); + } + } + } + } + } + #ifdef SA_DEBUG + // report FFT processing speed + start_time = std::chrono::high_resolution_clock::now().time_since_epoch().count() - start_time; + std::cout << "Processed " << m_framesFilledUp << " samples in " << start_time / 1000000.0 << " ms" << std::endl; + #endif + + // clean up before checking for more data from input buffer + m_framesFilledUp = 0; + } + } +} + + +// Produce a spectrogram pixel from normalized spectrum data. +// Values over 1.0 will cause the color components to overflow: this is left +// intentionally untreated as it clearly indicates which frequency is clipping. +// Gamma correction is applied to make small values more visible and to make +// a linear gradient actually appear roughly linear. The correction should be +// around 0.42 to 0.45 for sRGB displays (or lower for bigger visibility boost). +QRgb SaProcessor::makePixel(float left, float right, float gamma_correction) const +{ + if (m_controls->m_stereoModel.value()) + { + float ampL = pow(left, gamma_correction); + float ampR = pow(right, gamma_correction); + return qRgb(m_controls->m_colorL.red() * ampL + m_controls->m_colorR.red() * ampR, + m_controls->m_colorL.green() * ampL + m_controls->m_colorR.green() * ampR, + m_controls->m_colorL.blue() * ampL + m_controls->m_colorR.blue() * ampR); + } + else + { + float ampL = pow(left, gamma_correction); + // make mono color brighter to compensate for the fact it is not summed + return qRgb(m_controls->m_colorMono.lighter().red() * ampL, + m_controls->m_colorMono.lighter().green() * ampL, + m_controls->m_colorMono.lighter().blue() * ampL); + } +} + + + +// Inform the processor whether any display widgets actually need it. +void SaProcessor::setSpectrumActive(bool active) +{ + m_spectrumActive = active; +} + +void SaProcessor::setWaterfallActive(bool active) +{ + m_waterfallActive = active; +} + + +// Reallocate data buffers according to newly set block size. +void SaProcessor::reallocateBuffers() +{ + unsigned int new_size_index = m_controls->m_blockSizeModel.value(); + unsigned int new_in_size, new_fft_size; + unsigned int new_bins; + + // get new block sizes and bin count based on selected index + if (new_size_index < FFT_BLOCK_SIZES.size()) + { + new_in_size = FFT_BLOCK_SIZES[new_size_index]; + } + else + { + new_in_size = FFT_BLOCK_SIZES.back(); + } + if (new_size_index + m_zeroPadFactor < FFT_BLOCK_SIZES.size()) + { + new_fft_size = FFT_BLOCK_SIZES[new_size_index + m_zeroPadFactor]; + } + else + { + new_fft_size = FFT_BLOCK_SIZES.back(); + } + + new_bins = new_fft_size / 2 +1; + + // Lock data shared with SaSpectrumView and SaWaterfallView. + // The m_reallocating is here to tell analyse() to avoid asking for the + // lock, since fftw3 can take a while to find the fastest FFT algorithm + // for given machine, which would produce interruption in the audio stream. + m_reallocating = true; + QMutexLocker lock(&m_dataAccess); + + // destroy old FFT plan and free the result buffer + if (m_fftPlanL != NULL) {fftwf_destroy_plan(m_fftPlanL);} + if (m_fftPlanR != NULL) {fftwf_destroy_plan(m_fftPlanR);} + if (m_spectrumL != NULL) {fftwf_free(m_spectrumL);} + if (m_spectrumR != NULL) {fftwf_free(m_spectrumR);} + + // allocate new space, create new plan and resize containers + m_fftWindow.resize(new_in_size, 1.0); + precomputeWindow(m_fftWindow.data(), new_in_size, (FFT_WINDOWS) m_controls->m_windowModel.value()); + m_bufferL.resize(new_fft_size, 0); + m_bufferR.resize(new_fft_size, 0); + m_spectrumL = (fftwf_complex *) fftwf_malloc(new_bins * sizeof (fftwf_complex)); + m_spectrumR = (fftwf_complex *) fftwf_malloc(new_bins * sizeof (fftwf_complex)); + m_fftPlanL = fftwf_plan_dft_r2c_1d(new_fft_size, m_bufferL.data(), m_spectrumL, FFTW_MEASURE); + m_fftPlanR = fftwf_plan_dft_r2c_1d(new_fft_size, m_bufferR.data(), m_spectrumR, FFTW_MEASURE); + + if (m_fftPlanL == NULL || m_fftPlanR == NULL) + { + std::cerr << "Failed to create new FFT plan!" << std::endl; + } + m_absSpectrumL.resize(new_bins, 0); + m_absSpectrumR.resize(new_bins, 0); + m_normSpectrumL.resize(new_bins, 0); + m_normSpectrumR.resize(new_bins, 0); + + m_history.resize(new_bins * m_waterfallHeight * sizeof qRgb(0,0,0), 0); + + // done; publish new sizes and clean up + m_inBlockSize = new_in_size; + m_fftBlockSize = new_fft_size; + + lock.unlock(); + m_reallocating = false; + clear(); +} + + +// Precompute a new FFT window based on currently selected type. +void SaProcessor::rebuildWindow() +{ + // computation is done in fft_helpers + QMutexLocker lock(&m_dataAccess); + precomputeWindow(m_fftWindow.data(), m_inBlockSize, (FFT_WINDOWS) m_controls->m_windowModel.value()); +} + + +// Clear all data buffers and replace contents with zeros. +// Note: may take a few milliseconds, do not call in a loop! +void SaProcessor::clear() +{ + QMutexLocker lock(&m_dataAccess); + m_framesFilledUp = 0; + std::fill(m_bufferL.begin(), m_bufferL.end(), 0); + std::fill(m_bufferR.begin(), m_bufferR.end(), 0); + std::fill(m_absSpectrumL.begin(), m_absSpectrumL.end(), 0); + std::fill(m_absSpectrumR.begin(), m_absSpectrumR.end(), 0); + std::fill(m_normSpectrumL.begin(), m_normSpectrumL.end(), 0); + std::fill(m_normSpectrumR.begin(), m_normSpectrumR.end(), 0); + std::fill(m_history.begin(), m_history.end(), 0); +} + + +// -------------------------------------- +// Frequency conversion helpers +// + +// Get sample rate value that is valid for currently stored results. +unsigned int SaProcessor::getSampleRate() const +{ + return m_sampleRate; +} + + +// Maximum frequency of a sampled signal is equal to half of its sample rate. +float SaProcessor::getNyquistFreq() const +{ + return getSampleRate() / 2.0f; +} + + +// FFTW automatically discards upper half of the symmetric FFT output, so +// the useful bin count is the transform size divided by 2, plus zero. +unsigned int SaProcessor::binCount() const +{ + return m_fftBlockSize / 2 + 1; +} + + +// Return the center frequency of given frequency bin. +float SaProcessor::binToFreq(unsigned int bin_index) const +{ + return getNyquistFreq() * bin_index / binCount(); +} + + +// Return width of the frequency range that falls into one bin. +// The binCount is lowered by one since half of the first and last bin is +// actually outside the frequency range. +float SaProcessor::binBandwidth() const +{ + return getNyquistFreq() / (binCount() - 1); +} + + +float SaProcessor::getFreqRangeMin(bool linear) const +{ + switch (m_controls->m_freqRangeModel.value()) + { + case FRANGE_AUDIBLE: return FRANGE_AUDIBLE_START; + case FRANGE_BASS: return FRANGE_BASS_START; + case FRANGE_MIDS: return FRANGE_MIDS_START; + case FRANGE_HIGH: return FRANGE_HIGH_START; + default: + case FRANGE_FULL: return linear ? 0 : LOWEST_LOG_FREQ; + } +} + + +float SaProcessor::getFreqRangeMax() const +{ + switch (m_controls->m_freqRangeModel.value()) + { + case FRANGE_AUDIBLE: return FRANGE_AUDIBLE_END; + case FRANGE_BASS: return FRANGE_BASS_END; + case FRANGE_MIDS: return FRANGE_MIDS_END; + case FRANGE_HIGH: return FRANGE_HIGH_END; + default: + case FRANGE_FULL: return getNyquistFreq(); + } +} + + +// Map frequency to pixel x position on a display of given width. +float SaProcessor::freqToXPixel(float freq, unsigned int width) const +{ + if (m_controls->m_logXModel.value()) + { + if (freq <= 1) {return 0;} + float min = log10(getFreqRangeMin()); + float range = log10(getFreqRangeMax()) - min; + return (log10(freq) - min) / range * width; + } + else + { + float min = getFreqRangeMin(); + float range = getFreqRangeMax() - min; + return (freq - min) / range * width; + } +} + + +// Map pixel x position on display of given width back to frequency. +float SaProcessor::xPixelToFreq(float x, unsigned int width) const +{ + if (m_controls->m_logXModel.value()) + { + float min = log10(getFreqRangeMin()); + float max = log10(getFreqRangeMax()); + float range = max - min; + return pow(10, min + x / width * range); + } + else + { + float min = getFreqRangeMin(); + float range = getFreqRangeMax() - min; + return min + x / width * range; + } +} + + +// -------------------------------------- +// Amplitude conversion helpers +// +float SaProcessor::getAmpRangeMin(bool linear) const +{ + // return very low limit to make sure zero gets included at linear grid + if (linear) {return -900;} + switch (m_controls->m_ampRangeModel.value()) + { + case ARANGE_EXTENDED: return ARANGE_EXTENDED_START; + case ARANGE_AUDIBLE: return ARANGE_AUDIBLE_START; + case ARANGE_NOISE: return ARANGE_NOISE_START; + default: + case ARANGE_DEFAULT: return ARANGE_DEFAULT_START; + } +} + + +float SaProcessor::getAmpRangeMax() const +{ + switch (m_controls->m_ampRangeModel.value()) + { + case ARANGE_EXTENDED: return ARANGE_EXTENDED_END; + case ARANGE_AUDIBLE: return ARANGE_AUDIBLE_END; + case ARANGE_NOISE: return ARANGE_NOISE_END; + default: + case ARANGE_DEFAULT: return ARANGE_DEFAULT_END; + } +} + + +// Map linear amplitude to pixel y position on a display of given height. +// Note that display coordinates are flipped: amplitude grows from [height] to zero. +float SaProcessor::ampToYPixel(float amplitude, unsigned int height) const +{ + if (m_controls->m_logYModel.value()) + { + // logarithmic scale: convert linear amplitude to dB (relative to 1.0) + float amplitude_dB = 10 * log10(amplitude); + if (amplitude_dB < getAmpRangeMin()) + { + return height; + } + else + { + float max = getAmpRangeMax(); + float range = getAmpRangeMin() - max; + return (amplitude_dB - max) / range * height; + } + } + else + { + // linear scale: convert returned ranges from dB to linear scale + float max = pow(10, getAmpRangeMax() / 10); + float range = pow(10, getAmpRangeMin() / 10) - max; + return (amplitude - max) / range * height; + } +} + + +// Map pixel y position on display of given height back to amplitude. +// Note that display coordinates are flipped: amplitude grows from [height] to zero. +// Also note that in logarithmic Y mode the returned amplitude is in dB, not linear. +float SaProcessor::yPixelToAmp(float y, unsigned int height) const +{ + if (m_controls->m_logYModel.value()) + { + float max = getAmpRangeMax(); + float range = getAmpRangeMin() - max; + return max + range * (y / height); + } + else + { + // linear scale: convert returned ranges from dB to linear scale + float max = pow(10, getAmpRangeMax() / 10); + float range = pow(10, getAmpRangeMin() / 10) - max; + return max + range * (y / height); + } +} + diff --git a/plugins/SpectrumAnalyzer/SaProcessor.h b/plugins/SpectrumAnalyzer/SaProcessor.h new file mode 100644 index 000000000..ae2df16f8 --- /dev/null +++ b/plugins/SpectrumAnalyzer/SaProcessor.h @@ -0,0 +1,122 @@ +/* SaProcessor.h - declaration of SaProcessor class. + * + * Copyright (c) 2019 Martin Pavelek + * + * Based partially on Eq plugin code, + * Copyright (c) 2014 David French + * + * 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 SAPROCESSOR_H +#define SAPROCESSOR_H + +#include +#include +#include + +#include "fft_helpers.h" +#include "SaControls.h" + + +//! Receives audio data, runs FFT analysis and stores the result. +class SaProcessor +{ +public: + explicit SaProcessor(SaControls *controls); + virtual ~SaProcessor(); + + void analyse(sampleFrame *in_buffer, const fpp_t frame_count); + + // inform processor if any processing is actually required + void setSpectrumActive(bool active); + void setWaterfallActive(bool active); + + // configuration is taken from models in SaControls; some changes require + // an exlicit update request (reallocation and window rebuild) + void reallocateBuffers(); + void rebuildWindow(); + void clear(); + + // information about results and unit conversion helpers + float binToFreq(unsigned int bin_index) const; + float binBandwidth() const; + + float freqToXPixel(float frequency, unsigned int width) const; + float xPixelToFreq(float x, unsigned int width) const; + + float ampToYPixel(float amplitude, unsigned int height) const; + float yPixelToAmp(float y, unsigned int height) const; + + unsigned int getSampleRate() const; + float getNyquistFreq() const; + + float getFreqRangeMin(bool linear = false) const; + float getFreqRangeMax() const; + float getAmpRangeMin(bool linear = false) const; + float getAmpRangeMax() const; + + // data access lock must be acquired by any friendly class that touches + // the results, mainly to prevent unexpected mid-way reallocation + QMutex m_dataAccess; + +private: + SaControls *m_controls; + + // currently valid configuration + const unsigned int m_zeroPadFactor = 2; //!< use n-steps bigger FFT for given block size + unsigned int m_inBlockSize; //!< size of input (time domain) data block + unsigned int m_fftBlockSize; //!< size of padded block for FFT processing + unsigned int m_sampleRate; + + unsigned int binCount() const; //!< size of output (frequency domain) data block + + // data buffers (roughly in the order of processing, from input to output) + unsigned int m_framesFilledUp; + std::vector m_bufferL; //!< time domain samples (left) + std::vector m_bufferR; //!< time domain samples (right) + std::vector m_fftWindow; //!< precomputed window function coefficients + fftwf_plan m_fftPlanL; + fftwf_plan m_fftPlanR; + fftwf_complex *m_spectrumL; //!< frequency domain samples (complex) (left) + fftwf_complex *m_spectrumR; //!< frequency domain samples (complex) (right) + std::vector m_absSpectrumL; //!< frequency domain samples (absolute) (left) + std::vector m_absSpectrumR; //!< frequency domain samples (absolute) (right) + std::vector m_normSpectrumL; //!< frequency domain samples (normalized) (left) + std::vector m_normSpectrumR; //!< frequency domain samples (normalized) (right) + + // spectrum history for waterfall: new normSpectrum lines are added on top + std::vector m_history; + const unsigned int m_waterfallHeight = 200; // Number of stored lines. + // Note: high values may make it harder to see transients. + + // book keeping + bool m_spectrumActive; + bool m_waterfallActive; + unsigned int m_waterfallNotEmpty; + bool m_reallocating; + + // merge L and R channels and apply gamma correction to make a spectrogram pixel + QRgb makePixel(float left, float right, float gamma_correction = 0.30) const; + + friend class SaSpectrumView; + friend class SaWaterfallView; +}; +#endif // SAPROCESSOR_H + diff --git a/plugins/SpectrumAnalyzer/SaSpectrumView.cpp b/plugins/SpectrumAnalyzer/SaSpectrumView.cpp new file mode 100644 index 000000000..746d52cfd --- /dev/null +++ b/plugins/SpectrumAnalyzer/SaSpectrumView.cpp @@ -0,0 +1,796 @@ +/* SaSpectrumView.cpp - implementation of SaSpectrumView class. + * + * Copyright (c) 2019 Martin Pavelek + * + * Based partially on Eq plugin code, + * Copyright (c) 2014-2017, David French + * + * 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 "SaSpectrumView.h" + +#include +#include +#include +#include +#include +#include + +#include "GuiApplication.h" +#include "MainWindow.h" +#include "SaProcessor.h" + +#ifdef SA_DEBUG + #include + #include +#endif + + +SaSpectrumView::SaSpectrumView(SaControls *controls, SaProcessor *processor, QWidget *_parent) : + QWidget(_parent), + m_controls(controls), + m_processor(processor), + m_freezeRequest(false), + m_frozen(false) +{ + setMinimumSize(360, 170); + setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + + connect(gui->mainWindow(), SIGNAL(periodicUpdate()), this, SLOT(periodicUpdate())); + + m_displayBufferL.resize(m_processor->binCount(), 0); + m_displayBufferR.resize(m_processor->binCount(), 0); + m_peakBufferL.resize(m_processor->binCount(), 0); + m_peakBufferR.resize(m_processor->binCount(), 0); + + m_freqRangeIndex = m_controls->m_freqRangeModel.value(); + m_ampRangeIndex = m_controls->m_ampRangeModel.value(); + + m_logFreqTics = makeLogFreqTics(m_processor->getFreqRangeMin(), m_processor->getFreqRangeMax()); + m_linearFreqTics = makeLinearFreqTics(m_processor->getFreqRangeMin(), m_processor->getFreqRangeMax()); + m_logAmpTics = makeLogAmpTics(m_processor->getAmpRangeMin(), m_processor->getAmpRangeMax()); + m_linearAmpTics = makeLinearAmpTics(m_processor->getAmpRangeMin(), m_processor->getAmpRangeMax()); + + m_cursor = QPoint(0, 0); +} + + +// Compose and draw all the content; periodically called by Qt. +// NOTE: Performance sensitive! If the drawing takes too long, it will drag +// the FPS down for the entire program! Use SA_DEBUG to display timings. +void SaSpectrumView::paintEvent(QPaintEvent *event) +{ + #ifdef SA_DEBUG + int total_time = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + #endif + + // 0) Constants and init + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing, true); + + // drawing and path-making are split into multiple methods for clarity; + // display boundaries are updated here and shared as member variables + m_displayTop = 1; + m_displayBottom = height() -20; + m_displayLeft = 26; + m_displayRight = width() -26; + m_displayWidth = m_displayRight - m_displayLeft; + + // recompute range labels if needed + if (m_freqRangeIndex != m_controls->m_freqRangeModel.value()) + { + m_logFreqTics = makeLogFreqTics(m_processor->getFreqRangeMin(), m_processor->getFreqRangeMax()); + m_linearFreqTics = makeLinearFreqTics(m_processor->getFreqRangeMin(true), m_processor->getFreqRangeMax()); + m_freqRangeIndex = m_controls->m_freqRangeModel.value(); + } + if (m_ampRangeIndex != m_controls->m_ampRangeModel.value()) + { + m_logAmpTics = makeLogAmpTics(m_processor->getAmpRangeMin(), m_processor->getAmpRangeMax()); + m_linearAmpTics = makeLinearAmpTics(m_processor->getAmpRangeMin(true), m_processor->getAmpRangeMax()); + m_ampRangeIndex = m_controls->m_ampRangeModel.value(); + } + + // generate freeze request or clear "frozen" status based on freeze button + if (!m_frozen && m_controls->m_refFreezeModel.value()) + { + m_freezeRequest = true; + } + else if (!m_controls->m_refFreezeModel.value()) + { + m_frozen = false; + } + + // 1) Background, grid and labels + drawGrid(painter); + + // 2) Spectrum display + drawSpectrum(painter); + + // 3) Overlays + // draw cursor (if it is within bounds) + drawCursor(painter); + + // always draw the display outline + painter.setPen(QPen(m_controls->m_colorGrid, 2, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + painter.drawRoundedRect(m_displayLeft, 1, + m_displayWidth, m_displayBottom, + 2.0, 2.0); + + #ifdef SA_DEBUG + // display what FPS would be achieved if spectrum display ran in a loop + total_time = std::chrono::high_resolution_clock::now().time_since_epoch().count() - total_time; + painter.setPen(QPen(m_controls->m_colorLabels, 1, + Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + painter.drawText(m_displayRight -100, 70, 100, 16, Qt::AlignLeft, + QString(std::string("Max FPS: " + std::to_string(1000000000.0 / total_time)).c_str())); + #endif +} + + +// Refresh data and draw the spectrum. +void SaSpectrumView::drawSpectrum(QPainter &painter) +{ + #ifdef SA_DEBUG + int path_time = 0, draw_time = 0; + #endif + + // draw the graph only if there is any input, averaging residue or peaks + QMutexLocker lock(&m_processor->m_dataAccess); + if (m_decaySum > 0 || notEmpty(m_processor->m_normSpectrumL) || notEmpty(m_processor->m_normSpectrumR)) + { + lock.unlock(); + #ifdef SA_DEBUG + path_time = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + #endif + // update data buffers and reconstruct paths + refreshPaths(); + #ifdef SA_DEBUG + path_time = std::chrono::high_resolution_clock::now().time_since_epoch().count() - path_time; + #endif + + // draw stored paths + #ifdef SA_DEBUG + draw_time = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + #endif + // in case stereo is disabled, mono data are stored in left channel structures + if (m_controls->m_stereoModel.value()) + { + painter.fillPath(m_pathR, QBrush(m_controls->m_colorR)); + painter.fillPath(m_pathL, QBrush(m_controls->m_colorL)); + } + else + { + painter.fillPath(m_pathL, QBrush(m_controls->m_colorMono)); + } + // draw the peakBuffer only if peak hold or reference freeze is active + if (m_controls->m_peakHoldModel.value() || m_controls->m_refFreezeModel.value()) + { + if (m_controls->m_stereoModel.value()) + { + painter.setPen(QPen(m_controls->m_colorR, 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + painter.drawPath(m_pathPeakR); + painter.setPen(QPen(m_controls->m_colorL, 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + painter.drawPath(m_pathPeakL); + } + else + { + painter.setPen(QPen(m_controls->m_colorL, 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + painter.drawPath(m_pathPeakL); + } + } + #ifdef SA_DEBUG + draw_time = std::chrono::high_resolution_clock::now().time_since_epoch().count() - draw_time; + #endif + } + else + { + lock.unlock(); + } + + #ifdef SA_DEBUG + // display measurement results + painter.drawText(m_displayRight -100, 90, 100, 16, Qt::AlignLeft, + QString(std::string("Path ms: " + std::to_string(path_time / 1000000.0)).c_str())); + painter.drawText(m_displayRight -100, 110, 100, 16, Qt::AlignLeft, + QString(std::string("Draw ms: " + std::to_string(draw_time / 1000000.0)).c_str())); + #endif +} + + +// Read newest FFT results from SaProcessor, update local display buffers +// and build QPainter paths. +void SaSpectrumView::refreshPaths() +{ + // Lock is required for the entire function, mainly to prevent block size + // changes from causing reallocation of data structures mid-way. + QMutexLocker lock(&m_processor->m_dataAccess); + + // check if bin count changed and reallocate display buffers accordingly + if (m_processor->binCount() != m_displayBufferL.size()) + { + m_displayBufferL.clear(); + m_displayBufferR.clear(); + m_peakBufferL.clear(); + m_peakBufferR.clear(); + m_displayBufferL.resize(m_processor->binCount(), 0); + m_displayBufferR.resize(m_processor->binCount(), 0); + m_peakBufferL.resize(m_processor->binCount(), 0); + m_peakBufferR.resize(m_processor->binCount(), 0); + } + + // update display buffers for left and right channel + #ifdef SA_DEBUG + int refresh_time = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + #endif + m_decaySum = 0; + updateBuffers(m_processor->m_normSpectrumL.data(), m_displayBufferL.data(), m_peakBufferL.data()); + updateBuffers(m_processor->m_normSpectrumR.data(), m_displayBufferR.data(), m_peakBufferR.data()); + #ifdef SA_DEBUG + refresh_time = std::chrono::high_resolution_clock::now().time_since_epoch().count() - refresh_time; + #endif + + // if there was a freeze request, it was taken care of during the update + if (m_controls->m_refFreezeModel.value() && m_freezeRequest) + { + m_freezeRequest = false; + m_frozen = true; + } + + #ifdef SA_DEBUG + int make_time = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + #endif + // Use updated display buffers to prepare new paths for QPainter. + // This is the second slowest action (first is the subsequent drawing); use + // the resolution parameter to balance display quality and performance. + m_pathL = makePath(m_displayBufferL, 1.5); + if (m_controls->m_stereoModel.value()) + { + m_pathR = makePath(m_displayBufferR, 1.5); + } + if (m_controls->m_peakHoldModel.value() || m_controls->m_refFreezeModel.value()) + { + m_pathPeakL = makePath(m_peakBufferL, 0.25); + if (m_controls->m_stereoModel.value()) + { + m_pathPeakR = makePath(m_peakBufferR, 0.25); + } + } + #ifdef SA_DEBUG + make_time = std::chrono::high_resolution_clock::now().time_since_epoch().count() - make_time; + #endif + + #ifdef SA_DEBUG + // print measurement results + std::cout << "Buffer update ms: " << std::to_string(refresh_time / 1000000.0) << ", "; + std::cout << "Path-make ms: " << std::to_string(make_time / 1000000.0) << std::endl; + #endif +} + + +// Update display buffers: add new data, update average and peaks / reference. +// Output the sum of all displayed values -- draw only if it is non-zero. +// NOTE: The calling function is responsible for acquiring SaProcessor data +// access lock! +void SaSpectrumView::updateBuffers(float *spectrum, float *displayBuffer, float *peakBuffer) +{ + for (int n = 0; n < m_processor->binCount(); n++) + { + // Update the exponential average if enabled, or simply copy the value. + if (!m_controls->m_pauseModel.value()) + { + if (m_controls->m_smoothModel.value()) + { + displayBuffer[n] = spectrum[n] * m_smoothFactor + displayBuffer[n] * (1 - m_smoothFactor); + } + else + { + displayBuffer[n] = spectrum[n]; + } + } + // Update peak-hold and reference freeze data (using a shared curve). + // Peak hold and freeze can be combined: decay only if not frozen. + // Ref. freeze operates on the (possibly averaged) display buffer. + if (m_controls->m_refFreezeModel.value() && m_freezeRequest) + { + peakBuffer[n] = displayBuffer[n]; + } + else if (m_controls->m_peakHoldModel.value() && !m_controls->m_pauseModel.value()) + { + if (spectrum[n] > peakBuffer[n]) + { + peakBuffer[n] = spectrum[n]; + } + else if (!m_controls->m_refFreezeModel.value()) + { + peakBuffer[n] = peakBuffer[n] * m_peakDecayFactor; + } + } + else if (!m_controls->m_refFreezeModel.value() && !m_controls->m_peakHoldModel.value()) + { + peakBuffer[n] = 0; + } + // take note if there was actually anything to display + m_decaySum += displayBuffer[n] + peakBuffer[n]; + } +} + + +// Use display buffer to build a path that can be drawn or filled by QPainter. +// Resolution controls the performance / quality tradeoff; the value specifies +// number of points in x axis per device pixel. Values over 1.0 still +// contribute to quality and accuracy thanks to anti-aliasing. +QPainterPath SaSpectrumView::makePath(std::vector &displayBuffer, float resolution = 1.0) +{ + // convert resolution to number of path points per logical pixel + float pixel_limit = resolution * window()->devicePixelRatio(); + + QPainterPath path; + path.moveTo(m_displayLeft, m_displayBottom); + + // Translate frequency bins to path points. + // Display is flipped: y values grow towards zero, initial max is bottom. + // Bins falling to interval [x_start, x_next) contribute to a single point. + float max = m_displayBottom; + float x_start = -1; // lower bound of currently constructed point + for (unsigned int n = 0; n < m_processor->binCount(); n++) + { + float x = freqToXPixel(binToFreq(n), m_displayWidth); + float x_next = freqToXPixel(binToFreq(n + 1), m_displayWidth); + float y = ampToYPixel(displayBuffer[n], m_displayBottom); + + // consider making a point only if x falls within display bounds + if (0 < x && x < m_displayWidth) + { + if (x_start == -1) + { + x_start = x; + // the first displayed bin is stretched to the left edge to prevent + // creating a misleading slope leading to zero (at log. scale) + path.lineTo(m_displayLeft, y + m_displayTop); + } + // Opt.: QPainter is very slow -- draw at most [pixel_limit] points + // per logical pixel. As opposed to limiting the bin count, this + // allows high resolution display if user resizes the analyzer. + // Look at bins that share the pixel and use the highest value: + max = y < max ? y : max; + // And make the final point in the middle of current interval. + if ((int)(x * pixel_limit) != (int)(x_next * pixel_limit)) + { + x = (x + x_start) / 2; + path.lineTo(x + m_displayLeft, max + m_displayTop); + max = m_displayBottom; + x_start = x_next; + } + } + else + { + // stop processing after a bin falls outside right edge + // and align it to the edge to prevent a gap + if (n > 0 && x > 0) + { + path.lineTo(m_displayRight, y + m_displayTop); + break; + } + } + } + path.lineTo(m_displayRight, m_displayBottom); + path.closeSubpath(); + return path; +} + + +// Draw background, grid and associated frequency and amplitude labels. +void SaSpectrumView::drawGrid(QPainter &painter) +{ + std::vector> *freqTics = NULL; + std::vector> *ampTics = NULL; + float pos = 0; + float label_width = 24; + float label_height = 15; + float margin = 5; + + // always draw the background + painter.fillRect(m_displayLeft, m_displayTop, + m_displayWidth, m_displayBottom, + m_controls->m_colorBG); + + // select logarithmic or linear frequency grid and draw it + if (m_controls->m_logXModel.value()) + { + freqTics = &m_logFreqTics; + } + else + { + freqTics = &m_linearFreqTics; + } + // draw frequency grid (line.first is display position) + painter.setPen(QPen(m_controls->m_colorGrid, 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + for (auto &line: *freqTics) + { + painter.drawLine(m_displayLeft + freqToXPixel(line.first, m_displayWidth), + 2, + m_displayLeft + freqToXPixel(line.first, m_displayWidth), + m_displayBottom); + } + // print frequency labels (line.second is label) + painter.setPen(QPen(m_controls->m_colorLabels, 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + for (auto & line: *freqTics) + { + pos = m_displayLeft + freqToXPixel(line.first, m_displayWidth); + // align first and last label to the edge if needed, otherwise center them + if (line == freqTics->front() && pos - label_width / 2 < m_displayLeft) + { + painter.drawText(m_displayLeft, m_displayBottom + margin, + label_width, label_height, Qt::AlignLeft | Qt::TextDontClip, + QString(line.second.c_str())); + } + else if (line == freqTics->back() && pos + label_width / 2 > m_displayRight) + { + painter.drawText(m_displayRight - label_width, m_displayBottom + margin, + label_width, label_height, Qt::AlignRight | Qt::TextDontClip, + QString(line.second.c_str())); + } + else + { + painter.drawText(pos - label_width / 2, m_displayBottom + margin, + label_width, label_height, Qt::AlignHCenter | Qt::TextDontClip, + QString(line.second.c_str())); + } + } + + margin = 2; + // select logarithmic or linear amplitude grid and draw it + if (m_controls->m_logYModel.value()) + { + ampTics = &m_logAmpTics; + } + else + { + ampTics = &m_linearAmpTics; + } + // draw amplitude grid + painter.setPen(QPen(m_controls->m_colorGrid, 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + for (auto & line: *ampTics) + { + painter.drawLine(m_displayLeft + 1, + ampToYPixel(line.first, m_displayBottom), + m_displayRight - 1, + ampToYPixel(line.first, m_displayBottom)); + } + // print amplitude labels + painter.setPen(QPen(m_controls->m_colorLabels, 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + bool stereo = m_controls->m_stereoModel.value(); + for (auto & line: *ampTics) + { + pos = ampToYPixel(line.first, m_displayBottom); + // align first and last labels to edge if needed, otherwise center them + if (line == ampTics->back() && pos < 8) + { + if (stereo) + { + painter.setPen(QPen(m_controls->m_colorL.lighter(), 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + } + painter.drawText(m_displayLeft - label_width - margin, m_displayTop - 2, + label_width, label_height, Qt::AlignRight | Qt::AlignTop | Qt::TextDontClip, + QString(line.second.c_str())); + if (stereo) + { + painter.setPen(QPen(m_controls->m_colorR.lighter(), 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + } + painter.drawText(m_displayRight + margin, m_displayTop - 2, + label_width, label_height, Qt::AlignLeft | Qt::AlignTop | Qt::TextDontClip, + QString(line.second.c_str())); + } + else if (line == ampTics->front() && pos > m_displayBottom - label_height) + { + if (stereo) + { + painter.setPen(QPen(m_controls->m_colorL.lighter(), 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + } + painter.drawText(m_displayLeft - label_width - margin, m_displayBottom - label_height + 2, + label_width, label_height, Qt::AlignRight | Qt::AlignBottom | Qt::TextDontClip, + QString(line.second.c_str())); + if (stereo) + { + painter.setPen(QPen(m_controls->m_colorR.lighter(), 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + } + painter.drawText(m_displayRight + margin, m_displayBottom - label_height + 2, + label_width, label_height, Qt::AlignLeft | Qt::AlignBottom | Qt::TextDontClip, + QString(line.second.c_str())); + } + else + { + if (stereo) + { + painter.setPen(QPen(m_controls->m_colorL.lighter(), 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + } + painter.drawText(m_displayLeft - label_width - margin, pos - label_height / 2, + label_width, label_height, Qt::AlignRight | Qt::AlignVCenter | Qt::TextDontClip, + QString(line.second.c_str())); + if (stereo) + { + painter.setPen(QPen(m_controls->m_colorR.lighter(), 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + } + painter.drawText(m_displayRight + margin, pos - label_height / 2, + label_width, label_height, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextDontClip, + QString(line.second.c_str())); + } + } +} + + +// Draw cursor and its coordinates if it is within display bounds. +void SaSpectrumView::drawCursor(QPainter &painter) +{ + if( m_cursor.x() >= m_displayLeft + && m_cursor.x() <= m_displayRight + && m_cursor.y() >= m_displayTop + && m_cursor.y() <= m_displayBottom) + { + // cursor lines + painter.setPen(QPen(m_controls->m_colorGrid.lighter(), 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + painter.drawLine(m_cursor.x(), m_displayTop, m_cursor.x(), m_displayBottom); + painter.drawLine(m_displayLeft, m_cursor.y(), m_displayRight, m_cursor.y()); + + // coordinates + painter.setPen(QPen(m_controls->m_colorLabels.darker(), 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + painter.drawText(m_displayRight -60, 5, 100, 16, Qt::AlignLeft, "Cursor"); + + QString tmps; + // frequency + int xFreq = (int)m_processor->xPixelToFreq(m_cursor.x() - m_displayLeft, m_displayWidth); + tmps = QString(std::string(std::to_string(xFreq) + " Hz").c_str()); + painter.drawText(m_displayRight -60, 18, 100, 16, Qt::AlignLeft, tmps); + + // amplitude + float yAmp = m_processor->yPixelToAmp(m_cursor.y(), m_displayBottom); + if (m_controls->m_logYModel.value()) + { + tmps = QString(std::string(std::to_string(yAmp).substr(0, 5) + " dB").c_str()); + } + else + { + // add 0.0005 to get proper rounding to 3 decimal places + tmps = QString(std::string(std::to_string(0.0005f + yAmp)).substr(0, 5).c_str()); + } + painter.drawText(m_displayRight -60, 30, 100, 16, Qt::AlignLeft, tmps); + } +} + + +// Wrappers for most used SaProcessor helpers (to make local code more compact). +float SaSpectrumView::binToFreq(unsigned int bin_index) +{ + return m_processor->binToFreq(bin_index); +} + + +float SaSpectrumView::freqToXPixel(float frequency, unsigned int width) +{ + return m_processor->freqToXPixel(frequency, width); +} + + +float SaSpectrumView::ampToYPixel(float amplitude, unsigned int height) +{ + return m_processor->ampToYPixel(amplitude, height); +} + + +// Generate labels suitable for logarithmic frequency scale. +// Low / high limits are in Hz. Lowest possible label is 10 Hz. +std::vector> SaSpectrumView::makeLogFreqTics(int low, int high) +{ + std::vector> result; + int i, j; + int a[] = {10, 20, 50}; // sparse series multipliers + int b[] = {14, 30, 70}; // additional (denser) series + + // generate main steps (powers of 10); use the series to specify smaller steps + for (i = 1; i <= high; i *= 10) + { + for (j = 0; j < 3; j++) + { + // insert a label from sparse series if it falls within bounds + if (i * a[j] >= low && i * a[j] <= high) + { + if (i * a[j] < 1000) + { + result.emplace_back(i * a[j], std::to_string(i * a[j])); + } + else + { + result.emplace_back(i * a[j], std::to_string(i * a[j] / 1000) + "k"); + } + } + // also insert denser series if high and low values are close + if ((log10(high) - log10(low) < 2) && (i * b[j] >= low && i * b[j] <= high)) + { + if (i * b[j] < 1500) + { + result.emplace_back(i * b[j], std::to_string(i * b[j])); + } + else + { + result.emplace_back(i * b[j], std::to_string(i * b[j] / 1000) + "k"); + } + } + } + } + return result; +} + + +// Generate labels suitable for linear frequency scale. +// Low / high limits are in Hz. +std::vector> SaSpectrumView::makeLinearFreqTics(int low, int high) +{ + std::vector> result; + int i, increment; + + // select a suitable increment based on zoom level + if (high - low < 500) {increment = 50;} + else if (high - low < 1000) {increment = 100;} + else if (high - low < 5000) {increment = 1000;} + else {increment = 2000;} + + // generate steps based on increment, starting at 0 + for (i = 0; i <= high; i += increment) + { + if (i >= low) + { + if (i < 1000) + { + result.emplace_back(i, std::to_string(i)); + } + else + { + result.emplace_back(i, std::to_string(i/1000) + "k"); + } + } + } + return result; +} + + +// Generate labels suitable for logarithmic (dB) amplitude scale. +// Low / high limits are in dB; 0 dB amplitude = 1.0 linear. +// Treating results as power ratio, i.e., 3 dB should be about twice as loud. +std::vector> SaSpectrumView::makeLogAmpTics(int low, int high) +{ + std::vector> result; + float i; + double increment; + + // Base zoom level on selected range and how close is the current height + // to the sizeHint() (denser scale for bigger window). + if ((high - low) < 20 * ((float)height() / sizeHint().height())) + { + increment = pow(10, 0.3); // 3 dB steps when really zoomed in + } + else if (high - low < 45 * ((float)height() / sizeHint().height())) + { + increment = pow(10, 0.6); // 6 dB steps when sufficiently zoomed in + } + else + { + increment = 10; // 10 dB steps otherwise + } + + // Generate n dB increments, start checking at -90 dB. Limits are tweaked + // just a little bit to make sure float comparisons do not miss edges. + for (i = 0.000000001; 10 * log10(i) <= (high + 0.001); i *= increment) + { + if (10 * log10(i) >= (low - 0.001)) + { + result.emplace_back(i, std::to_string((int)std::round(10 * log10(i)))); + } + } + return result; +} + + +// Generate labels suitable for linear amplitude scale. +// Low / high limits are in dB; 0 dB amplitude = 1.0 linear. +// Smallest possible label is 0.001, largest is 999. This includes the majority +// of useful labels; going lower or higher would require increasing margin size +// so that the text can fit. That would be a waste of space -- the linear scale +// would only make the experience worse for the main, logarithmic (dB) scale. +std::vector> SaSpectrumView::makeLinearAmpTics(int low, int high) +{ + std::vector> result; + double i, nearest; + + // make about 5 labels when window is small, 10 if it is big + float split = (float)height() / sizeHint().height() >= 1.5 ? 10.0 : 5.0; + + // convert limits to linear scale + float lin_low = pow(10, low / 10.0); + float lin_high = pow(10, high / 10.0); + + // Linear scale will vary widely, so instead of trying to craft extra nice + // multiples, just generate a few evenly spaced increments across the range, + // paying attention only to the decimal places to keep labels short. + // Limits are shifted a bit so that float comparisons do not miss edges. + for (i = 0; i <= (lin_high + 0.0001); i += (lin_high - lin_low) / split) + { + if (i >= (lin_low - 0.0001)) + { + if (i >= 9.99 && i < 99.9) + { + nearest = std::round(i); + result.emplace_back(nearest, std::to_string(nearest).substr(0, 2)); + } + else if (i >= 0.099) + { // also covers numbers above 100 + nearest = std::round(i * 10) / 10; + result.emplace_back(nearest, std::to_string(nearest).substr(0, 3)); + } + else if (i >= 0.0099) + { + nearest = std::round(i * 1000) / 1000; + result.emplace_back(nearest, std::to_string(nearest).substr(0, 4)); + } + else if (i >= 0.00099) + { + nearest = std::round(i * 10000) / 10000; + result.emplace_back(nearest, std::to_string(nearest).substr(1, 4)); + } + else if (i > -0.01 && i < 0.01) + { + result.emplace_back(i, "0"); // an exception, zero is short.. + } + } + } + return result; +} + + +// Periodic update is called by LMMS. +void SaSpectrumView::periodicUpdate() +{ + // check if the widget is visible; if it is not, processing can be paused + m_processor->setSpectrumActive(isVisible()); + // tell Qt it is time for repaint + update(); +} + + +// Handle mouse input: set new cursor position. +void SaSpectrumView::mouseMoveEvent(QMouseEvent *event) +{ + m_cursor = event->pos(); +} + +void SaSpectrumView::mousePressEvent(QMouseEvent *event) +{ + m_cursor = event->pos(); +} + + +// Handle resize event: rebuild grid and labels +void SaSpectrumView::resizeEvent(QResizeEvent *event) +{ + // frequency does not change density with size + // amplitude does: rebuild labels + m_logAmpTics = makeLogAmpTics(m_processor->getAmpRangeMin(), m_processor->getAmpRangeMax()); + m_linearAmpTics = makeLinearAmpTics(m_processor->getAmpRangeMin(), m_processor->getAmpRangeMax()); +} + diff --git a/plugins/SpectrumAnalyzer/SaSpectrumView.h b/plugins/SpectrumAnalyzer/SaSpectrumView.h new file mode 100644 index 000000000..0db5852e1 --- /dev/null +++ b/plugins/SpectrumAnalyzer/SaSpectrumView.h @@ -0,0 +1,126 @@ +/* SaSpectrumView.h - declaration of SaSpectrumView class. + * + * Copyright (c) 2019 Martin Pavelek + * + * Based partially on Eq plugin code, + * Copyright (c) 2014 David French + * + * 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 SASPECTRUMVIEW_H +#define SASPECTRUMVIEW_H + +#include +#include +#include +#include + +class QMouseEvent; +class QPainter; +class SaControls; +class SaProcessor; + +//! Widget that displays a spectrum curve and frequency / amplitude grid +class SaSpectrumView : public QWidget +{ + Q_OBJECT +public: + explicit SaSpectrumView(SaControls *controls, SaProcessor *processor, QWidget *_parent = 0); + virtual ~SaSpectrumView() {} + + QSize sizeHint() const override {return QSize(400, 200);} + +protected: + void paintEvent(QPaintEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + +private slots: + void periodicUpdate(); + +private: + const SaControls *m_controls; + SaProcessor *m_processor; + + // grid labels (position, label) and methods to generate them + std::vector> m_logFreqTics; // 10-20-50... Hz + std::vector> m_linearFreqTics; // 2k-4k-6k... Hz + std::vector> m_logAmpTics; // dB + std::vector> m_linearAmpTics; // 0..1 + + std::vector> makeLogFreqTics(int low, int high); + std::vector> makeLinearFreqTics(int low, int high); + std::vector> makeLogAmpTics(int low, int high); + std::vector> makeLinearAmpTics(int low, int high); + + // currently selected ranges (see SaControls.h for enum definitions) + int m_freqRangeIndex; + int m_ampRangeIndex; + + // draw the grid and all labels based on selected ranges + void drawGrid(QPainter &painter); + + // local buffers for frequency bin values and a method to update them + // (mainly needed for averaging and to keep track of peak values) + std::vector m_displayBufferL; + std::vector m_displayBufferR; + std::vector m_peakBufferL; + std::vector m_peakBufferR; + void updateBuffers(float *spectrum, float *displayBuffer, float *peakBuffer); + + // final paths to be drawn by QPainter and methods to build them + QPainterPath m_pathL; + QPainterPath m_pathR; + QPainterPath m_pathPeakL; + QPainterPath m_pathPeakR; + void refreshPaths(); + QPainterPath makePath(std::vector &displayBuffer, float resolution); + + // helper variables for path drawing + float m_decaySum; // indicates if there is anything left to draw + bool m_freezeRequest; // new reference should be acquired + bool m_frozen; // a reference is currently stored in the peakBuffer + + const float m_smoothFactor = 0.15; // alpha for exponential smoothing + const float m_peakDecayFactor = 0.992; // multiplier for gradual peak decay + + // top level: refresh buffers, make paths and draw the spectrum + void drawSpectrum(QPainter &painter); + + // current cursor location and a method to draw it + QPoint m_cursor; + void drawCursor(QPainter &painter); + + // wrappers for most used SaProcessor conversion helpers + // (to make local code more readable) + float binToFreq(unsigned int bin_index); + float freqToXPixel(float frequency, unsigned int width); + float ampToYPixel(float amplitude, unsigned int height); + + // current boundaries for drawing + unsigned int m_displayTop; + unsigned int m_displayBottom; + unsigned int m_displayLeft; + unsigned int m_displayRight; + unsigned int m_displayWidth; +}; +#endif // SASPECTRUMVIEW_H + diff --git a/plugins/SpectrumAnalyzer/SaWaterfallView.cpp b/plugins/SpectrumAnalyzer/SaWaterfallView.cpp new file mode 100644 index 000000000..617e80b2c --- /dev/null +++ b/plugins/SpectrumAnalyzer/SaWaterfallView.cpp @@ -0,0 +1,230 @@ +/* SaWaterfallViewView.cpp - implementation of SaWaterfallViewView class. + * + * Copyright (c) 2019 Martin Pavelek + * + * 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 "SaWaterfallView.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "EffectControlDialog.h" +#include "GuiApplication.h" +#include "MainWindow.h" +#include "SaProcessor.h" + + +SaWaterfallView::SaWaterfallView(SaControls *controls, SaProcessor *processor, QWidget *_parent) : + QWidget(_parent), + m_controls(controls), + m_processor(processor) +{ + m_controlDialog = (EffectControlDialog*) _parent; + setMinimumSize(300, 150); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + connect(gui->mainWindow(), SIGNAL(periodicUpdate()), this, SLOT(periodicUpdate())); + + m_timeTics = makeTimeTics(); + m_oldTimePerLine = (float)m_processor->m_inBlockSize / m_processor->getSampleRate(); +} + + +// Compose and draw all the content; called by Qt. +// Not as performance sensitive as SaSpectrumView, most of the processing is +// done directly in SaProcessor. +void SaWaterfallView::paintEvent(QPaintEvent *event) +{ + #ifdef SA_DEBUG + int start_time = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + #endif + + // all drawing done here, local variables are sufficient for the boundary + const int displayTop = 1; + const int displayBottom = height() -2; + const int displayLeft = 26; + const int displayRight = width() -26; + const int displayWidth = displayRight - displayLeft; + float label_width = 20; + float label_height = 16; + float margin = 2; + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing, true); + + // check if time labels need to be rebuilt + if ((float)m_processor->m_inBlockSize / m_processor->getSampleRate() != m_oldTimePerLine) + { + m_timeTics = makeTimeTics(); + m_oldTimePerLine = (float)m_processor->m_inBlockSize / m_processor->getSampleRate(); + } + + // print time labels + float pos = 0; + painter.setPen(QPen(m_controls->m_colorLabels, 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + for (auto & line: m_timeTics) + { + pos = timeToYPixel(line.first, displayBottom); + // align first and last label to the edge if needed, otherwise center them + if (line == m_timeTics.front() && pos < label_height / 2) + { + painter.drawText(displayLeft - label_width - margin, displayTop - 1, + label_width, label_height, Qt::AlignRight | Qt::AlignTop | Qt::TextDontClip, + QString(line.second.c_str())); + painter.drawText(displayRight + margin, displayTop - 1, + label_width, label_height, Qt::AlignLeft | Qt::AlignTop | Qt::TextDontClip, + QString(line.second.c_str())); + } + else if (line == m_timeTics.back() && pos > displayBottom - label_height + 2) + { + painter.drawText(displayLeft - label_width - margin, displayBottom - label_height, + label_width, label_height, Qt::AlignRight | Qt::AlignBottom | Qt::TextDontClip, + QString(line.second.c_str())); + painter.drawText(displayRight + margin, displayBottom - label_height + 2, + label_width, label_height, Qt::AlignLeft | Qt::AlignBottom | Qt::TextDontClip, + QString(line.second.c_str())); + } + else + { + painter.drawText(displayLeft - label_width - margin, pos - label_height / 2, + label_width, label_height, Qt::AlignRight | Qt::AlignVCenter | Qt::TextDontClip, + QString(line.second.c_str())); + painter.drawText(displayRight + margin, pos - label_height / 2, + label_width, label_height, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextDontClip, + QString(line.second.c_str())); + } + } + + // draw the spectrogram precomputed in SaProcessor + if (m_processor->m_waterfallNotEmpty) + { + QMutexLocker lock(&m_processor->m_dataAccess); + painter.drawImage(displayLeft, displayTop, // top left corner coordinates + QImage(m_processor->m_history.data(), // raw pixel data to display + m_processor->binCount(), // width = number of frequency bins + m_processor->m_waterfallHeight, // height = number of history lines + QImage::Format_RGB32 + ).scaled(displayWidth, // scale to fit view.. + displayBottom, + Qt::IgnoreAspectRatio, + Qt::SmoothTransformation)); + lock.unlock(); + } + else + { + painter.fillRect(displayLeft, displayTop, displayWidth, displayBottom, QColor(0,0,0)); + } + + // always draw the outline + painter.setPen(QPen(m_controls->m_colorGrid, 2, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + painter.drawRoundedRect(displayLeft, displayTop, displayWidth, displayBottom, 2.0, 2.0); + + #ifdef SA_DEBUG + // display what FPS would be achieved if waterfall ran in a loop + start_time = std::chrono::high_resolution_clock::now().time_since_epoch().count() - start_time; + painter.setPen(QPen(m_controls->m_colorLabels, 1, Qt::SolidLine, Qt::RoundCap, Qt::BevelJoin)); + painter.drawText(displayRight -100, 10, 100, 16, Qt::AlignLeft, + QString(std::string("Max FPS: " + std::to_string(1000000000.0 / start_time)).c_str())); + #endif +} + + +// Convert time value to Y coordinate for display of given height. +float SaWaterfallView::timeToYPixel(float time, int height) +{ + float pixels_per_line = (float)height / m_processor->m_waterfallHeight; + float seconds_per_line = ((float)m_processor->m_inBlockSize / m_processor->getSampleRate()); + + return pixels_per_line * time / seconds_per_line; +} + + +// Generate labels for linear time scale. +std::vector> SaWaterfallView::makeTimeTics() +{ + std::vector> result; + float i; + + // upper limit defined by number of lines * time per line + float limit = m_processor->m_waterfallHeight * ((float)m_processor->m_inBlockSize / m_processor->getSampleRate()); + + // set increment so that about 8 tics are generated + float increment = std::round(10 * limit / 7) / 10; + + // NOTE: labels positions are rounded to match the (rounded) label value + for (i = 0; i <= limit; i += increment) + { + if (i < 10) + { + result.emplace_back(std::round(i * 10) / 10, std::to_string(std::round(i * 10) / 10).substr(0, 3)); + } + else + { + result.emplace_back(std::round(i), std::to_string(std::round(i)).substr(0, 2)); + } + } + return result; +} + + +// Periodically trigger repaint and check if the widget is visible. +// If it is not, stop drawing and inform the processor. +void SaWaterfallView::periodicUpdate() +{ + m_processor->setWaterfallActive(isVisible()); + if (isVisible()) {update();} +} + + +// Adjust window size and widget visibility when waterfall is enabled or disabbled. +void SaWaterfallView::updateVisibility() +{ + // get container of the control dialog to be resized if needed + QWidget *subWindow = m_controlDialog->parentWidget(); + + + if (m_controls->m_waterfallModel.value()) + { + // clear old data before showing the waterfall + QMutexLocker lock(&m_processor->m_dataAccess); + std::fill(m_processor->m_history.begin(), m_processor->m_history.end(), 0); + lock.unlock(); + + setVisible(true); + + // increase window size if it is too small + if (subWindow->size().height() < m_controlDialog->sizeHint().height()) + { + subWindow->resize(subWindow->size().width(), m_controlDialog->sizeHint().height()); + } + } + else + { + setVisible(false); + // decrease window size only if it does not violate sizeHint + subWindow->resize(subWindow->size().width(), m_controlDialog->sizeHint().height()); + } +} + diff --git a/plugins/SpectrumAnalyzer/SaWaterfallView.h b/plugins/SpectrumAnalyzer/SaWaterfallView.h new file mode 100644 index 000000000..0e104c0a1 --- /dev/null +++ b/plugins/SpectrumAnalyzer/SaWaterfallView.h @@ -0,0 +1,66 @@ +/* SaWaterfallView.h - declaration of SaWaterfallView class. + * + * Copyright (c) 2019 Martin Pavelek + * + * 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 SAWATERFALLVIEW_H +#define SAWATERFALLVIEW_H + +#include +#include +#include +#include +#include + +#include "SaControls.h" +#include "SaProcessor.h" + + +// Widget that displays a spectrum waterfall (spectrogram) and time labels. +class SaWaterfallView : public QWidget +{ + Q_OBJECT +public: + explicit SaWaterfallView(SaControls *controls, SaProcessor *processor, QWidget *_parent = 0); + virtual ~SaWaterfallView() {} + + QSize sizeHint() const override {return QSize(400, 350);} + + // Check if waterfall should be displayed and adjust window size if needed. + void updateVisibility(); + +protected: + void paintEvent(QPaintEvent *event) override; + +private slots: + void periodicUpdate(); + +private: + const SaControls *m_controls; + SaProcessor *m_processor; + const EffectControlDialog *m_controlDialog; + + // Methods and data used to make time labels + float m_oldTimePerLine; + float timeToYPixel(float time, int height); + std::vector> makeTimeTics(); + std::vector> m_timeTics; // 0..n (s) +}; +#endif // SAWATERFALLVIEW_H diff --git a/plugins/SpectrumAnalyzer/SpectrumAnalyzer.cpp b/plugins/SpectrumAnalyzer/SpectrumAnalyzer.cpp deleted file mode 100644 index 0b947a3ba..000000000 --- a/plugins/SpectrumAnalyzer/SpectrumAnalyzer.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - * SpectrumAnalyzer.cpp - spectrum analyzer effect plugin - * - * Copyright (c) 2008-2014 Tobias Doerffel - * - * This file is part of LMMS - https://lmms.io - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - -#include "SpectrumAnalyzer.h" - -#include "embed.h" -#include "plugin_export.h" - -extern "C" -{ - -Plugin::Descriptor PLUGIN_EXPORT spectrumanalyzer_plugin_descriptor = -{ - STRINGIFY( PLUGIN_NAME ), - "Spectrum Analyzer", - QT_TRANSLATE_NOOP( "pluginBrowser", "Graphical spectrum analyzer plugin" ), - "Tobias Doerffel ", - 0x0100, - Plugin::Effect, - new PluginPixmapLoader(), - NULL, - NULL -} ; - -} - - - -SpectrumAnalyzer::SpectrumAnalyzer( Model * _parent, - const Descriptor::SubPluginFeatures::Key * _key ) : - Effect( &spectrumanalyzer_plugin_descriptor, _parent, _key ), - m_saControls( this ), - m_framesFilledUp( 0 ), - m_energy( 0 ) -{ - memset( m_buffer, 0, sizeof( m_buffer ) ); - - m_specBuf = (fftwf_complex *) fftwf_malloc( ( FFT_BUFFER_SIZE + 1 ) * sizeof( fftwf_complex ) ); - m_fftPlan = fftwf_plan_dft_r2c_1d( FFT_BUFFER_SIZE*2, m_buffer, m_specBuf, FFTW_MEASURE ); -} - - - - -SpectrumAnalyzer::~SpectrumAnalyzer() -{ - fftwf_destroy_plan( m_fftPlan ); - fftwf_free( m_specBuf ); -} - - - - -bool SpectrumAnalyzer::processAudioBuffer( sampleFrame* _buf, const fpp_t _frames ) -{ - if( !isEnabled() || !isRunning () ) - { - return false; - } - - if( !m_saControls.isViewVisible() ) - { - return true; - } - - fpp_t f = 0; - if( _frames > FFT_BUFFER_SIZE ) - { - m_framesFilledUp = 0; - f = _frames - FFT_BUFFER_SIZE; - } - - const int cm = m_saControls.m_channelMode.value(); - - switch( cm ) - { - case MergeChannels: - for( ; f < _frames; ++f ) - { - m_buffer[m_framesFilledUp] = - ( _buf[f][0] + _buf[f][1] ) * 0.5; - ++m_framesFilledUp; - } - break; - case LeftChannel: - for( ; f < _frames; ++f ) - { - m_buffer[m_framesFilledUp] = _buf[f][0]; - ++m_framesFilledUp; - } - break; - case RightChannel: - for( ; f < _frames; ++f ) - { - m_buffer[m_framesFilledUp] = _buf[f][1]; - ++m_framesFilledUp; - } - break; - } - - if( m_framesFilledUp < FFT_BUFFER_SIZE ) - { - return isRunning(); - } - - -// hanming( m_buffer, FFT_BUFFER_SIZE, HAMMING ); - - const sample_rate_t sr = Engine::mixer()->processingSampleRate(); - const int LOWEST_FREQ = 0; - const int HIGHEST_FREQ = sr / 2; - - fftwf_execute( m_fftPlan ); - absspec( m_specBuf, m_absSpecBuf, FFT_BUFFER_SIZE+1 ); - if( m_saControls.m_linearSpec.value() ) - { - compressbands( m_absSpecBuf, m_bands, FFT_BUFFER_SIZE+1, - MAX_BANDS, - (int)(LOWEST_FREQ*(FFT_BUFFER_SIZE+1)/(float)(sr/2)), - (int)(HIGHEST_FREQ*(FFT_BUFFER_SIZE+1)/(float)(sr/2))); - m_energy = maximum( m_bands, MAX_BANDS ) / maximum( m_buffer, FFT_BUFFER_SIZE ); - } - else - { - calc13octaveband31( m_absSpecBuf, m_bands, FFT_BUFFER_SIZE+1, sr/2.0 ); - m_energy = signalpower( m_buffer, FFT_BUFFER_SIZE ) / maximum( m_buffer, FFT_BUFFER_SIZE ); - } - - - m_framesFilledUp = 0; - - checkGate( 1 ); - - return isRunning(); -} - - - - - -extern "C" -{ - -// necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin * lmms_plugin_main( Model* parent, void* data ) -{ - return new SpectrumAnalyzer( parent, static_cast( data ) ); -} - -} - diff --git a/plugins/SpectrumAnalyzer/SpectrumAnalyzer.h b/plugins/SpectrumAnalyzer/SpectrumAnalyzer.h deleted file mode 100644 index c92351176..000000000 --- a/plugins/SpectrumAnalyzer/SpectrumAnalyzer.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * SpectrumAnalyzer.h - spectrum anaylzer effect plugin - * - * Copyright (c) 2008-2014 Tobias Doerffel - * - * This file is part of LMMS - https://lmms.io - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - - -#ifndef _SPECTRUM_ANALYZER_H -#define _SPECTRUM_ANALYZER_H - -#include "Effect.h" -#include "fft_helpers.h" -#include "SpectrumAnalyzerControls.h" - - -const int MAX_BANDS = 249; - - -class SpectrumAnalyzer : public Effect -{ -public: - enum ChannelModes - { - MergeChannels, - LeftChannel, - RightChannel - } ; - - SpectrumAnalyzer( Model * _parent, - const Descriptor::SubPluginFeatures::Key * _key ); - virtual ~SpectrumAnalyzer(); - virtual bool processAudioBuffer( sampleFrame * _buf, - const fpp_t _frames ); - - virtual EffectControls * controls() - { - return( &m_saControls ); - } - - -private: - SpectrumAnalyzerControls m_saControls; - - fftwf_plan m_fftPlan; - - fftwf_complex * m_specBuf; - float m_absSpecBuf[FFT_BUFFER_SIZE+1]; - float m_buffer[FFT_BUFFER_SIZE*2]; - int m_framesFilledUp; - - float m_bands[MAX_BANDS]; - float m_energy; - - friend class SpectrumAnalyzerControls; - friend class SpectrumView; - -} ; - - -#endif diff --git a/plugins/SpectrumAnalyzer/SpectrumAnalyzerControlDialog.cpp b/plugins/SpectrumAnalyzer/SpectrumAnalyzerControlDialog.cpp deleted file mode 100644 index 05b1ed08a..000000000 --- a/plugins/SpectrumAnalyzer/SpectrumAnalyzerControlDialog.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* - * SpectrumAnalyzerControlDialog.cpp - view for spectrum analyzer - * - * Copyright (c) 2008-2014 Tobias Doerffel - * - * This file is part of LMMS - https://lmms.io - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - -#include - -#include -#include - -#include "SpectrumAnalyzer.h" -#include "MainWindow.h" -#include "GuiApplication.h" -#include "LedCheckbox.h" -#include "embed.h" - - -static inline void darken( QImage& img, int x, int y, int w, int h ) -{ - int imgWidth = img.width(); - QRgb * base = ( (QRgb *) img.bits() ) + y*imgWidth + x; - for( int y = 0; y < h; ++y ) - { - QRgb * d = base + y*imgWidth; - for( int x = 0; x < w; ++x ) - { - // shift each color component by 1 bit and set alpha - // to 0xff - d[x] = ( ( d[x] >> 1 ) & 0x7f7f7f7f ) | 0xff000000; - } - } -} - - - -class SpectrumView : public QWidget -{ -public: - SpectrumView( SpectrumAnalyzer* s, QWidget * _parent ) : - QWidget( _parent ), - m_sa( s ), - m_backgroundPlain( PLUGIN_NAME::getIconPixmap( "spectrum_background_plain" ).toImage() ), - m_background( PLUGIN_NAME::getIconPixmap( "spectrum_background" ).toImage() ) - { - setFixedSize( 249, 151 ); - connect( gui->mainWindow(), SIGNAL( periodicUpdate() ), this, SLOT( update() ) ); - setAttribute( Qt::WA_OpaquePaintEvent, true ); - } - - virtual ~SpectrumView() - { - } - - virtual void paintEvent( QPaintEvent* event ) - { - QPainter p( this ); - QImage i = m_sa->m_saControls.m_linearSpec.value() ? - m_backgroundPlain : m_background; - const float e = m_sa->m_energy; - if( e <= 0 ) - { - darken( i, 0, 0, i.width(), i.height() ); - p.drawImage( 0, 0, i ); - return; - } - - const bool lin_y = m_sa->m_saControls.m_linearYAxis.value(); - float * b = m_sa->m_bands; - const int LOWER_Y = -60; // dB - int h; - const int fh = height(); - if( m_sa->m_saControls.m_linearSpec.value() ) - { - if( lin_y ) - { - for( int x = 0; x < MAX_BANDS; ++x, ++b ) - { - h = fh * 2.0 / 3.0 * (*b / e ); - if( h < 0 ) h = 0; else if( h >= fh ) continue; - darken( i, x, 0, 1, fh-h ); - } - } - else - { - for( int x = 0; x < MAX_BANDS; ++x, ++b ) - { - h = (int)( fh * 2.0 / 3.0 * (20*(log10( *b / e ) ) - LOWER_Y ) / (-LOWER_Y ) ); - if( h < 0 ) h = 0; else if( h >= fh ) continue; - darken( i, x, 0, 1, fh-h ); - } - } - } - else - { - if( lin_y ) - { - for( int x = 0; x < 31; ++x, ++b ) - { - h = fh * 2.0 / 3.0 * ( 1.2 * *b / e ); - if( h < 0 ) h = 0; else if( h >= fh ) continue; else h = ( h / 3 ) * 3; - darken( i, x*8, 0, 8, fh-h ); - } - } - else - { - for( int x = 0; x < 31; ++x, ++b ) - { - h = (int)( fh * 2.0 / 3.0 * (20*(log10( *b / e ) ) - LOWER_Y ) / (-LOWER_Y ) ); - if( h < 0 ) h = 0; else if( h >= fh ) continue; else h = ( h / 3 ) * 3; - darken( i, x*8, 0, 8, fh-h ); - } - } - darken( i, 31*8, 0, 1, fh ); - } - p.drawImage( 0, 0, i ); - } - - -private: - SpectrumAnalyzer * m_sa; - QImage m_backgroundPlain; - QImage m_background; - -} ; - - - - -SpectrumAnalyzerControlDialog::SpectrumAnalyzerControlDialog( SpectrumAnalyzerControls* controls ) : - EffectControlDialog( controls ), - m_controls( controls ), - m_logXAxis( PLUGIN_NAME::getIconPixmap( "log_x_axis" ) ), - m_logYAxis( PLUGIN_NAME::getIconPixmap( "log_y_axis" ) ) -{ - setAutoFillBackground( true ); - QPalette pal; - pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "background" ) ); - setFixedSize( 293, 205 ); - setPalette( pal ); -/* QVBoxLayout * l = new QVBoxLayout( this );*/ - SpectrumView* v = new SpectrumView( controls->m_effect, this ); - v->move( 34, 10 ); - - LedCheckBox * lin_spec = new LedCheckBox( tr( "Linear spectrum" ), this ); - lin_spec->move( 32, 182 ); - lin_spec->setModel( &controls->m_linearSpec ); - - LedCheckBox * lin_y = new LedCheckBox( tr( "Linear Y axis" ), this ); - lin_y->move( 137, 182 ); - lin_y->setModel( &controls->m_linearYAxis ); - - connect( &controls->m_linearSpec, SIGNAL( dataChanged() ), this, SLOT( update() ) ); - connect( &controls->m_linearYAxis, SIGNAL( dataChanged() ), this, SLOT( update() ) ); -/* l->addWidget( v ); - l->addWidget( lin_spec ); - l->addWidget( lin_y );*/ - -} - - -void SpectrumAnalyzerControlDialog::paintEvent( QPaintEvent * ) -{ - QPainter p( this ); - - if( !m_controls->m_linearSpec.value() ) - { - p.drawPixmap( 33, 165, m_logXAxis ); - } - - if( !m_controls->m_linearYAxis.value() ) - { - p.drawPixmap( 10, 29, m_logYAxis); - } - -} diff --git a/plugins/SpectrumAnalyzer/SpectrumAnalyzerControls.cpp b/plugins/SpectrumAnalyzer/SpectrumAnalyzerControls.cpp deleted file mode 100644 index 4a59b3c0a..000000000 --- a/plugins/SpectrumAnalyzer/SpectrumAnalyzerControls.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SpectrumAnalyzerControls.cpp - controls for spectrum analyzer - * - * Copyright (c) 2008-2014 Tobias Doerffel - * - * This file is part of LMMS - https://lmms.io - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - - -#include "SpectrumAnalyzer.h" -#include "SpectrumAnalyzerControls.h" - - - -SpectrumAnalyzerControls::SpectrumAnalyzerControls( SpectrumAnalyzer* effect ) : - EffectControls( effect ), - m_effect( effect ), - m_linearSpec( false, this, tr( "Linear spectrum" ) ), - m_linearYAxis( false, this, tr( "Linear Y axis" ) ), - m_channelMode( SpectrumAnalyzer::MergeChannels, - SpectrumAnalyzer::MergeChannels, - SpectrumAnalyzer::RightChannel, - this, tr( "Channel mode" ) ) -{ -} - - - - -void SpectrumAnalyzerControls::loadSettings( const QDomElement & _this ) -{ -} - - - - -void SpectrumAnalyzerControls::saveSettings( QDomDocument & _doc, - QDomElement & _this ) -{ -} - - - - - diff --git a/plugins/SpectrumAnalyzer/SpectrumAnalyzerControls.h b/plugins/SpectrumAnalyzer/SpectrumAnalyzerControls.h deleted file mode 100644 index e46407863..000000000 --- a/plugins/SpectrumAnalyzer/SpectrumAnalyzerControls.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * SpectrumAnalyzerControls.h - controls for spectrum-analyzer - * - * Copyright (c) 2008-2014 Tobias Doerffel - * - * This file is part of LMMS - https://lmms.io - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - -#ifndef SPECTRUM_ANALYZER_CONTROLS_H -#define SPECTRUM_ANALYZER_CONTROLS_H - -#include "EffectControls.h" -#include "SpectrumAnalyzerControlDialog.h" -#include "Knob.h" - - -class SpectrumAnalyzer; - - -class SpectrumAnalyzerControls : public EffectControls -{ - Q_OBJECT -public: - SpectrumAnalyzerControls( SpectrumAnalyzer* effect ); - virtual ~SpectrumAnalyzerControls() - { - } - - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); - inline virtual QString nodeName() const - { - return "spectrumanaylzercontrols"; - } - - virtual int controlCount() - { - return 1; - } - - virtual EffectControlDialog * createView() - { - return new SpectrumAnalyzerControlDialog( this ); - } - - -private: - SpectrumAnalyzer* m_effect; - BoolModel m_linearSpec; - BoolModel m_linearYAxis; - IntModel m_channelMode; - - friend class SpectrumAnalyzer; - friend class SpectrumAnalyzerControlDialog; - friend class SpectrumView; - -} ; - -#endif diff --git a/plugins/SpectrumAnalyzer/background.png b/plugins/SpectrumAnalyzer/background.png deleted file mode 100644 index e375f7d34034b4452f38300573fba71722843fc8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 859 zcmeAS@N?(olHy`uVBq!ia0y~yU{nRN&vLK<$$#u=IzWo0*vT`50|;t3QaXTq&H|6f zVxao#Ak65bF}ngNC|TkfQ4*Y=R#Ki=l*&+EUaps!mtCBkSdglhUz9%kosAR&1Jeyp z7srr_IdAW7^!s>W)1w-S(zvWuX-#JL12`RYviKqSF)_LXp4IRI~@H6}nR#kAF z(jXGZ6y(C`A&AVGnf%+?{6eB8qvj%(B|h@`4xLL`mUIYBQ1Wu<(f|t*$+3`OSQ3Fn zQ(qvH<}~8Wt5_`Uu@Sp7QQQpV9BqwJI2wfM9gx&R23%4&!T@1-%n8;Y9iS1?cOAOO z3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/plugins/SpectrumAnalyzer/freeze.svg b/plugins/SpectrumAnalyzer/freeze.svg new file mode 100644 index 000000000..4c9a43c12 --- /dev/null +++ b/plugins/SpectrumAnalyzer/freeze.svg @@ -0,0 +1,296 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/SpectrumAnalyzer/freeze_off.svg b/plugins/SpectrumAnalyzer/freeze_off.svg new file mode 100644 index 000000000..b6353d7a7 --- /dev/null +++ b/plugins/SpectrumAnalyzer/freeze_off.svg @@ -0,0 +1,297 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/SpectrumAnalyzer/log_x_axis.png b/plugins/SpectrumAnalyzer/log_x_axis.png deleted file mode 100644 index 97c5e729dff984e1d8e6ddeca6542cb326cd8916..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1293 zcmeAS@N?(olHy`uVBq!ia0vp^|A3f>gBeJc3VkR9Qk(@Ik;M!Q+`=Ht$S`Y;1W=H@ z#M9T6{RW$?sG79Toz!5UkYtH#M2T~LZffz8 zz@VzC`s~@WKY#u}v@cq;2-%$K>S`eO(W6IBPEKlSYC!hNl`D@QKfZVG-ptI*{rmR= zO#li40fdp5n0V~iF$f!(1S(j&b}f)(V`GDe2L=WLxx&K0z+&+5@PL@`^XE?p14sga zh=>TX2t?zTFJFL+<;#}?6+lFQa3#^6qCe_=w4TqANh+UpF!I zDwj`PZSvKJ7ZesL8ODEl`*7Lq!1&O{&hzqX_MHm3b~GtJ;9%coiA_W}Q${s0oaZFFxbSGNWK$#CbO+@&5mkEHfte@0hZgVGmUKzx<*f dyfeRxv%gS&v}19}K498l@O1TaS?83{1OTnEkhTB- diff --git a/plugins/SpectrumAnalyzer/log_y_axis.png b/plugins/SpectrumAnalyzer/log_y_axis.png deleted file mode 100644 index e20d27001fa6079c66e5db296ae4f90784990cb2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 734 zcmeAS@N?(olHy`uVBq!ia0vp^B0yZt!3-pwzXogoQk(@Ik;M!Q+`=Ht$S`Y;1W=H@ z#M9T6{RW$?sJhPEs*kcjA;}Wgh!W@g+}zZ>5(ej@)Wnk16ovB4k_-iRPv3y>Mm}){ z21cd;pAc7|;{X5u14(;(dmsY{fNUUuFp#+*x&Qz5_4Uu4JBO@h^XAP!aflWmWB>mB zMMXutyu6PdJpu~ey?fW!*Z1$=zYql%FJ6Q&zJLD?G7iZ)pc){Tjg1YW07ya@5H)6I zW)KF1yl~+Hvh2Zw2Z7=yCMG~*A?C2MvbwsuK7IQ1!-o&wzI_9V1Jx@kDr#wI0liRK zTKfL|`+xub0d*OjcJKwt`IQ9u1v9X6D42Q_6c!d06_=J)RJV3bm^g9Lq^Z-V&zL!D z_M+u0R&U$C|MbO+*Kgi>`s~^B=PzEqeE;Fo=dWMCf~@%QEamTas2I-qe0GrA}$wu*|<61v6OR&sbp+uH@o%!zc$Yd zhq)oGNfL4W?`$83N@tzBKkxbClzuCQ)AwHg-(^?tBXa!x?e=FnufHzjZ+N%#cFO0p zttPoQJm~r@qtQn6P3 z>tnC3RIL`$Ub=CWxS8(lzMN_7+eL1usDEZLdmVng^}w>Xg{x$er)u(FN&Czhdmv?j U|CQ-Cf!<~CboFyt=akR{0KKt<8 diff --git a/plugins/SpectrumAnalyzer/pause.svg b/plugins/SpectrumAnalyzer/pause.svg new file mode 100644 index 000000000..d28a93aa5 --- /dev/null +++ b/plugins/SpectrumAnalyzer/pause.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/plugins/SpectrumAnalyzer/play.svg b/plugins/SpectrumAnalyzer/play.svg new file mode 100644 index 000000000..eb3178284 --- /dev/null +++ b/plugins/SpectrumAnalyzer/play.svg @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/plugins/SpectrumAnalyzer/spectrum_background.png b/plugins/SpectrumAnalyzer/spectrum_background.png deleted file mode 100644 index b65491bc39ae94adef4449c175edbabc70a0f021..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1849 zcmYLK4OCKB9JjTlW!5@Y&i2YIEwz@FIVEEjYC?*cX{m+P()?(MfS~2kjXp5v#L}js znF{7-VzylQ2y3hLhUIKIeVSryG~Ie(rjq3syZ6~SJDkVky#Kxb`}_JoG6Dm9E#@to zXJTSv!JvBwf%`jf<(tg`-+03m3T|`0^z-#LF~U!&sxlWmnVUcl^dB>F5<@>zi{e@LxxEb-EoX6#m%C&_ zNXQhHIY}&Mdqa$nSL!#wMUr0P#7TL@0t>K4P%f}k$gLAt=$-!ChQVF-%h-mNC2D~ zE>>41hgiVgW7RuAeE{7c4an}gh=h*zL?GDml=b#YT%!+hkujoEmIlD_6vUPC+|?!Y z1viZ2TLF4%UQSDkhJs*JCG+>JnH4#SUyZt`MUq-)9VFnmwuZAwUcgZ7Qo zER*OiYaYaI1RZV@Cm&B|aO_MwzrJJr-lZ3r+62H=m@bAcHYvu`qYovuYEh5yy9eM5 zJWc;G6iY6!Bq5-7`r=6;?{NFgY)Ip%?cS0nZhpYE9(K7HLTFN0<-GBy6d+y0t>IA5 zkv>BpzupDf72lcgVyi6$7dXa@jowp>>he*TvxY!J_kILRRa&&0k#$4R6NQwj7O|~R z=-K}{WS@&Ko6*Wne<^hf<=WKbYErASg>6>>h;H`zok1js{LSo=lx>u2Be_?|P|%&? zgaeT1=iB8lQwMSLkJv@V9lXPMQ#u6Enu2?^?zaR#386gx%FHSD)JE-BJZ*`4=zGnkf9_hMU$K6~9 zD*!VAi$nKwtIVI!as0`;w7M#M5Kz}wOpn1BC>2FZIjW0@dt(Zjcqh6~Rq}km@hS84 zS~zp4!n9o$-R|ahDXsb=?6~TJd-#dC=**>@-A3xPF(ufm!|0E_HfnLF$-)r$2#xJp z47?4)1?F*@*HJv}ONlk)RV5A%R@I0hwyc7kfH#4zINj%w8!@C@GNc!q!f5PS z8kd&>$2~TD9TdW@d8WV+}Zo{ww)sF7j*mqRMMca-J9Y5=o8VDn)SJ!V5(Ar zuf6zt1;)kW!<$Y)dSQ(+WKW*jMxtw`{(5!XmZV-6#(?5qWrZzpe)xPL82R6he1f#~ zG6^M!a%3@vJ}irpPQrZ3X|23$C>Q%66YSAVn#+<}+9UD>>%gC!3BxDATR}T~>OaUO B!UF&R diff --git a/plugins/SpectrumAnalyzer/spectrum_background_plain.png b/plugins/SpectrumAnalyzer/spectrum_background_plain.png deleted file mode 100644 index ba9bcd1c89d579945a5c58a83fb94de4460898d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 819 zcmXw1Ye-X39G}jd3cD^8HMtkN1hXjANYm?dPOqXOyM#tmOd3(KkbGPpnUBzPUL~Qy z?E&gizvw5I!cga{q0)BkgO9X@Op|$)+H~f~+H`4WS{(l8z~O&>kN@wqTq8310pS50 z4u_wem7WVu7pOOWzF;>E{22j<@7sBdvVe*t$+WGcMaLFsn zmS*tQ{6aWa!e6%+S~(nVeRg{4^~&Y#l>zCrBsgP!*V5PAYW>y#x4gVP7?k@%5Tx;$ zEG;Me&n1r^8GhNX8a~02&*Bf8!Ci>sd0t(GF`~me%;Y77I%3&SDYUIBYJ)APiIqq4 zw%9r~+)r~W$hB3qdDJF|Fezb+v`|Jl3A=@FSsxMdL|DIrh++j_8716mt1Ceg9va`9 zHFy&Hmc~UaC8R3pgL%I>RzHId(RhvQ7&!!TEwX|lQiLrU$~~k9l2glQN+V$Yos3Q6 z_Pjj6n?sqm6ScS?ifu&334-m6~`&vgof!x0M-|#UWp&- zwh6DvL6`e7!Yy<8@U7CrLuU`uJw}h_Q&mRk)*R&e`7s8Nqtrf7u7Y%(_nNAVwMyST zkIA`0a+X0?*@=IAh~vpT+r@Z^u;K+(H397jhv)_&?*^oMYyx5q7K5!KT?t~5f{84k zorj&Ub$vt)FQ6&1vDDhgP*OpeOTkvN%yf%2KtrVwSaAZ)DB_sv?GXg()Nm};Uq)9q z`hHi<=F|8n(+3#qU*X4gccNA$o(%NEP?)JcMM177YTM0PXjgS74%42DFL1~c&WdO3 zg(h@@E+FUFIw6mkSxTIK^lk`4xC&Cfq;_v?3eF;A^pqrtHP{6J*49*`Ae&#Xf)R7E_RV0#c9ws0|*DXaA$nBCddx zZ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/plugins/SpectrumAnalyzer/x_linear.svg b/plugins/SpectrumAnalyzer/x_linear.svg new file mode 100644 index 000000000..cef788670 --- /dev/null +++ b/plugins/SpectrumAnalyzer/x_linear.svg @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/plugins/SpectrumAnalyzer/x_log.svg b/plugins/SpectrumAnalyzer/x_log.svg new file mode 100644 index 000000000..8b8dc8b5a --- /dev/null +++ b/plugins/SpectrumAnalyzer/x_log.svg @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/plugins/SpectrumAnalyzer/y_linear.svg b/plugins/SpectrumAnalyzer/y_linear.svg new file mode 100644 index 000000000..69c39bb05 --- /dev/null +++ b/plugins/SpectrumAnalyzer/y_linear.svg @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/plugins/SpectrumAnalyzer/y_log.svg b/plugins/SpectrumAnalyzer/y_log.svg new file mode 100644 index 000000000..645e09e5a --- /dev/null +++ b/plugins/SpectrumAnalyzer/y_log.svg @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/src/core/fft_helpers.cpp b/src/core/fft_helpers.cpp index a17ebf719..bc7d289e3 100644 --- a/src/core/fft_helpers.cpp +++ b/src/core/fft_helpers.cpp @@ -2,6 +2,7 @@ * fft_helpers.cpp - some functions around FFT analysis * * Copyright (c) 2008-2012 Tobias Doerffel + * Copyright (c) 2019 Martin Pavelek * * This file is part of LMMS - https://lmms.io * @@ -28,127 +29,194 @@ #include #include "lmms_constants.h" -/* returns biggest value from abs_spectrum[spec_size] array - - returns -1 on error -*/ -float maximum(float *abs_spectrum, unsigned int spec_size) +/* Returns biggest value from abs_spectrum[spec_size] array. + * + * return -1 on error, otherwise the maximum value + */ +float maximum(const float *abs_spectrum, unsigned int spec_size) { - float maxi=0; + float maxi = 0; unsigned int i; - if ( abs_spectrum==NULL ) - return -1; + if (abs_spectrum == NULL) {return -1;} + if (spec_size <= 0) {return -1;} - if (spec_size<=0) - return -1; - - for ( i=0; imaxi ) - maxi=abs_spectrum[i]; + if (abs_spectrum[i] > maxi) {maxi = abs_spectrum[i];} } - return maxi; } +float maximum(const std::vector &abs_spectrum) +{ + return maximum(abs_spectrum.data(), abs_spectrum.size()); +} -/* apply hanning or hamming window to channel - returns -1 on error */ -int hanming(float *timebuffer, int length, WINDOWS type) +/* Normalize the array of absolute magnitudes to a 0..1 range. + * Block size refers to FFT block size before any zero padding. + * + * return -1 on error, 0 on success + */ +int normalize(const float *abs_spectrum, float *norm_spectrum, unsigned int bin_count, unsigned int block_size) { int i; - float alpha; - if ( (timebuffer==NULL)||(length<=0) ) - return -1; + if (abs_spectrum == NULL || norm_spectrum == NULL) {return -1;} + if (bin_count == 0 || block_size == 0) {return -1;} + for (i = 0; i < bin_count; i++) + { + norm_spectrum[i] = abs_spectrum[i] / block_size; + } + return 0; +} + +int normalize(const std::vector &abs_spectrum, std::vector &norm_spectrum, unsigned int block_size) +{ + if (abs_spectrum.size() != norm_spectrum.size()) {return -1;} + + return normalize(abs_spectrum.data(), norm_spectrum.data(), abs_spectrum.size(), block_size); +} + + +/* Check if the spectrum contains any non-zero value. + * + * return 1 if spectrum contains any non-zero value + * return 0 otherwise + */ +int notEmpty(const std::vector &spectrum) +{ + for (int i = 0; i < spectrum.size(); i++) + { + if (spectrum[i] != 0) {return 1;} + } + return 0; +} + + +/* Precompute an FFT window function for later real-time use. + * + * return -1 on error + */ +int precomputeWindow(float *window, unsigned int length, FFT_WINDOWS type, bool normalized) +{ + unsigned int i; + float gain = 0; + float a0; + float a1; + float a2; + float a3; + + if (window == NULL) {return -1;} + + // constants taken from + // https://en.wikipedia.org/wiki/Window_function#AList_of_window_functions switch (type) { - case HAMMING: alpha=0.54; break; + default: + case RECTANGULAR: + for (i = 0; i < length; i++) {window[i] = 1.0;} + gain = 1; + return 0; + case BLACKMAN_HARRIS: + a0 = 0.35875; + a1 = 0.48829; + a2 = 0.14128; + a3 = 0.01168; + break; + case HAMMING: + a0 = 0.54; + a1 = 1.0 - a0; + a2 = 0; + a3 = 0; + break; case HANNING: - default: alpha=0.5; break; + a0 = 0.5; + a1 = 1.0 - a0; + a2 = 0; + a3 = 0; + break; } - for ( i=0; i num_new - - returns 0 on success, else -1 */ -int compressbands(float *absspec_buffer, float *compressedband, int num_old, int num_new, int bottom, int top) +/* Build fewer subbands from many absolute spectrum values. + * Take care that - compressedbands[] array num_new elements long + * - num_old > num_new + * + * return 0 on success, else -1 + */ +int compressbands(const float *absspec_buffer, float *compressedband, int num_old, int num_new, int bottom, int top) { float ratio; int i, usefromold; float j; float j_min, j_max; - if ( (absspec_buffer==NULL)||(compressedband==NULL) ) - return -1; + if (absspec_buffer == NULL || compressedband == NULL) {return -1;} + if (num_old < num_new) {return -1;} + if (num_old <= 0 || num_new <= 0) {return -1;} + if (bottom < 0) {bottom = 0;} + if (top >= num_old) {top = num_old - 1;} - if ( num_old=num_old ) - top=num_old-1; - - usefromold=num_old-(num_old-top)-bottom; - - ratio=(float)usefromold/(float)num_new; + ratio = (float)usefromold / (float)num_new; // for each new subband - for ( i=0; iviewport(), windowFlags); win->setAttribute(Qt::WA_DeleteOnClose); win->setWidget(w); + if (w->sizeHint().isValid()) {win->resize(w->sizeHint());} m_workspace->addSubWindow(win); return win; } diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index 63bdee7a8..5cbac4cd6 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include "embed.h" diff --git a/src/gui/widgets/EffectView.cpp b/src/gui/widgets/EffectView.cpp index 2a492128b..a159eedf9 100644 --- a/src/gui/widgets/EffectView.cpp +++ b/src/gui/widgets/EffectView.cpp @@ -97,9 +97,14 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) : if( m_controlView ) { m_subWindow = gui->mainWindow()->addWindowedWidget( m_controlView ); - m_subWindow->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); - if (m_subWindow->layout()) { - m_subWindow->layout()->setSizeConstraint(QLayout::SetFixedSize); + + if ( !m_controlView->isResizable() ) + { + m_subWindow->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + if (m_subWindow->layout()) + { + m_subWindow->layout()->setSizeConstraint(QLayout::SetFixedSize); + } } Qt::WindowFlags flags = m_subWindow->windowFlags(); diff --git a/src/gui/widgets/PixmapButton.cpp b/src/gui/widgets/PixmapButton.cpp index 9858c221d..eb2553cf7 100644 --- a/src/gui/widgets/PixmapButton.cpp +++ b/src/gui/widgets/PixmapButton.cpp @@ -134,11 +134,11 @@ QSize PixmapButton::sizeHint() const { if( ( model() != NULL && model()->value() ) || m_pressed ) { - return m_activePixmap.size(); + return m_activePixmap.size() / devicePixelRatio(); } else { - return m_inactivePixmap.size(); + return m_inactivePixmap.size() / devicePixelRatio(); } } From 0ed75813559d943a1f318c5ca862c2c3931ec27e Mon Sep 17 00:00:00 2001 From: Freshek Date: Sat, 20 Jul 2019 15:19:10 +0200 Subject: [PATCH 351/445] Fixed renaming mixer channel from the context menu --- include/FxLine.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/FxLine.h b/include/FxLine.h index 6024026bd..ef8313e74 100644 --- a/include/FxLine.h +++ b/include/FxLine.h @@ -79,8 +79,6 @@ public: static const int FxLineHeight; - void renameChannel(); - bool eventFilter (QObject *dist, QEvent *event); private: @@ -101,6 +99,9 @@ private: QLineEdit * m_renameLineEdit; QGraphicsView * m_view; +public slots: + void renameChannel(); + private slots: void renameFinished(); void removeChannel(); From ba6a86d331ec2707a8dc6e244641bcdffb385ffe Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Mon, 22 Jul 2019 01:11:30 +0200 Subject: [PATCH 352/445] TabWidget: Improve size hints --- src/gui/widgets/TabWidget.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/gui/widgets/TabWidget.cpp b/src/gui/widgets/TabWidget.cpp index 125bbbd74..22d322612 100644 --- a/src/gui/widgets/TabWidget.cpp +++ b/src/gui/widgets/TabWidget.cpp @@ -319,8 +319,8 @@ QSize TabWidget::minimumSizeHint() const for ( widgetStack::const_iterator it = m_widgets.begin(); it != m_widgets.end(); ++it ) { - maxWidth = std::max(maxWidth, it->w->width()); - maxHeight = std::max(maxHeight, it->w->height()); + maxWidth = std::max(maxWidth, it->w->minimumSizeHint().width()); + maxHeight = std::max(maxHeight, it->w->minimumSizeHint().height()); } // "-1" : // in "addTab", under "Position tab's window", the widget is @@ -335,7 +335,21 @@ QSize TabWidget::minimumSizeHint() const QSize TabWidget::sizeHint() const { - return minimumSizeHint(); + if (m_resizable) + { + int maxWidth = 0, maxHeight = 0; + for ( widgetStack::const_iterator it = m_widgets.begin(); + it != m_widgets.end(); ++it ) + { + maxWidth = std::max(maxWidth, it->w->sizeHint().width()); + maxHeight = std::max(maxHeight, it->w->sizeHint().height()); + } + // "-1" : + // in "addTab", under "Position tab's window", the widget is + // moved up by 1 pixel + return QSize(maxWidth + 4, maxHeight + m_tabbarHeight - 1); + } + else { return QWidget::sizeHint(); } } From 6e7c4a47c2478804f2b07d0bc50caaddf1049d5f Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Mon, 22 Jul 2019 01:14:02 +0200 Subject: [PATCH 353/445] Fixes #5061: Fix Effect Rack View in Instrument The EffectRackView in an InstrumentTrackWindow had some parts hidden when loading files with >= 4 effects. This was now fixed by force-resizing the EffectRackView to its desired size. It's a dirty fix, but good enough, plus many Instrument UIs might get rewritten to be resizable in the future. --- src/tracks/InstrumentTrack.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 5466dd806..4c71eeef6 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -1477,6 +1477,8 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : adjustTabSize(m_ssView); adjustTabSize(instrumentFunctions); adjustTabSize(m_effectView); + // stupid bugfix, no one knows why + m_effectView->resize(INSTRUMENT_WIDTH - 4, INSTRUMENT_HEIGHT - 4 - 1); adjustTabSize(m_midiView); adjustTabSize(m_miscView); From 7492e53b022a3534e5f76a0241fcf161872afc48 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 22 Jul 2019 09:01:58 +0900 Subject: [PATCH 354/445] Fix broken translations in 12ea80d4fb1849d367c7c1ba0467fb72e54571f8 --- data/locale/cs.ts | 12000 ++++++++++++++++++++++++++++++------- data/locale/en.ts | 7019 +++++++++++++++++++++- data/locale/ko.ts | 5345 +++++++++++++++-- data/locale/ru.ts | 12931 ++++++++++++++++++++++++++++++++-------- data/locale/uk.ts | 12674 +++++++++++++++++++++++++++++++-------- data/locale/zh_TW.ts | 13108 +++++++++++++++++++++++++++++++++-------- 6 files changed, 53047 insertions(+), 10030 deletions(-) diff --git a/data/locale/cs.ts b/data/locale/cs.ts index ffb3b8a09..6e2435a4d 100644 --- a/data/locale/cs.ts +++ b/data/locale/cs.ts @@ -1,37 +1,113 @@ - - - + + + AboutDialog + + + About LMMS + O LMMS + + + + LMMS + LMMS + + + + Version %1 (%2/%3, Qt %4, %5) + Verze %1 (%2/%3, Qt %4, %5) + + + + About + O LMMS + + + + LMMS - easy music production for everyone + LMMS – snadné vytváření hudby pro každého + + + + Copyright © %1 + Copyright © %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 + Autoři + + + + Involved + Spolupracovníci + + + + Contributors ordered by number of commits: + Přispěvatelé řazení podle počtu příspěvků: + + + + Translation + Překlad + + + + 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! + Chcete-li vylepšit stávající překlad, Vaše pomoc bude vítána! Stačí jen kontaktovat vývojáře! + + + + License + Licence + + AmplifierControlDialog + VOL HLA + Volume: Hlasitost: + PAN PAN + Panning: Panoráma: + LEFT LEVÝ + Left gain: Zesílení vlevo: + RIGHT PRAVÝ + Right gain: Zesílení vpravo: @@ -39,95 +115,725 @@ AmplifierControls + Volume Hlasitost + Panning Panoráma + Left gain Zesílení vlevo + Right gain Zesílení vpravo + + AudioAlsaSetupWidget + + + DEVICE + ZAŘÍZENÍ + + + + CHANNELS + KANÁLY + + AudioFileProcessorView + + Open other sample + Otevřít jiný sampl + + + + 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. + Klepnutím sem můžete otevřít jiný audio soubor. Zobrazí se dialog, pomocí kterého si soubor můžete vybrat. Nastavení smyčky, počátečního a koncového bodu, zesílení apod. zůstanou nezměněná, takže to nemusí znít jako původní sampl. + + + Reverse sample Přehrávat pozpátku - Amplify: - Zesílení: - - - Continue sample playback across notes - Pokračovat v přehrávání samplu při změně noty + + If you enable this button, the whole sample is reversed. This is useful for cool effects, e.g. a reversed crash. + Zapnete-li toto tlačítko, celý sampl bude přehráván pozpátku. Tato volba je užitečná pro zajímavé efekty jako např. pozpátku přehraná srážka. + Disable loop Vypnout smyčku + + This button disables looping. The sample plays only once from start to end. + Toto tlačítko vypne smyčku. Sampl bude přehrán jen jednou od začátku do konce. + + + + Enable loop Zapnout smyčku + + This button enables forwards-looping. The sample loops between the end point and the loop point. + Toto tlačítko zapne smyčku směrem dopředu. Vzorek se bude vracet z koncového bodu na začátek. + + + + This button enables ping-pong-looping. The sample loops backwards and forwards between the end point and the loop point. + Toto tlačítko zapne smyčku typu ping-pong. Vzorek bude přehráván dopředu a zpět mezi koncovým bodem a začátkem smyčky. + + + + Continue sample playback across notes + Pokračovat v přehrávání samplu přes znějící tóny + + + + 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) + Povolení této možnosti způsobí, že se sampl bude přehrávat přes různé tóny – když změníte výšku tónu nebo když tón skončí před koncem samplu, bude další přehrávaný tón pokračovat tam, kde přestal. Pro obnovení přehrávání od začátku samplu vložte tón do spodní části klávesnice (< 20 Hz) + + + + Amplify: + Zesílení: + + + + 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!) + Tímto otočným ovladačem můžete nastavit poměr zesílení. Pokud nastavíte hodnotu 100%, sampl se nezmění. Jinak se zesílí nebo ztiší (váš stávající soubor samplu tím nebude nijak ovlivněn!) + + + + Startpoint: + Začátek samplu: + + + + With this knob you can set the point where AudioFileProcessor should begin playing your sample. + Tímto otočným ovladačem můžete nastavit bod, od kterého bude AudioFileProcessor přehrávat váš sampl. + + + + Endpoint: + Konec samplu: + + + + With this knob you can set the point where AudioFileProcessor should stop playing your sample. + Tímto otočným ovladačem můžete nastavit bod, ve kterém AudioFileProcessor zastaví přehrávání vašeho samplu. + + + Loopback point: Začátek smyčky: - Open sample - - - - Enable ping-pong loop - - - - Start point: - - - - End point: - + + With this knob you can set the point where the loop starts. + Tímto otočným ovladačem můžete nastavit bod, kterým začíná smyčka. AudioFileProcessorWaveView + Sample length: Délka samplu: + + AudioJack + + + JACK client restarted + Klient JACK je restartován + + + + 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 bylo z nějakého důvodu shozeno JACKem. Proto byl ovladač JACK v LMMS restartován. Musíte znovu provést ruční připojení. + + + + JACK server down + JACK server byl zastaven + + + + 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. + Vypnutí a nové spuštění serveru JACK se nezdařilo. LMMS proto nemůže pokračovat. Uložte svůj projekt a restartujte JACK i LMMS. + + + + CLIENT-NAME + JMÉNO-KLIENTA + + + + CHANNELS + KANÁLY + + + + AudioOss::setupWidget + + + DEVICE + ZAŘÍZENÍ + + + + CHANNELS + KANÁLY + + + + AudioPortAudio::setupWidget + + + BACKEND + OVLADAČ + + + + DEVICE + ZAŘÍZENÍ + + + + AudioPulseAudio::setupWidget + + + DEVICE + ZAŘÍZENÍ + + + + CHANNELS + KANÁLY + + + + AudioSdl::setupWidget + + + DEVICE + ZAŘÍZENÍ + + + + AudioSndio::setupWidget + + + DEVICE + ZAŘÍZENÍ + + + + CHANNELS + KANÁLY + + + + AudioSoundIo::setupWidget + + + BACKEND + OVLADAČ + + + + DEVICE + ZAŘÍZENÍ + + + + AutomatableModel + + + &Reset (%1%2) + &Resetovat hodnoty (%1%2) + + + + &Copy value (%1%2) + &Kopírovat hodnoty (%1%2) + + + + &Paste value (%1%2) + &Vložit hodnoty (%1%2) + + + + Edit song-global automation + Upravit hlavní automatizaci skladby + + + + Remove song-global automation + Odebrat hlavní automatizaci skladby + + + + Remove all linked controls + Odebrat všechny propojené ovládací prvky + + + + Connected to %1 + Připojeno k %1 + + + + Connected to controller + Připojeno k ovladači + + + + Edit connection... + Upravit připojení... + + + + Remove connection + Odebrat připojení + + + + Connect to controller... + Připojit k ovladači... + + + + AutomationEditor + + + Please open an automation pattern with the context menu of a control! + Otevřete prosím automatizační záznam pomocí kontextové nabídky ovládání! + + + + Values copied + Hodnoty zkopírovány + + + + All selected values were copied to the clipboard. + Všechny označené hodnoty byly zkopírovány do schránky. + + + + AutomationEditorWindow + + + Play/pause current pattern (Space) + Přehrát/Pozastavit přehrávání aktuálního záznamu (mezerník) + + + + 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. + Klepněte sem, pokud chcete přehrát aktuální záznam. To je užitečné při editaci. Záznam je automaticky přehráván ve smyčce. + + + + Stop playing of current pattern (Space) + Zastavit přehrávání aktuálního záznamu (mezerník) + + + + Click here if you want to stop playing of the current pattern. + Klepněte sem, pokud chcete zastavit přehrávání aktuálního záznamu. + + + + Edit actions + Akce úprav + + + + Draw mode (Shift+D) + Režim kreslení (Shift+D) + + + + Erase mode (Shift+E) + Režim mazání (Shift+E) + + + + Flip vertically + Převrátit vertikálně + + + + Flip horizontally + Převrátit horizontálně + + + + Click here and the pattern will be inverted.The points are flipped in the y direction. + Klepněte sem, pokud chcete převrátit záznam. Body budou převráceny v ose y. + + + + Click here and the pattern will be reversed. The points are flipped in the x direction. + Klepněte sem, pokud chcete převrátit záznam. Body budou převráceny v ose 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. + Klepněte sem, pokud chcete aktivovat režim kreslení. V tomto výchozím a nejčastěji užívaném režimu lze přidávat a přesunovat jednotlivé hodnoty. Pro aktivaci můžete využít též klávesové zkratky "Shift+D". + + + + 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. + Klepněte sem, pokud chcete aktivovat režim mazání. V tomto režimu lze mazat jednotlivé hodnoty. Pro aktivaci můžete využít též klávesové zkratky "Shift+E". + + + + Interpolation controls + Ovládání interpolace + + + + Discrete progression + Terasovitý průběh + + + + Linear progression + Lineární průběh + + + + Cubic Hermite progression + Křivkovitý průběh + + + + Tension value for spline + Hodnota napětí pro křivku + + + + 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. + Vyšší hodnota napětí vytvoří hladší křivku, ale více se vzdálí od zadaných hodnot. Nižší hodnota napětí upřednostní výchozí sklon křivky v každém kontrolním bodě. + + + + 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. + Klepnutím sem vyberete terasovitý vývoj pro tento automatizační záznam. Hodnota připojeného objektu zůstane neměnná mezi ovládacími body a okamžitě bude nastavena na novou hodnotu, když se dosáhne dalšího ovládacího bodu. + + + + 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. + Klepnutím sem vyberete lineární vývoj pro tento automatizační záznam. Hodnota připojeného objektu bude mezi ovládacími body měněna přímočaře, aby postupně došlo k dosažení dalšího kontrolního bodu. + + + + 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. + Klepnutím sem vyberte vývoj typu cubic hermite pro tento automatizační záznam. Hodnota připojeného objektu se změní po plynulé křivce a hladce přejde do vrchních i spodních bodů. + + + + Tension: + Napětí: + + + + Cut selected values (%1+X) + Vyjmout označené hodnoty (%1+X) + + + + Copy selected values (%1+C) + Kopírovat označené hodnoty (%1+C) + + + + Paste values from clipboard (%1+V) + Vložit hodnoty ze schránky (%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. + Klepněte sem, pokud chcete označené hodnoty vyjmout a uložit do schránky. Vložit je pak můžete kdekoliv v libovolném záznamu pomocí tlačítka Vložit. + + + + 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. + Klepněte sem, pokud chcete označené hodnoty zkopírovat do schránky. Vložit je pak můžete kdekoliv v libovolném záznamu pomocí tlačítka Vložit. + + + + Click here and the values from the clipboard will be pasted at the first visible measure. + Klepnete-li sem, budou hodnoty ze schránky vloženy do prvního viditelného taktu. + + + + Zoom controls + Ovládání zvětšení + + + + Quantization controls + Ovládání kvantizace + + + + Quantization + Kvantizace + + + + 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. + Kvantizace. Nastaví nejmenší velikost kroku pro body automatizace. Ve výchozím stavu také nastaví délku a vymazává další body v rozsahu. Stisknutím <Ctrl> zrušíte toto chování. + + + + + Automation Editor - no pattern + Editor automatizace – žádný záznam + + + + + Automation Editor - %1 + Editor automatizace – %1 + + + + Model is already connected to this pattern. + Model je již k tomuto záznamu připojen. + + + + AutomationPattern + + + Drag a control while pressing <%1> + Ovládací prvek táhni při stisknutém <%1> + + + + AutomationPatternView + + + double-click to open this pattern in automation editor + dvojklikem otevřít tento pattern v Editoru automatizace + + + + Open in Automation editor + Otevřít v Editoru automatizace + + + + Clear + Vyčistit + + + + Reset name + Obnovit výchozí jméno + + + + Change name + Změnit jméno + + + + Set/clear record + Zapnout/Vypnout záznam + + + + Flip Vertically (Visible) + Převrátit vertikálně (viditelné) + + + + Flip Horizontally (Visible) + Převrátit horizontálně (viditelné) + + + + %1 Connections + %1 Připojení + + + + Disconnect "%1" + Odpojit "%1" + + + + Model is already connected to this pattern. + Model je již k tomuto záznamu připojen. + + + + AutomationTrack + + + Automation track + Stopa automatizace + + + + BBEditor + + + Beat+Bassline Editor + Editor bicích/basů + + + + Play/pause current beat/bassline (Space) + Přehrát/Pozastavit přehrávání aktuálního záznamu bicích/basů (mezerník) + + + + Stop playback of current beat/bassline (Space) + Zastavit přehrávání aktuálního záznamu bicích/basů (mezerník) + + + + Click here to play the current beat/bassline. The beat/bassline is automatically looped when its end is reached. + Klepněte sem, pokud chcete přehrát aktuální záznam bicích/basů. Bicí/basy jsou automaticky přehrávány ve smyčce. + + + + Click here to stop playing of current beat/bassline. + Klepněte sem, pokud chcete zastavit přehrávání aktuálního záznamu bicích/basů. + + + + Beat selector + Výběr rytmu + + + + Track and step actions + Akce stopy a kroků + + + + Add beat/bassline + Přidat bicí/basy + + + + Add sample-track + Přidat stopu samplů + + + + Add automation-track + Přidat stopu automatizace + + + + Remove steps + Odstranit kroky + + + + Add steps + Přidat kroky + + + + Clone Steps + Klonovat kroky + + + + BBTCOView + + + Open in Beat+Bassline-Editor + Otevřít v editoru bicích/basů + + + + Reset name + Resetovat jméno + + + + Change name + Změnit jméno + + + + Change color + Změnit barvu + + + + Reset color to default + Obnovit výchozí barvy + + + + BBTrack + + + Beat/Bassline %1 + Bicí/basy %1 + + + + Clone of %1 + Klon z %1 + + BassBoosterControlDialog + FREQ FREKV + Frequency: Frekvence: + GAIN ZES + Gain: Zesílení: + RATIO POMĚR + Ratio: Poměr: @@ -135,14 +841,17 @@ BassBoosterControls + Frequency Frekvence + Gain Zesílení + Ratio Poměr @@ -150,1043 +859,2117 @@ BitcrushControlDialog + IN IN + OUT OUT + + GAIN ZISK - CLIP - OŘÍZ - - - Sample rate: - Vzorkovací frekvence: - - - Stereo difference: - Stereo rozdíl: - - - Levels: - Úrovně: + + Input Gain: + Zesílení vstupu: + NOISE ŠUM + + Input Noise: + Vstup šumu: + + + + Output Gain: + Zesílení výstupu: + + + + CLIP + OŘÍZ + + + + Output Clip: + Oříznutí výstupu: + + + + Rate Enabled + Frekvence zapnuta + + + + Enable samplerate-crushing + Zapnout drtič vzorkovací frekvence + + + + Depth Enabled + Hloubka zapnuta + + + + Enable bitdepth-crushing + Zapnout drtič bitové hloubky + + + FREQ FREKV + + Sample rate: + Vzorkovací frekvence: + + + STEREO STEREO + + Stereo difference: + Stereo rozdíl: + + + QUANT KVANT - Input gain: - Zesílení vstupu: - - - Input noise: - - - - Output gain: - Zesílení výstupu: - - - Output clip: - - - - Rate enabled - - - - Enable sample-rate crushing - - - - Depth enabled - - - - Enable bit-depth crushing - + + Levels: + Úrovně: - BitcrushControls + CaptionMenu - Input gain - Zesílení vstupu + + &Help + &Nápověda - Input noise - - - - Output gain - Zesílení výstupu - - - Output clip - - - - Sample rate - - - - Stereo difference - - - - Levels - - - - Rate enabled - - - - Depth enabled - + + Help (not available) + Nápověda (nedostupná) CarlaInstrumentView + Show GUI Ukázar grafické rozhraní + + + Click here to show or hide the graphical user interface (GUI) of Carla. + Klepněte sem pro zobrazení nebo skrytí grafického uživatelského rozhraní (GUI) Carla. + + + + Controller + + + Controller %1 + Ovladač %1 + + + + ControllerConnectionDialog + + + Connection Settings + Nastavení připojení + + + + MIDI CONTROLLER + MIDI OVLADAČ + + + + Input channel + Vstupní kanál + + + + CHANNEL + KANÁL + + + + Input controller + Vstupní ovladač + + + + CONTROLLER + OVLADAČ + + + + + Auto Detect + Autodetekce + + + + MIDI-devices to receive MIDI-events from + MIDI zařízení k přijmu MIDI události + + + + USER CONTROLLER + UŽIVATELSKÝ OVLADAČ + + + + MAPPING FUNCTION + MAPOVACÍ FUNKCE + + + + OK + OK + + + + Cancel + Zrušit + + + + LMMS + LMMS + + + + Cycle Detected. + Zjištěno zacyklení. + + + + ControllerRackView + + + Controller Rack + Ovladače + + + + Add + Přidat + + + + Confirm Delete + Potvrdit smazání + + + + Confirm delete? There are existing connection(s) associated with this controller. There is no way to undo. + Opravdu smazat? Je (jsou) zde propojení na tento ovladač. Nebude možné vrátit se zpět. + + + + ControllerView + + + Controls + Ovládací prvky + + + + Controllers are able to automate the value of a knob, slider, and other controls. + Kontroléry jsou schopny automatizovat nastavení otočných ovladačů, táhel a dalších řídicích prvků. + + + + Rename controller + Přejmenovat ovladač + + + + Enter the new name for this controller + Vložte nové jméno pro tento ovladač + + + + LFO + LFO + + + + &Remove this controller + Odst&ranit tento ovladač + + + + Re&name this controller + Přejme&novat tento ovladač + CrossoverEQControlDialog - Band 1/2 crossover: - + + Band 1/2 Crossover: + Přechod mezi pásmy 1/2: - Band 2/3 crossover: - + + Band 2/3 Crossover: + Přechod mezi pásmy 2/3: - Band 3/4 crossover: - + + Band 3/4 Crossover: + Přechod mezi pásmy 3/4: - Band 1 gain - + + Band 1 Gain: + Zesílení pásma 1: - Band 1 gain: - + + Band 2 Gain: + Zesílení pásma 2: - Band 2 gain - + + Band 3 Gain: + Zesílení pásma 3: - Band 2 gain: - + + Band 4 Gain: + Zesílení pásma 4: - Band 3 gain - + + Band 1 Mute + Ztlumení pásma 1 - Band 3 gain: - + + Mute Band 1 + Ztlumit pásmo 1 - Band 4 gain - + + Band 2 Mute + Ztlumení pásma 2 - Band 4 gain: - + + Mute Band 2 + Ztlumit pásmo 2 - Band 1 mute - + + Band 3 Mute + Ztlumení pásma 3 - Mute band 1 - + + Mute Band 3 + Ztlumit pásmo 3 - Band 2 mute - + + Band 4 Mute + Ztlumení pásma 4 - Mute band 2 - - - - Band 3 mute - - - - Mute band 3 - - - - Band 4 mute - - - - Mute band 4 - + + Mute Band 4 + Ztlumit pásmo 4 DelayControls + + Delay Samples + Zpoždění vzorků + + + Feedback Zpětná vazba + + Lfo Frequency + Frekvence LFO + + + + Lfo Amount + Hloubka LFO + + + Output gain Zesílení výstupu - - Delay samples - - - - LFO frequency - - - - LFO amount - - DelayControlsDialog - Gain - Zesílení - - + DELAY ZPOŽ - FDBK - FDBK + + Delay Time + Délka zpoždění + + FDBK + ZPVAZ + + + + Feedback Amount + Hloubka zpětné vazby + + + RATE RYCH + + Lfo + LFO + + + AMNT MNOŽ - Delay time - + + Lfo Amt + Hloubka LFO - Feedback amount - + + Out Gain + Zesílení výstupu - LFO frequency - - - - LFO amount - - - - Out gain - + + Gain + Zesílení DualFilterControlDialog - Filter 1 enabled - Filtr 1 zapnutý - - - Filter 2 enabled - Filtr 2 zapnutý - - + + FREQ FREKV + + Cutoff frequency Frekvence oříznutí + + RESO REZON + + Resonance Rezonance + + GAIN ZESIL + + Gain Zesílení + MIX POMĚR + Mix Poměr - Enable/disable filter 1 - + + Filter 1 enabled + Filtr 1 zapnutý - Enable/disable filter 2 - + + Filter 2 enabled + Filtr 2 zapnutý + + + + Click to enable/disable Filter 1 + Klepněte pro zapnutí/vypnutí filtru 1 + + + + Click to enable/disable Filter 2 + Klepněte pro zapnutí/vypnutí filtru 2 DualFilterControls + Filter 1 enabled Filtr 1 zapnutý + Filter 1 type Typ filtru 1 + + Cutoff 1 frequency + Frekvence oříznutí 1 + + + Q/Resonance 1 Q/rezonance 1 + Gain 1 Zesílení 1 + Mix Mix + Filter 2 enabled Filtr 1 zapnutý + Filter 2 type Typ filtru 2 + + Cutoff 2 frequency + Frekvence oříznutí 2 + + + Q/Resonance 2 Q/rezonance 2 + Gain 2 Zesílení 2 + + + LowPass + Dolní propust + + + + + HiPass + Horní propust + + + + + BandPass csg + Pásmová propust csg + + + + + BandPass czpg + Pásmová propust czpg + + + + Notch Pásmová zádrž + + + Allpass + Všepásmový filtr + + + + Moog Moogův filtr + + + 2x LowPass + 2x dolní propust + + + + + RC LowPass 12dB + RC dolní propust 12dB + + + + + RC BandPass 12dB + RC pásmová propust 12dB + + + + + RC HighPass 12dB + RC horní propust 12dB + + + + + RC LowPass 24dB + RC dolní propust 24dB + + + + + RC BandPass 24dB + RC pásmová propust 24dB + + + + + RC HighPass 24dB + RC horní propust 24dB + + + + + Vocal Formant Filter + Vokální formantový filtr + + + + 2x Moog 2x Moogův filtr + + + SV LowPass + SV dolní propust + + + + + SV BandPass + SV pásmová propust + + + + + SV HighPass + SV horní propust + + + + SV Notch SV pásmová zádrž + + Fast Formant Rychlý formantový filtr + + Tripole Třípólový filtr + + + Editor - Cutoff frequency 1 - + + Transport controls + Řízení přenosu - Cutoff frequency 2 - + + Play (Space) + Přehrát (mezerník) - Low-pass - + + Stop (Space) + Zastavit (mezerník) - Hi-pass - + + Record + Nahrávat - Band-pass csg - + + Record while playing + Nahrávat při přehrávání + + + + Effect + + + Effect enabled + Efekt aktivován - Band-pass czpg - + + Wet/Dry mix + Poměr zpracovaného/původního signálu - All-pass - + + Gate + Brána - 2x Low-pass - + + Decay + Pokles + + + + EffectChain + + + Effects enabled + Efekty aktivovány + + + + EffectRackView + + + EFFECTS CHAIN + ŘETĚZ EFEKTŮ - RC Low-pass 12 dB/oct - + + Add effect + Přidat efekt + + + + EffectSelectDialog + + + Add effect + Přidat efekt - RC Band-pass 12 dB/oct - + + + Name + Název - RC High-pass 12 dB/oct - + + Type + Typ - RC Low-pass 24 dB/oct - + + Description + Popis - RC Band-pass 24 dB/oct - + + Author + Autor + + + + EffectView + + + Toggles the effect on or off. + Zapnout nebo vypnout efekty. - RC High-pass 24 dB/oct - + + On/Off + Zap/Vyp - Vocal Formant - + + W/D + POM - SV Low-pass - + + Wet Level: + Úroveň zpracovaného signálu: - SV Band-pass - + + The Wet/Dry knob sets the ratio between the input signal and the effect signal that forms the output. + Otočný ovladač Poměr nastavuje poměr mezi vstupním signálem a signálem efektu, který formuje výstup. - SV High-pass - + + DECAY + POKLES + + + + Time: + Délka: + + + + 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. + Otočný ovladač Útlum nastavuje, kolik bufferů ticha musí proběhnout před tím, než plugin přestane zpracovávat. Menší hodnoty zredukují přetížení CPU, ale mohou způsobit oříznutí na konci zpožďovacích a dozvukových efektů. + + + + GATE + BRÁ + + + + Gate: + Brána: + + + + The Gate knob controls the signal level that is considered to be 'silence' while deciding when to stop processing signals. + Otočný ovladač Brána určuje sílu signálu, který je považován za "ticho" při rozhodování, kdy skončit se zpracováním signálů. + + + + Controls + Ovladače + + + + 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. + Efektové pluginy fungují jako zřetězená série efektů, kde signál bude postupně zpracováván shora dolů. + +Přepínač Zapnuto/Vypnuto vám umožní v libovolném časovém okamžiku daný plugin odpojit. + +Otočný ovladač Poměr řídí vyvážení mezi vstupním a již zpracovaným signálem ve výsledném výstupu efektu. Vstup je v této fázi shodný s výstupem předchozího efektu. Takže když je Poměr nastaven na nízkou hodnotu, obsahuje signál všechny předchozí efekty. + +Otočný ovladač Útlum určuje, jak dlouho bude zpracovávání signálu pokračovat po skončení noty. Efekt přestane zpracovávat signál, když hlasitost klesne pod hodnotu daného prahu v daném časovém úseku. Tento ovladač nastavuje právě "daný časový úsek". Delší časy vyžadují více výkonu procesoru, takže pro většinu efektů by měla být nastavena nízká hodnota. Naopak je potřeba nastavit vyšší hodnotu pro efekty, které vytvářejí delší úseky ticha, jako je např. echo (delay). +Otočný ovladač Brána určuje "daný práh" pro automatické ukončení efektu. + +Počítání délky "daného časového úseku" začíná bezprostředně poté, co úroveň zpracovávaného signálu poklesne pod úroveň určenou tímto ovladačem. + +Tlačítko Ovladače otevře dialogové okno pro úpravu parametrů efektu. + +Klepnutí pravým tlačítkem myši vyvolá kontextovou nabídku, kde můžete měnit pořadí, ve kterém budou efekty zpracovávány, nebo můžete efekt úplně odstranit. + + + + Move &up + Posunout &nahoru + + + + Move &down + Posunout &dolů + + + + &Remove this plugin + &Odstranit tento plugin + + + + EnvelopeAndLfoParameters + + + Predelay + Předzpoždění + + + + Attack + Náběh + + + + Hold + Držení + + + + Decay + Útlum + + + + Sustain + Vydržení + + + + Release + Doznění + + + + Modulation + Modulace + + + + LFO Predelay + Předzpoždění LFO + + + + LFO Attack + Náběh LFO + + + + LFO speed + Rychlost LFO + + + + LFO Modulation + Modulace LFO + + + + LFO Wave Shape + Tvar vlny LFO + + + + Freq x 100 + Frekvence x 100 + + + + Modulate Env-Amount + Hloubka modulace + + + + EnvelopeAndLfoView + + + + DEL + PŘED + + + + Predelay: + Předzpoždění: + + + + Use this knob for setting predelay of the current envelope. The bigger this value the longer the time before start of actual envelope. + Tento otočný ovladač nastavuje předzpoždění (predelay) aktuální obálky. Zvýšením hodnoty se prodlouží čas před začátkem obálky. + + + + + ATT + NÁB + + + + Attack: + Náběh: + + + + 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. + Tento otočný ovladač nastavuje náběh (attack) u aktuální obálky. Zvýšením hodnoty se prodlouží délka náběhu obálky. Zvolte nižší hodnotu pro nástroje typu piano a vyšší pro smyčce. + + + + HOLD + DRŽ + + + + Hold: + Držení: + + + + 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. + Tento otočný ovladač nastavuje délku držení (hold) u aktuální obálky. Zvýšením hodnoty se prodlouží část obálky, která zůstává na úrovni náběhu (attack) ještě před začátkem útlumu (decay) na úroveň vydržení (sustain). + + + + DEC + ÚTL + + + + Decay: + Útlum: + + + + 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. + Tento otočný ovladač nastavuje délku útlumu (decay) u aktuální obálky. Zvýšením hodnoty se prodlouží část obálky, potřebná k zeslabení z úrovně náběhu (attack) na úroveň vydržení (sustain). Zvolte nižší hodnotu pro nástroje typu piano. + + + + SUST + VYD + + + + Sustain: + Držení: + + + + 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. + Tento otočný ovladač nastavuje vydržení (sustain) u aktuální obálky. Zvýšením hodnoty se navýší úroveň, na které obálka zůstává před poklesem na nulu. + + + + REL + UVOL + + + + Release: + Uvolnění: + + + + 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. + Tento otočný ovladač nastavuje délku uvolnění (release) u aktuální obálky. Zvýšením hodnoty se prodlouží část obálky, potřebná k zeslabení z úrovně vydržení (sustain) na nulovou úroveň. Zvolte vyšší hodnotu pro nástroje s měkkým zvukem, jako např. smyčce. + + + + + AMT + MOD + + + + + Modulation amount: + Hloubka modulace: + + + + 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. + Tento otočný ovladač nastavuje hloubku modulace u aktuální obálky. Zvýšení této hodnoty v závislosti na velikosti (např. hlasitosti nebo frekvence odstřihnutí) způsobí větší ovlivnění touto obálkou. + + + + LFO predelay: + Předzpoždění 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. + Tento otočný ovladač nastavuje délku předzpoždění (predelay) aktuálního LFO. Zvýšením hodnoty se prodlouží čas před spuštěním kmitání LFO. + + + + LFO- attack: + Náběh 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. + Tento otočný ovladač nastavuje délku náběhu (attack) u aktuálního LFO. Zvýšením hodnoty se prodlouží čas potřebný pro zvýšení amplitudy LFO na maximum. + + + + SPD + RYCH + + + + LFO speed: + Rychlost 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. + Tento otočný ovladač nastavuje rychlost u aktuálního LFO. Zvýšením hodnoty se zrychlí kmitání LFO a průběh vašeho efektu. + + + + 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. + Tento otočný ovladač nastavuje hloubku modulace u aktuálního LFO. Zvýšení hodnoty v závislosti na velikosti (např. hlasitosti nebo frekvence odstřihnutí) způsobí větší ovlivnění tímto LFO. + + + + Click here for a sine-wave. + Klepněte sem pro sinusovou vlnu. + + + + Click here for a triangle-wave. + Klepněte sem pro trojúhelníkovou vlnu. + + + + Click here for a saw-wave for current. + Klepněte sem pro pilovitou vlnu. + + + + Click here for a square-wave. + Klepněte sem pro pravoúhlou vlnu. + + + + Click here for a user-defined wave. Afterwards, drag an according sample-file onto the LFO graph. + Klepněte sem pro vlastní vlnu. Poté přetáhněte zvolený soubor samplu do grafického okna LFO. + + + + Click here for random wave. + Klepněte sem pro náhodnou vlnu. + + + + FREQ x 100 + FREKVENCE x 100 + + + + Click here if the frequency of this LFO should be multiplied by 100. + Klepněte sem, pokud má být frekvence LFO vynásobena x100. + + + + multiply LFO-frequency by 100 + vynásobit frekvenci LFO x100 + + + + MODULATE ENV-AMOUNT + MODULOVAT OBÁLKU + + + + Click here to make the envelope-amount controlled by this LFO. + Klepněte sem, pokud má být množství obálky řízeno tímto LFO. + + + + control envelope-amount by this LFO + řízení množství obálky tímto LFO + + + + ms/LFO: + ms/LFO: + + + + Hint + Rada + + + + Drag a sample from somewhere and drop it in this window. + Sampl odněkud přetáhněte a pusťte jej v tomto okně. EqControls + Input gain Zesílení vstupu + Output gain Zesílení výstupu + + Low shelf gain + Zesílení dolního šelfu + + + Peak 1 gain Zesílení špičky 1 + Peak 2 gain Zesílení špičky 2 + Peak 3 gain Zesílení špičky 3 + Peak 4 gain Zesílení špičky 4 + + High Shelf gain + Zesílení horního šelfu + + + HP res Rezonance horní propusti + + Low Shelf res + Rezonance dolního šelfu + + + Peak 1 BW Šířka pásma špičky 1 + Peak 2 BW Šířka pásma špičky 2 + Peak 3 BW Šířka pásma špičky 3 + Peak 4 BW Šířka pásma špičky 4 + + High Shelf res + Rezonance horního šelfu + + + LP res Rezonance dolní propusti + HP freq Frekvence horní propusti + + Low Shelf freq + Frekvence dolního šelfu + + + Peak 1 freq Frekvence špičky 1 + Peak 2 freq Frekvence špičky 2 + Peak 3 freq Frekvence špičky 3 + Peak 4 freq Frekvence špičky 3 + + High shelf freq + Frekvence špičky 4 + + + LP freq Frekvence dolní propusti + HP active Horní propust aktivní + + Low shelf active + Dolní šelf aktivní + + + Peak 1 active Špička 1 aktivní + Peak 2 active Špička 2 aktivní + Peak 3 active Špička 3 aktivní + Peak 4 active Špička 4 aktivní + + High shelf active + Horní šelf aktivní + + + LP active Dolní propust aktivní + LP 12 DP 12 + LP 24 DP 24 + LP 48 DP 48 + HP 12 HP 12 + HP 24 HP 24 + HP 48 HP 48 + + low pass type + typ dolní propusti + + + + high pass type + typ horní propusti + + + Analyse IN Analýza VSTUPU + Analyse OUT Analýza VÝSTUPU - - Low-shelf gain - - - - High-shelf gain - - - - Low-shelf res - - - - High-shelf res - - - - Low-shelf freq - - - - High-shelf freq - - - - Low-shelf active - - - - High-shelf active - - - - Low-pass type - - - - High-pass type - - EqControlsDialog + HP HP + + Low Shelf + Dolní šelf + + + Peak 1 Špička 1 + Peak 2 Špička 2 + Peak 3 Špička 3 + Peak 4 Špička 4 + + High Shelf + Horní šelf + + + LP DP + + In Gain + Zesílení vstupu + + + + + Gain Zesílení + + Out Gain + Zesílení výstupu + + + Bandwidth: Šířka pásma: - Resonance : - Rezonance: - - - Frequency: - Frekvence: - - + Octave oktávy - Low-shelf - + + Resonance : + Rezonance: - High-shelf - + + Frequency: + Frekvence: - Input gain - Zesílení vstupu + + lp grp + dp skup - Output gain - Zesílení výstupu - - - LP group - - - - HP group - + + hp grp + hp skup EqHandle + Reso: Rezon: + BW: ŠPás: + + Freq: Frekv: + + ExportProjectDialog + + + Export project + Exportovat projekt + + + + Output + Výstup + + + + File format: + Formát souboru: + + + + Samplerate: + Vzorkovací frekvence: + + + + 44100 Hz + 44100 Hz + + + + 48000 Hz + 48000 Hz + + + + 88200 Hz + 88200 Hz + + + + 96000 Hz + 96000 Hz + + + + 192000 Hz + 192000 Hz + + + + Depth: + Hloubka: + + + + 16 Bit Integer + 16 bitů celočíselně + + + + 24 Bit Integer + 24 bitů celočíselně + + + + 32 Bit Float + 32 bitů s plovoucí čárkou + + + + Stereo mode: + Režim stereo: + + + + Stereo + Stereo + + + + Joint Stereo + Joint stereo + + + + Mono + Mono + + + + Bitrate: + Datový tok: + + + + 64 KBit/s + 64 kbit/s + + + + 128 KBit/s + 128 kbit/s + + + + 160 KBit/s + 160 kbit/s + + + + 192 KBit/s + 192 kbit/s + + + + 256 KBit/s + 256 kbit/s + + + + 320 KBit/s + 320 kbit/s + + + + Use variable bitrate + Použít proměnlivý datový tok + + + + Quality settings + Nastavení kvality + + + + Interpolation: + Interpolace: + + + + Zero Order Hold + Zero-order hold + + + + Sinc Fastest + Sinc nejrychlejší + + + + Sinc Medium (recommended) + Sinc střední (doporučeno) + + + + Sinc Best (very slow!) + Sinc nejlepší (velmi pomalé!) + + + + Oversampling (use with care!): + Převzorkování (používejte opatrně!): + + + + 1x (None) + 1x (žádné) + + + + 2x + 2x + + + + 4x + 4x + + + + 8x + 8x + + + + Export as loop (remove end silence) + Exportovat jako smyčku (odstranění ticha na konci) + + + + Export between loop markers + Exportovat obsah smyčky + + + + Start + Začít + + + + Cancel + Zrušit + + + + Could not open file + Nemohu otevřít soubor + + + + 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! + Nelze otevřít soubor %1 pro zápis. +Ověřte si prosím, zda máte povolen zápis do souboru a do složky, ve které je umístěn, a zkuste znovu! + + + + Export project to %1 + Exportovat projekt do %1 + + + + Error + Chyba + + + + Error while determining file-encoder device. Please try to choose a different output format. + Chyba při zjišťování souboru enkodéru. Zkuste prosím vybrat jiný výstupní formát. + + + + Rendering: %1% + Renderuji: %1% + + + Compression level: + Úroveň komprese: + + + (fastest) + (nejrychlejší) + + + (default) + (výchozí) + + + (smallest) + (nejmenší) + + + + Expressive + + Selected graph + Zvolený graf + + + A1 + A1 + + + A2 + A2 + + + A3 + A3 + + + W1 smoothing + W1 vyhlazování + + + W2 smoothing + W2 vyhlazování + + + W3 smoothing + W3 vyhlazování + + + PAN1 + PAN1 + + + PAN2 + PAN2 + + + REL TRANS + + + + + Fader + + + + Please enter a new value between %1 and %2: + Vložte prosím novou hodnotu mezi %1 a %2: + + + + FileBrowser + + + Browser + Prohlížeč + + + Search + Hledat + + + Refresh list + Obnovit seznam + + + + FileBrowserTreeWidget + + + Send to active instrument-track + Odeslat do aktivní stopy nástroje + + + + Open in new instrument-track/Song Editor + Otevřít v nové nástrojové stopě / Editoru skladby + + + + Open in new instrument-track/B+B Editor + Otevřít v nové nástrojové stopě / editoru bicich/basů + + + + Loading sample + Načítám vzorek + + + + Please wait, loading sample for preview... + Počkejte prosím, načítám vzorek pro náhled... + + + + Error + Chyba + + + + does not appear to be a valid + nevypadá, že je platný + + + + file + soubor + + + + --- Factory files --- + --- Tovární soubory --- + + + + FileBrowserTreeWidget + FlangerControls + + Delay Samples + Zpoždění vzorků + + + + Lfo Frequency + Frekvence LFO + + + Seconds Sekund + Regen Obnov + Noise Šum + Invert Převrátit - - Delay samples - - - - LFO frequency - - FlangerControlsDialog + DELAY ZPOŽ + + Delay Time: + Délka zpoždění: + + + RATE POMĚR - AMNT - MNOŽ - - - Amount: - Množství: - - - FDBK - FDBK - - - NOISE - ŠUM - - - Invert - Převrátit - - + Period: Perioda: - Delay time: - + + AMNT + MNOŽ - Feedback amount: - + + Amount: + Množství: - White noise amount: - + + FDBK + ZP. VAZ + + + + Feedback Amount: + Velikost zpětné vazby: + + + + NOISE + ŠUM + + + + White Noise Amount: + Množství bílého šumu: + + + + Invert + Převrátit - FreeBoyInstrument + FxLine - Sweep time - Trvání sweepu + + Channel send amount + Množství odeslaného kanálu - Sweep direction - Směr sweepu + + 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. + + Efektový (FX) kanál přijímá vstup z jedné nebo více nástrojových stop. +Ten může být následně směrován do dalších efektových kanálů. LMMS automaticky zabraňuje vzniku nekonečných smyček a nedovoluje provést propojení, které by ke vzniku smyčky mohlo vést. + +Chcete-li směrovat kanál do jiného kanálu, vyberte efektový kanál a klepněte na tlačítko "SEND" v kanálu, který chcete odeslat. Otočný ovladač pod tlačítkem "SEND" určuje množství signálu, které bude do kanálu odesláno. + +Efektové kanály můžete odstranit nebo přesunout v kontextové nabídce, která je dostupná po klepnutí pravým tlačítkem myši na efektový kanál. + - Channel 1 volume - Hlasitost kanálu 1 + + Move &left + Přesunout do&leva - Volume sweep direction - Směr hlasitosti sweepu + + Move &right + Přesun dop&rava - Length of each step in sweep - Délka každého kroku ve sweepu + + Rename &channel + Přejmenovat &kanál - Channel 2 volume - Hlasitost kanálu 2 + + R&emove channel + Př&esunout kanál - Channel 3 volume - Hlasitost kanálu 3 - - - Channel 4 volume - Hlasitost kanálu 4 - - - Channel 1 to SO2 (Left) - Kanál 1 do SO2 (pravý) - - - Channel 2 to SO2 (Left) - Kanál 2 do SO2 (pravý) - - - Channel 3 to SO2 (Left) - Kanál 3 do SO2 (pravý) - - - Channel 4 to SO2 (Left) - Kanál 4 do SO2 (pravý) - - - Channel 1 to SO1 (Right) - Kanál 1 do SO1 (pravý) - - - Channel 2 to SO1 (Right) - Kanál 2 do SO1 (pravý) - - - Channel 3 to SO1 (Right) - Kanál 3 do SO1 (pravý) - - - Channel 4 to SO1 (Right) - Kanál 4 do SO1 (pravý) - - - Treble - Výšky - - - Bass - Basy - - - Shift Register width - Posun šířky registru - - - Sweep rate shift amount - - - - Wave pattern duty cycle - - - - Right output level - - - - Left output level - + + Remove &unused channels + Odstranit nepo&užívané kanály - FreeBoyInstrumentView + FxMixer - Length of each step in sweep: - Délka každého kroku ve sweepu: + + Master + Hlavní - Length of each step in sweep - Délka každého kroku ve sweepu + + + + FX %1 + Efekt %1 - Treble: - Výšky: + + Volume + Hlasitost - Treble - Výšky + + Mute + Ztlumit - Bass: - Basy: + + Solo + Sólo + + + + FxMixerView + + + FX-Mixer + Efektový mixážní panel - Bass - Basy + + FX Fader %1 + Efektový fader %1 - Sweep time: - + + Mute + Ztlumit - Sweep time - Trvání sweepu + + Mute this FX channel + Ztlumit tento efektový kanál - Sweep rate shift amount: - + + Solo + Sólo - Sweep rate shift amount - + + Solo FX channel + Sólovat efektový kanál + + + FxRoute - Wave pattern duty cycle: - - - - Wave pattern duty cycle - - - - Square channel 1 volume: - - - - Square channel 1 volume - - - - Square channel 2 volume: - - - - Square channel 2 volume - - - - Wave pattern channel volume: - - - - Wave pattern channel volume - - - - Noise channel volume: - - - - Noise channel volume - - - - SO1 volume (Right): - - - - SO1 volume (Right) - - - - SO2 volume (Left): - - - - SO2 volume (Left) - - - - Sweep direction - Směr sweepu - - - Volume sweep direction - Směr hlasitosti sweepu - - - Shift register width - - - - Channel 1 to SO1 (Right) - Kanál 1 do SO1 (pravý) - - - Channel 2 to SO1 (Right) - Kanál 2 do SO1 (pravý) - - - Channel 3 to SO1 (Right) - Kanál 3 do SO1 (pravý) - - - Channel 4 to SO1 (Right) - Kanál 4 do SO1 (pravý) - - - Channel 1 to SO2 (Left) - Kanál 1 do SO2 (pravý) - - - Channel 2 to SO2 (Left) - Kanál 2 do SO2 (pravý) - - - Channel 3 to SO2 (Left) - Kanál 3 do SO2 (pravý) - - - Channel 4 to SO2 (Left) - Kanál 4 do SO2 (pravý) - - - Wave pattern graph - + + + Amount to send from channel %1 to channel %2 + Množství k odeslání z kanálu %1 do kanálu %2 GigInstrument + Bank Banka + Patch Patch + Gain Zisk @@ -1194,1125 +2977,3777 @@ GigInstrumentView + + Open other GIG file + Otevřít jiný GIG soubor + + + + Click here to open another GIG file + Klepněte sem pro otevření jiného GIG souboru + + + + Choose the patch + Vybrat patch + + + + Click here to change which patch of the GIG file to use + Klepněte sem pro změnu patche GIG souboru + + + + + Change which instrument of the GIG file is being played + Změnit přehrávaný nástroj GIG souboru + + + + Which GIG file is currently being used + Který GIG soubor je právě používán + + + + Which patch of the GIG file is currently being used + Který patch GIG souboru je právě používán + + + + Gain + Zesílení + + + + Factor to multiply samples by + Vynásobit vzorky x + + + Open GIG file Otevřít GIG soubor + GIG Files (*.gig) GIG soubory (*.gig) + + + GuiApplication - Choose patch - + + Working directory + Pracovní adresář - Gain: - + + The LMMS working directory %1 does not exist. Create it now? You can change the directory later via Edit -> Settings. + Pracovní adresář LMMS %1 neexistuje. Chcete jej nyní vytvořit? Změnu adresáře mžete provést později v nabídce Úpravy -> Nastavení. + + + + Preparing UI + Připravuji UI + + + + Preparing song editor + Připravuji editor skladby + + + + Preparing mixer + Připravuji mixážní panel + + + + Preparing controller rack + Připravuji panel ovladačů + + + + Preparing project notes + Připravuji poznámky k projektu + + + + Preparing beat/bassline editor + Připravuji editor bicích/basů + + + + Preparing piano roll + Připravuji Piano roll + + + + Preparing automation editor + Připravuji Editor automatizace + + + + InstrumentFunctionArpeggio + + + Arpeggio + Arpeggio + + + + Arpeggio type + Typ arpeggia + + + + Arpeggio range + Rozsah arpeggia + + + + Cycle steps + Počet kroků v cyklu + + + + Skip rate + Míra vynechávání + + + + Miss rate + Míra míjení + + + + Arpeggio time + Trvání arpeggia + + + + Arpeggio gate + Brána arpeggia + + + + Arpeggio direction + Směr arpeggia + + + + Arpeggio mode + Styl arpeggia + + + + Up + Nahoru + + + + Down + Dolů + + + + Up and down + Nahoru a dolů + + + + Down and up + Dolů a nahoru + + + + Random + Náhodné + + + + Free + Volné + + + + Sort + Tříděné + + + + Sync + Synchronizované + + + + 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. + Arpeggio je způsob hry (zejména na drnkací nástroje), který činí hudbu mnohem živější. Struny těchto nástrojů (např. harfy) jsou rozezněny jako v akordech. Jediným rozdílem je, že se tak stane sekvenčně, takže tóny nejsou zahrány ve stejnou dobu. Typickým arpeggiem jsou durové a mollové trojzvuky, ale možných dalších akordů, které si můžete vybrat, je spousta. + + + + RANGE + ROZSAH + + + + Arpeggio range: + Rozsah arpeggia: + + + + octave(s) + oktáva(y) + + + + Use this knob for setting the arpeggio range in octaves. The selected arpeggio will be played within specified number of octaves. + Tento otočný ovladač použijte pro nastavení rozsahu arpeggia v oktávách. Vybrané arpeggio bude zahráno ve zvoleném počtu oktáv. + + + + CYCLE + CYKL + + + + Cycle notes: + Počet not v cyklu: + + + + note(s) + nota(y) + + + + 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. + Skočí přes n kroků v arpeggiu a pokud přesáhne rozsah not, zacyklí se zde. Je-li je celkový rozsah not rovnoměrně dělitelný počtem kroků nad rozdah, uvíznete v kratším arpeggiu nebo dokonce na jedné notě. + + + + SKIP + VYNECH + + + + Skip rate: + Míra vynechávání: + + + + + + % + % + + + + 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. + Funkce vynechávání způsobí, že arpeggiator náhodně pozastaví některý krok. Od počáteční pozice, kde nemá žádný efekt, se po směru hodinových ručiček efekt stupňuje až po maximální nastavení, kdy vynechá vše. + + + + MISS + MÍJ + + + + Miss rate: + Míra míjení: + + + + The miss function will make the arpeggiator miss the intended note. + Funkce míjení způsobí, že arpeggiator netrefí dotyčnou notu. + + + + TIME + TRVÁNÍ + + + + Arpeggio time: + Trvání arpeggia: + + + + ms + ms + + + + Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. + Tento otočný ovladač nastavuje trvání arpeggia v milisekundách. Trvání arpeggia udává, jak dlouho bude každý tón arpeggia přehráván. + + + + GATE + BRÁNA + + + + Arpeggio gate: + Brána arpeggia: + + + + 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. + Tento otočný ovladač nastavuje bránu arpeggia. Brána arpeggia určuje procento délky jednotlivých arpeggiových tónů, které budou zahrány. Pomocí brány arpeggia můžete udělat skvělé staccatové arpeggio. + + + + Chord: + Akord: + + + + Direction: + Směr: + + + + Mode: + Styl: + + + + InstrumentFunctionNoteStacking + + + octave + Oktáva + + + + + Major + Dur + + + + Majb5 + Maj5b + + + + minor + Moll + + + + minb5 + m5b + + + + sus2 + sus2 + + + + sus4 + sus4 + + + + aug + aug + + + + augsus4 + aug sus4 + + + + tri + tri + + + + 6 + 6 + + + + 6sus4 + 6 sus4 + + + + 6add9 + 6 add9 + + + + m6 + m6 + + + + m6add9 + m6 add9 + + + + 7 + 7 + + + + 7sus4 + 7 sus4 + + + + 7#5 + 7/5# + + + + 7b5 + 7/5b + + + + 7#9 + 7/9# + + + + 7b9 + 7/9b + + + + 7#5#9 + 7/5#/9# + + + + 7#5b9 + 7/5#/9b + + + + 7b5b9 + 7/5b/9b + + + + 7add11 + 7 add11 + + + + 7add13 + 7 add13 + + + + 7#11 + 7/11# + + + + Maj7 + Maj7 + + + + Maj7b5 + Maj7/5b + + + + Maj7#5 + Maj7/5# + + + + Maj7#11 + Maj7/11# + + + + Maj7add13 + Maj7 add13 + + + + m7 + m7 + + + + m7b5 + m7/5b + + + + m7b9 + m7/9b + + + + m7add11 + m7 add11 + + + + m7add13 + m7 add13 + + + + m-Maj7 + m-Maj7 + + + + m-Maj7add11 + m-Maj7 add11 + + + + m-Maj7add13 + m-Maj7 add13 + + + + 9 + 9 + + + + 9sus4 + 9 sus4 + + + + add9 + add9 + + + + 9#5 + 9/5# + + + + 9b5 + 9/5b + + + + 9#11 + 9/11# + + + + 9b13 + 9/13b + + + + Maj9 + Maj9 + + + + Maj9sus4 + Maj9 sus4 + + + + Maj9#5 + Maj9/5# + + + + Maj9#11 + Maj9/11# + + + + m9 + m9 + + + + madd9 + m add9 + + + + m9b5 + m9/5b + + + + m9-Maj7 + m9-Maj7 + + + + 11 + 11 + + + + 11b9 + 11/9b + + + + Maj11 + Maj11 + + + + m11 + m11 + + + + m-Maj11 + m-Maj11 + + + + 13 + 13 + + + + 13#9 + 13/9# + + + + 13b9 + 13/9b + + + + 13b5b9 + 13/9b/5b + + + + Maj13 + Maj13 + + + + m13 + m13 + + + + m-Maj13 + m-Maj13 + + + + Harmonic minor + Mollová harmonická + + + + Melodic minor + Mollová melodická + + + + Whole tone + Celotónová stupnice + + + + Diminished + Zmenšená + + + + Major pentatonic + Durová pentatonika + + + + Minor pentatonic + Mollová pentatonika + + + + Jap in sen + Japonská (in sen) stupnice + + + + Major bebop + Durová bebopová + + + + Dominant bebop + Dominantní bebopová + + + + Blues + Bluesová stupnice + + + + Arabic + Arabská + + + + Enigmatic + Enigmatická + + + + Neopolitan + Neapolská + + + + Neopolitan minor + Mollová neapolská + + + + Hungarian minor + Mollová maďarská + + + + Dorian + Dórská + + + + Phrygian + Frygický + + + + Lydian + Lydická + + + + Mixolydian + Mixolydická + + + + Aeolian + Aiolská + + + + Locrian + Lokrická + + + + Minor + Moll + + + + Chromatic + Chromatická + + + + Half-Whole Diminished + Zmenšená (půltón–celý tón) + + + + 5 + 5 + + + + Phrygian dominant + Frygická dominanta + + + + Persian + Perská + + + + Chords + Akordy + + + + Chord type + Typ akordu + + + + Chord range + Rozsah akordu + + + + InstrumentFunctionNoteStackingView + + + STACKING + VRSTVENÍ + + + + Chord: + Akord: + + + + RANGE + ROZSAH + + + + Chord range: + Rozsah akordu: + + + + octave(s) + oktáva(y) + + + + Use this knob for setting the chord range in octaves. The selected chord will be played within specified number of octaves. + Tento otočný ovladač nastavuje rozsah akordů v oktávách. Vybraný akord bude zahrán ve zvoleném počtu oktáv. + + + + InstrumentMidiIOView + + + ENABLE MIDI INPUT + POVOLIT MIDI VSTUP + + + + + CHANNEL + KANÁL + + + + + VELOCITY + DYNAM + + + + ENABLE MIDI OUTPUT + POVOLIT MIDI VÝSTUP + + + + PROGRAM + PROGRAM + + + + NOTE + NOTA + + + + MIDI devices to receive MIDI events from + MIDI zařízení pro přijímání MIDI událostí + + + + MIDI devices to send MIDI events to + MIDI zařízení pro odesílání MIDI událostí + + + + CUSTOM BASE VELOCITY + VLASTNÍ VÝCHOZÍ DYNAMIKA + + + + Specify the velocity normalization base for MIDI-based instruments at 100% note velocity + Udává výchozí úroveň dynamiky pro MIDI nástroje při 100 % dynamiky tónu + + + + BASE VELOCITY + VÝCHOZÍ DYNAMIKA + + + + InstrumentMiscView + + + MASTER PITCH + TRANSPOZICE + + + + Enables the use of Master Pitch + Umožní použití transpozice + + + + InstrumentSoundShaping + + + VOLUME + HLASITOST + + + + Volume + Hlasitost + + + + CUTOFF + SEŘÍZNUTÍ + + + + + Cutoff frequency + Frekvence oříznutí + + + + RESO + REZONANCE + + + + Resonance + Rezonance + + + + Envelopes/LFOs + Obálky/LFO + + + + Filter type + Typ filtru + + + + Q/Resonance + Q/rezonance + + + + LowPass + Dolní propust + + + + HiPass + Horní propust + + + + BandPass csg + Pásmová propust csg + + + + BandPass czpg + Pásmová propust czpg + + + + Notch + Pásmová zádrž + + + + Allpass + Všepásmový filtr + + + + Moog + Moogův filtr + + + + 2x LowPass + 2x dolní propust + + + + RC LowPass 12dB + RC dolní propust 12dB + + + + RC BandPass 12dB + RC pásmová propust 12dB + + + + RC HighPass 12dB + RC horní propust 12dB + + + + RC LowPass 24dB + RC dolní propust 24dB + + + + RC BandPass 24dB + RC pásmová propust 24dB + + + + RC HighPass 24dB + RC horní propust 24dB + + + + Vocal Formant Filter + Vokální formantový filtr + + + + 2x Moog + 2x Moogův filtr + + + + SV LowPass + SV dolní propust + + + + SV BandPass + SV pásmová propust + + + + SV HighPass + SV horní propust + + + + SV Notch + SV pásmová zádrž + + + + Fast Formant + Rychlý formantový filtr + + + + Tripole + Třípólový filtr + + + + InstrumentSoundShapingView + + + TARGET + CÍL: + + + + 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...! + Tato stránka obsahuje obálky. Ty jsou velmi důležité pro úpravu zvuku a obvykle také i nezbytné pro rozdílovou (subtraktivní) syntézu. Pokud máte například obálku hlasitosti, můžete nastavit, kdy má mít zvuk jakou sílu. Pokud chcete vytvořit něco jako smyčce, váš zvuk by měl mít velmi měkké nasazení i ukončení tónu. Toho dosáhneme nastavením dlouhého času náběhu i uvolnění. Totéž se týká ostatních druhů obálek, jako je obálka panorámatu, frekvence odříznutí pro použití u filtrů apod. Prostě si s tím můžete vyhrát dle libosti! Můžete vytvořit opravdu úžasné zvuky třeba jen z pilovité vlny pomocí vhodných obálek...! + + + + FILTER + FILTR + + + + 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. + Zde si můžete vybrat z vestavěných filtrů, které chcete použít pro tuto stopu nástroje. Filtry jsou velmi důležité pro změnu charakteristiky zvuku. + + + + FREQ + FREKV + + + + cutoff frequency: + Frekvence oříznutí: + + + + 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... + Tento otočný ovladač nastavuje frekvenci odříznutí pro vybraný filtr. Frekvence odříznutí určuje frekvenci pro odříznutí signálu filtrem. Například filtr typu dolní propust (low-pass) odstřihne všechny frekvence, které jsou vyšší než frekvence odříznutí. Filtr typu horní propust (high-pass) odstřihne všechny frekvence, které jsou nižší než frekvence odříznutí atd... + + + + RESO + REZO + + + + Resonance: + Rezonance: + + + + 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. + Tento otočný ovladač nastavuje Q/rezonanci pro vybraný filtr. Q/rezonance určuje, jak hodně filtr zesílí frekvence poblíž frekvence oříznutí. + + + + Envelopes, LFOs and filters are not supported by the current instrument. + Obálky, LFO a filtry nejsou podporovány stávajícím nástrojem. InstrumentTrack + + With this knob you can set the volume of the opened channel. + Tímto otočným ovladačem můžete nastavit hlasitost otevřeného kanálu. + + + + + unnamed_track + nepojmenovaná_stopa + + + + Base note + Základní nota + + + + Volume + Hlasitost + + + + Panning + Panoráma + + + + Pitch + Ladění + + + + Pitch range + Výškový rozsah + + + + FX channel + Efektový kanál + + + + Master Pitch + Transpozice + + + + Default preset Výchozí předvolba + + InstrumentTrackView + + + Volume + Hlasitost + + + + Volume: + Hlasitost: + + + + VOL + HLA + + + + Panning + Panoráma + + + + Panning: + Panoráma: + + + + PAN + PAN + + + + MIDI + MIDI + + + + Input + Vstup + + + + Output + Výstup + + + + FX %1: %2 + Efekt %1: %2 + + + + InstrumentTrackWindow + + + GENERAL SETTINGS + HLAVNÍ NASTAVENÍ + + + + Use these controls to view and edit the next/previous track in the song editor. + Použije tyto ovládací prvky pro zobrazení a editaci další/předchozí stopy v editoru skladby. + + + + Instrument volume + Hlasitost nástroje + + + + Volume: + Hlasitost: + + + + VOL + HLA + + + + Panning + Panoráma + + + + Panning: + Panoráma: + + + + PAN + PAN + + + + Pitch + Ladění + + + + Pitch: + Ladění: + + + + cents + centů + + + + PITCH + LADĚNÍ + + + + Pitch range (semitones) + Rozsah výšky (v půltónech) + + + + RANGE + ROZSAH + + + + FX channel + Efektový kanál + + + + FX + EFEKT + + + + Save current instrument track settings in a preset file + Uložit aktuální nastavení nástrojové stopy do souboru předvoleb + + + + 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. + Klepněte sem, chcete-li uložit aktuální nastavení nástrojové stopy do souboru předvoleb. Později můžete nahrát tuto předvolbu poklepáním na prohlížeč předvoleb. + + + + SAVE + ULOŽIT + + + + Envelope, filter & LFO + Obálka, filtr a LFO + + + + Chord stacking & arpeggio + Vrstvení akordů a arpeggio + + + + Effects + Efekty + + + + MIDI settings + MIDI nastavení + + + + Miscellaneous + Různé + + + + Save preset + Uložit předvolbu + + + + XML preset file (*.xpf) + XML soubor předvoleb (*.xpf) + + + + Plugin + Plugin + + + + Knob + + + Set linear + Lineární zobrazení + + + + Set logarithmic + Logaritmické zobrazení + + + + Please enter a new value between -96.0 dBFS and 6.0 dBFS: + Zadejte prosím novou hodnotu mezi -96.0 dBFS a 6.0 dBFS: + + + + Please enter a new value between %1 and %2: + Vložte prosím novou hodnotu mezi %1 a %2: + + + + LadspaControl + + + Link channels + Propojit kanály + + LadspaControlDialog + Link Channels Propojit kanály + Channel Kanál + + LadspaControlView + + + Link channels + Propojit kanály + + + + Value: + Hodnota: + + + + Sorry, no help available. + Promiňte, nápověda není k dispozici. + + LadspaEffect + Unknown LADSPA plugin %1 requested. Je požadován neznámý LADSPA plugin %1. + + LcdSpinBox + + + Please enter a new value between %1 and %2: + Vložte prosím novou hodnotu mezi %1 a %2: + + + + LeftRightNav + + + + + Previous + Předchozí + + + + + + Next + Další + + + + Previous (%1) + Předchozí (%1) + + + + Next (%1) + Další (%1) + + + + LfoController + + + LFO Controller + Ovladač LFO + + + + Base value + Základní hodnota + + + + Oscillator speed + Rychlost oscilátoru + + + + Oscillator amount + Míra oscilátoru + + + + Oscillator phase + Fáze oscilátoru + + + + Oscillator waveform + Vlna oscilátoru + + + + Frequency Multiplier + Frekvenční multiplikátor + + + + LfoControllerDialog + + + LFO + LFO + + + + LFO Controller + Ovladač LFO + + + + BASE + ZÁKL + + + + Base amount: + Základní míra: + + + + todo + udělat + + + + SPD + RYCH + + + + LFO-speed: + Rychlost LFO: + + + + Use this knob for setting speed of the LFO. The bigger this value the faster the LFO oscillates and the faster the effect. + Tento otočný ovladač nastavuje rychlost LFO. Zvýšením hodnoty se zrychlí kmitání LFO a průběh efektu. + + + + AMNT + MNOŽ + + + + Modulation amount: + Hloubka modulace: + + + + 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. + Tento otočný ovladač nastavuje množství modulace LFO. Čím vyšší bude tato hodnota, tím více budou propojené parametry (např. hlasitost nebo frekvence odříznutí) ovlivněny LFO. + + + + PHS + FÁZ + + + + Phase offset: + Posun fáze: + + + + degrees + stupňů + + + + 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. + Tímto otočným ovladačem můžete nastavit fázový posun LFO. To znamená, že můžete posunout bod, ve kterém oscilátor začne kmitat. Například pokud máte sinusovou vlnu s fázovým posunem 180 stupňů, vlna půjde nejdříve dolů. Totéž se stane u vlny pravoúhlé. + + + + Click here for a sine-wave. + Klepněte sem pro sinusovou vlnu. + + + + Click here for a triangle-wave. + Klepněte sem pro trojúhelníkovou vlnu. + + + + Click here for a saw-wave. + Klepněte sem pro pilovitou vlnu. + + + + Click here for a square-wave. + Klepněte sem pro pravoúhlou vlnu. + + + + Click here for a moog saw-wave. + Klepněte sem pro pilovitou vlnu typu Moog. + + + + Click here for an exponential wave. + Klepněte sem pro exponenciální vlnu. + + + + Click here for white-noise. + Klepněte sem pro bílý šum. + + + + Click here for a user-defined shape. +Double click to pick a file. + Klepněte sem pro uživatelem definovaný tvar. +Poklepejte pro výběr souboru. + + + + LmmsCore + + + Generating wavetables + Generuji vlny + + + + Initializing data structures + Inicializuji datové struktury + + + + Opening audio and midi devices + Spouštím zvuková a MIDI zařízení + + + + Launching mixer threads + Spouštím vlákna mixážního panelu + + + + MainWindow + + + Configuration file + Soubor nastavení + + + + Error while parsing configuration file at line %1:%2: %3 + Chyba při kontrole konfiguračního souboru na řádku %1:%2: %3 + + + + Could not open file + Nemohu otevřít soubor + + + + 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! + Nelze otevřít soubor %1 pro zápis. +Ujistěte se prosím, zda máte povolen zápis do souboru a do složky obsahující soubor a zkuste znovu! + + + + Project recovery + Obnovení projektu + + + + 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? + Je k dispozici soubor pro obnovu. Zdá se, že poslední práce nebyla správně ukončena nebo že je již spuštěna jiná instance LMMS. Chcete obnovit tuto verzi projektu? + + + + + + Recover + Obnovit + + + + Recover the file. Please don't run multiple instances of LMMS when you do this. + Obnovit soubor. Před dokončením prosím nespouštějte další instance LMMS. + + + + + + Discard + Zrušit + + + + Launch a default session and delete the restored files. This is not reversible. + Spustit LMMS do výchozího stavu a smazat obnovené soubory. Tento krok je nevratný. + + + + Version %1 + Verze %1 + + + + Preparing plugin browser + Připravuji prohlížeč pluginů + + + + Preparing file browsers + Připravuji prohlížeč souborů + + + + My Projects + Moje projekty + + + + My Samples + Moje samply + + + + My Presets + Moje předvolby + + + + My Home + Domů + + + + Root directory + Kořenový adresář + + + + Volumes + Hlasitosti + + + + My Computer + Můj počítač + + + + Loading background artwork + Načítám grafiku prostředí + + + + &File + &Soubor + + + + &New + &Nový + + + + New from template + Nový z šablony + + + + &Open... + &Otevřít... + + + + &Recently Opened Projects + &Naposledy otevřené projekty + + + + &Save + &Uložit + + + + Save &As... + Uložit &jako... + + + + Save as New &Version + Uložit jako novou &verzi + + + + Save as default template + Uložit jako výchozí šablonu + + + + Import... + Importovat... + + + + E&xport... + E&xportovat... + + + + E&xport Tracks... + E&xportovat stopy... + + + + Export &MIDI... + &Exportovat MIDI... + + + + &Quit + &Ukončit + + + + &Edit + Úpr&avy + + + + Undo + Zpět + + + + Redo + Znovu + + + + Settings + Nastavení + + + + &View + &Zobrazení + + + + &Tools + &Nástroje + + + + &Help + &Nápověda + + + + Online Help + Nápověda online + + + + Help + Nápověda + + + + What's This? + Co je to? + + + + About + O LMMS + + + + Create new project + Vytvořit nový projekt + + + + Create new project from template + Vytvořit nový projekt ze šablony + + + + Open existing project + Otevřít existující projekt + + + + Recently opened projects + Naposledy otevřené projekty + + + + Save current project + Uložit aktuální projekt + + + + Export current project + Exportovat aktuální projekt + + + + What's this? + Co je to? + + + + Toggle metronome + Zapnout/Vypnout metronom + + + + Show/hide Song-Editor + Zobrazit/Skrýt editor skladby + + + + 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. + Stisknutím tohoto tlačítka zobrazíte nebo skryjete Editor skladby. S jeho pomocí můžete upravovat playlist skladby a určit, kdy a která stopa má být přehrána. Můžete také vkládat a přesunovat samply (např. rapové) přímo do playlistu. + + + + Show/hide Beat+Bassline Editor + Zobrazit/Skrýt editor bicích/basů + + + + 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. + Stisknutím tohoto tlačítka zobrazíte nebo skryjete editor bicích/basů. Tento editor je nezbytný pro tvorbu beatů, otevírání, přidávání či odebírání kanálů a dále pro vyjímání, kopírování a vkládání beatů, bicích/basových záznamů apod. + + + + Show/hide Piano-Roll + Zobrazit/Skrýt Piano roll + + + + Click here to show or hide the Piano-Roll. With the help of the Piano-Roll you can edit melodies in an easy way. + Klepněte sem, pokud chcete ukázat nebo skrýt Piano roll. S pomocí Piano rollu můžete jednoduchým způsobem upravovat melodie. + + + + Show/hide Automation Editor + Zobrazit/Skrýt Editor automatizace + + + + 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. + Klepněte sem, pokud chcete ukázat nebo skrýt Editor automatizace. S pomocí Editoru automatizace můžete jednoduchým způsobem upravovat proměnlivý průběh hodnot. + + + + Show/hide FX Mixer + Zobrazit/Skrýt efektový mixážní panel + + + + 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. + Klepněte sem, pokud chcete ukázat nebo skrýt efektový (FX) mixážní panel. Efektový mixážní panel je velmi výkonný nástroj pro správu efektů ve vaší skladbě. Efekty můžete vkládat do různých efektových kanálů. + + + + Show/hide project notes + Zobrazit/Skrýt poznámky k projektu + + + + Click here to show or hide the project notes window. In this window you can put down your project notes. + Klepněte sem, pokud chcete ukázat nebo schovat okno pro poznámky. V tomto okně lze vkládat vaše poznámky k projektu. + + + + Show/hide controller rack + Zobrazit/Skrýt panel ovladačů + + + + Untitled + Nepojmenovaný + + + + Recover session. Please save your work! + Obnovit projekt. Uložte prosím svou práci! + + + + LMMS %1 + LMMS %1 + + + + Recovered project not saved + Obnovený projekt není uložen + + + + 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? + Tento projekt byl obnoven z minulého spuštění LMMS. Zatím není uložen a pokud tak neučiníte, práce bude ztracena. Chcete jej nyní uložit? + + + + Project not saved + Projekt není uložen + + + + The current project was modified since last saving. Do you want to save it now? + Aktuální projekt byl od posledního uložení změněn. Chcete jej nyní uložit? + + + + Open Project + Otevřít projekt + + + + LMMS (*.mmp *.mmpz) + LMMS (*.mmp *.mmpz) + + + + Save Project + Uložit projekt + + + + LMMS Project + Projekt LMMS + + + + LMMS Project Template + Šablona projektu LMMS + + + + Save project template + Uložit šablonu projektu + + + + Overwrite default template? + Přepsat výchozí šablonu? + + + + This will overwrite your current default template. + Tímto se přepíše vaše nynější výchozí šablona. + + + + Help not available + Nápověda není dostupná + + + + Currently there's no help available in LMMS. +Please visit http://lmms.sf.net/wiki for documentation on LMMS. + V současnosti není v LMMS nápověda dostupná. +Navštivte prosím stránku s dokumentací k LMMS na adrese http://lmms.sf.net/wiki. + + + + Song Editor + Editor skladby + + + + Beat+Bassline Editor + Editor bicích/basů + + + + Piano Roll + Piano roll + + + + Automation Editor + Editor automatizace + + + + FX Mixer + Efektový mixážní panel + + + + Project Notes + Poznámky k projektu + + + + Controller Rack + Panel ovladačů + + + + Volume as dBFS + Hlasitost v dBFS + + + + Smooth scroll + Plynulé posouvání + + + + Enable note labels in piano roll + Povolit názvy tónů v Piano rollu + + + + MeterDialog + + + + Meter Numerator + Počet dob v taktu + + + + + Meter Denominator + Délka doby v taktu + + + + TIME SIG + METRUM + + + + MeterModel + + + Numerator + Počet dob + + + + Denominator + Délka doby + + + + MidiController + + + MIDI Controller + MIDI ovladač + + + + unnamed_midi_controller + nepojmenovaný_midi_ovladač + + MidiImport + + Setup incomplete Nastavení není dokončeno + + 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. + Nemáte nastaven výchozí soundfont v dialogovém okně (Edit-> Nastavení). Z tohoto důvodu nebude po importu MIDI souboru přehráván žádný zvuk. Stáhněte si nějaký General MIDI soundfont, zadejte jej v dialogovém okně nastavení a zkuste to znovu. + + + 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. Nelze zkompilovat LMMS s podporou přehrávače SoundFont2, který je použitý k přidání výchozího zvuku do importovaných MIDI souborů. Proto nebude po importování tohoto MIDI souboru přehráván žádný zvuk. + Track Stopa + + + MidiJack - You have not 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. - + + JACK server down + When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (title) + JACK server zhavaroval + + + + The JACK server seems to be shuted down. + When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (dialog message) + Zdá se, že JACK server zhavaroval. + + + + MidiPort + + + Input channel + Vstupní kanál + + + + Output channel + Výstupní kanál + + + + Input controller + Vstupní ovladač + + + + Output controller + Výstupní ovladač + + + + Fixed input velocity + Pevná vstupní dynamika + + + + Fixed output velocity + Pevná výstupní dynamika + + + + Fixed output note + Pevná výstupní nota + + + + Output MIDI program + Výstupní MIDI program + + + + Base velocity + Výchozí dynamika + + + + Receive MIDI-events + Přijímat MIDI události + + + + Send MIDI-events + Posílat MIDI události + + + + MidiSetupWidget + + + DEVICE + ZAŘÍZENÍ MonstroInstrument + + Osc 1 Volume + Osc 1 hlasitost + + + + Osc 1 Panning + Osc 1 panoráma + + + + Osc 1 Coarse detune + Osc 1 hrubé rozladění + + + + Osc 1 Fine detune left + Osc 1 jemné rozladění vlevo + + + + Osc 1 Fine detune right + Osc 1 jemné rozladění vpravo + + + + Osc 1 Stereo phase offset + Osc 1 posun stereo fáze + + + + Osc 1 Pulse width + Osc 1 délka pulzu + + + + Osc 1 Sync send on rise + Osc 1 synchronizace při nárůstu + + + + Osc 1 Sync send on fall + Osc 1 synchronizace při poklesu + + + + Osc 2 Volume + Osc 2 hlasitost + + + + Osc 2 Panning + Osc 2 panoráma + + + + Osc 2 Coarse detune + Osc 2 hrubé rozladění + + + + Osc 2 Fine detune left + Osc 2 jemné rozladění vlevo + + + + Osc 2 Fine detune right + Osc 2 jemné rozladění vpravo + + + + Osc 2 Stereo phase offset + Osc 2 posun stereo fáze + + + + Osc 2 Waveform + Osc 2 vlna + + + + Osc 2 Sync Hard + Osc 2 pevná synchronizace + + + + Osc 2 Sync Reverse + Osc 2 reverzní synchronizace + + + + Osc 3 Volume + Osc 3 hlasitost + + + + Osc 3 Panning + Osc 3 panoráma + + + + Osc 3 Coarse detune + Osc 3 hrubé rozladění + + + Osc 3 Stereo phase offset Osc 3 posun stereo fáze + + Osc 3 Sub-oscillator mix + Osc 3 smíchání se sub-oscilátorem + + + + Osc 3 Waveform 1 + Osc 3 vlna 1 + + + + Osc 3 Waveform 2 + Osc 3 vlna 2 + + + + Osc 3 Sync Hard + Osc 3 pevná synchronizace + + + + Osc 3 Sync Reverse + Osc 3 reverzní synchronizace + + + + LFO 1 Waveform + LFO 1 vlna + + + + LFO 1 Attack + LFO 1 náběh + + + + LFO 1 Rate + LFO 1 rychlost + + + + LFO 1 Phase + LFO 1 fáze + + + + LFO 2 Waveform + LFO 2 vlna + + + + LFO 2 Attack + LFO 2 náběh + + + + LFO 2 Rate + LFO 2 rychlost + + + + LFO 2 Phase + LFO 2 fáze + + + + Env 1 Pre-delay + Obálka 1 předzpoždění + + + + Env 1 Attack + Obálka 1 náběh + + + + Env 1 Hold + Obálka 1 držení + + + + Env 1 Decay + Obálka 1 útlum + + + + Env 1 Sustain + Obálka 1 vydržení + + + + Env 1 Release + Obálka 1 uvolnění + + + + Env 1 Slope + Obálka 1 sklon + + + + Env 2 Pre-delay + Obálka 2 předzpoždění + + + + Env 2 Attack + Obálka 2 náběh + + + + Env 2 Hold + Obálka 2 držení + + + + Env 2 Decay + Obálka 2 útlum + + + + Env 2 Sustain + Obálka 2 vydržení + + + + Env 2 Release + Obálka 2 uvolnění + + + + Env 2 Slope + Obálka 2 sklon + + + + Osc2-3 modulation + Osc 2–3 modulace + + + Selected view Zvolený pohled + + Vol1-Env1 + Hla1-Obá1 + + + + Vol1-Env2 + Hla1-Obá2 + + + + Vol1-LFO1 + Hla1-LFO1 + + + + Vol1-LFO2 + Hla1-LFO2 + + + + Vol2-Env1 + Hla2-Obá1 + + + + Vol2-Env2 + Hla2-Obá2 + + + + Vol2-LFO1 + Hla2-LFO1 + + + + Vol2-LFO2 + Hla2-LFO2 + + + + Vol3-Env1 + Hla3-Obá1 + + + + Vol3-Env2 + Hla3-Obá2 + + + + Vol3-LFO1 + Hla3-LFO1 + + + + Vol3-LFO2 + Hla3-LFO2 + + + + Phs1-Env1 + Fáz1-Obá1 + + + + Phs1-Env2 + Fáz1-Obá2 + + + + Phs1-LFO1 + Fáz1-LFO1 + + + + Phs1-LFO2 + Fáz1-LFO2 + + + + Phs2-Env1 + Fáz2-Obá1 + + + + Phs2-Env2 + Fáz2-Obá2 + + + + Phs2-LFO1 + Fáz2-LFO1 + + + + Phs2-LFO2 + Fáz2-LFO2 + + + + Phs3-Env1 + Fáz3-Obá1 + + + + Phs3-Env2 + Fáz3-Obá2 + + + + Phs3-LFO1 + Fáz3-LFO1 + + + + Phs3-LFO2 + Fáz3-LFO2 + + + + Pit1-Env1 + Výš1-Obá1 + + + + Pit1-Env2 + Výš1-Obá2 + + + + Pit1-LFO1 + Výš1-LFO1 + + + + Pit1-LFO2 + Výš1-LFO2 + + + + Pit2-Env1 + Výš2-Obá1 + + + + Pit2-Env2 + Výš2-Obá2 + + + + Pit2-LFO1 + Výš2-LFO1 + + + + Pit2-LFO2 + Výš2-LFO2 + + + + Pit3-Env1 + Výš3-Obá1 + + + + Pit3-Env2 + Výš3-Obá2 + + + + Pit3-LFO1 + Výš3-LFO1 + + + + Pit3-LFO2 + Výš3-LFO2 + + + + PW1-Env1 + Pul1-Obá1 + + + + PW1-Env2 + Pul1-Obá2 + + + + PW1-LFO1 + Pul1-LFO1 + + + + PW1-LFO2 + Pul1-LFO2 + + + + Sub3-Env1 + Sub3-Obá1 + + + + Sub3-Env2 + Sub3-Obá2 + + + + Sub3-LFO1 + Sub3-LFO1 + + + + Sub3-LFO2 + Sub3-LFO2 + + + + Sine wave Sinusová vlna + Bandlimited Triangle wave Pásmově zúžená trojúhelníková vlna + Bandlimited Saw wave Pásmově zúžená pilovitá vlna + Bandlimited Ramp wave Pásmově zúžená šikmá vlna + Bandlimited Square wave Pásmově zúžená pravoúhlá vlna + Bandlimited Moog saw wave Pásmově zúžená pilovitá vlna typu Moog + + Soft square wave Zaoblená pravoúhlá vlna + Absolute sine wave Absolutní sinusová vlna + + Exponential wave Exponenciální vlna + White noise Bílý šum + Digital Triangle wave Digitální trojúhelníková vlna + Digital Saw wave Digitální pilovitá vlna + Digital Ramp wave Digitální šikmá vlna + Digital Square wave Digitální pravoúhlá vlna + Digital Moog saw wave Digitální pilovitá vlna typu Moog + Triangle wave Trojúhelníková vlna + Saw wave Pilovitá vlna + Ramp wave Šikmá vlna + Square wave Pravoúhlá vlna + Moog saw wave Pilovitá vlna typu Moog + Abs. sine wave Abs. sinusová vlna + Random Náhodná + Random smooth Vyhlazená náhodná - - Osc 1 volume - - - - Osc 1 panning - - - - 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 - - - - Osc 2 panning - - - - 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 - - - - Osc 3 panning - - - - Osc 3 coarse detune - - - - Osc 3 sub-oscillator mix - - - - Osc 3 waveform 1 - - - - Osc 3 waveform 2 - - - - Osc 3 sync hard - - - - Osc 3 Sync reverse - - - - LFO 1 waveform - - - - LFO 1 attack - - - - LFO 1 rate - - - - LFO 1 phase - - - - LFO 2 waveform - - - - LFO 2 attack - - - - LFO 2 rate - - - - LFO 2 phase - - - - Env 1 pre-delay - - - - Env 1 attack - - - - 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 - - - - Osc 2+3 modulation - - - - Osc 1 - Vol env 1 - - - - Osc 1 - Vol env 2 - - - - Osc 1 - Vol LFO 1 - - - - Osc 1 - Vol LFO 2 - - - - Osc 2 - Vol env 1 - - - - Osc 2 - Vol env 2 - - - - Osc 2 - Vol LFO 1 - - - - Osc 2 - Vol LFO 2 - - - - Osc 3 - Vol env 1 - - - - Osc 3 - Vol env 2 - - - - Osc 3 - Vol LFO 1 - - - - Osc 3 - Vol LFO 2 - - - - Osc 1 - Phs env 1 - - - - Osc 1 - Phs env 2 - - - - Osc 1 - Phs LFO 1 - - - - Osc 1 - Phs LFO 2 - - - - Osc 2 - Phs env 1 - - - - Osc 2 - Phs env 2 - - - - Osc 2 - Phs LFO 1 - - - - Osc 2 - Phs LFO 2 - - - - Osc 3 - Phs env 1 - - - - Osc 3 - Phs env 2 - - - - Osc 3 - Phs LFO 1 - - - - Osc 3 - Phs LFO 2 - - - - Osc 1 - Pit env 1 - - - - Osc 1 - Pit env 2 - - - - Osc 1 - Pit LFO 1 - - - - Osc 1 - Pit LFO 2 - - - - Osc 2 - Pit env 1 - - - - Osc 2 - Pit env 2 - - - - Osc 2 - Pit LFO 1 - - - - Osc 2 - Pit LFO 2 - - - - Osc 3 - Pit env 1 - - - - Osc 3 - Pit env 2 - - - - Osc 3 - Pit LFO 1 - - - - Osc 3 - Pit LFO 2 - - - - Osc 1 - PW env 1 - - - - Osc 1 - PW env 2 - - - - Osc 1 - PW LFO 1 - - - - Osc 1 - PW LFO 2 - - - - Osc 3 - Sub env 1 - - - - Osc 3 - Sub env 2 - - - - Osc 3 - Sub LFO 1 - - - - Osc 3 - Sub LFO 2 - - MonstroView + Operators view Zobrazení operátorů + + 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. + Zobrazení operátorů obsahuje všechny operátory. Toto společně zahrnuje jak přímo slyšitelné operátory (oscilátory), tak i neslyšitelné operátory nebo modulátory: generátory nízkých kmitů (LFO) a obálek. + +Otočné ovladače a další ovládací prvky v Zobrazení operátorů mají své vlastní textové popisky, takže můžete získat bližší nápovědu, co který konkrétně dělá. + + + Matrix view Zobrazení matrice + + 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. + Zobrazení matrice obsahuje modulační matrici. Zde můžete nadefinovat modulační vazby mezi různými operátory: každý slyšitelný operátor (oscilátory 1–3) má 3–4 vlastnosti, které mohou být modulovány dalšími modulátory. Použití více modulací spotřebovává více výkonu procesoru. + +Okno je rozděleno na cíle modulace, seskupené podle cílových oscilátorů. Dostupné cíle jsou: hlasitost, výška, fáze, délka pulzu a poměr sub-oscilátoru. Poznámka: některé cíle jsou dostupné pouze pro určitý oscilátor. + +Každý cíl modulace má 4 otočné ovladače, jeden pro každý modulátor. Výchozí stav ovladačů je 0, tedy bez modulace. Otočení ovladače na 1 způsobí, že modulátor bude působit na cíl nejvíce, jak je možno. Otočení na -1 způsobí totéž, ale modulace bude inverzně obrácena. + + + + + Volume Hlasitost + + + Panning Panoráma + + + Coarse detune Hrubé rozladění + + + semitones půltónů + + + Finetune left + Jemné rozladění vlevo + + + + + + cents centů + + + Finetune right + Jemné rozladění vpravo + + + + + Stereo phase offset Posun stereo fáze + + + + + deg stupňů + Pulse width Délka pulzu + Send sync on pulse rise Synchronizace při nárůstu pulzu + Send sync on pulse fall Synchronizace při poklesu pulzu + Hard sync oscillator 2 Pevně synchronizovat oscilátor 2 + Reverse sync oscillator 2 Reverzně synchronizovat oscilátor 2 + Sub-osc mix Míchání sub-osc + Hard sync oscillator 3 Pevně synchronizovat oscilátor 3 + Reverse sync oscillator 3 Reverzně synchronizovat oscilátor 3 + + + + Attack Náběh + + Rate Typ + + Phase Fáze + + Pre-delay Předzpoždění + + Hold Držení + + Decay - Útlum + Pokles + + Sustain - Vydržení + Držení + + Release - Uvolnění + Doznění + + Slope - Stoupání + Strmost + + Mix Osc2 with Osc3 + Smíchat Osc2 a Osc3 + + + + Modulate amplitude of Osc3 with Osc2 + Modulovat amplitudu Osc3 pomocí Osc2 + + + + Modulate frequency of Osc3 with Osc2 + Modulovat frekvenci Osc3 pomocí Osc2 + + + + Modulate phase of Osc3 with Osc2 + Modulovat fázi Osc3 pomocí Osc2 + + + + The CRS knob changes the tuning of oscillator 1 in semitone steps. + Otočný ovladač CRS mění ladění oscilátoru 1 v půltónových krocích. + + + + The CRS knob changes the tuning of oscillator 2 in semitone steps. + Otočný ovladač CRS mění ladění oscilátoru 2 v půltónových krocích. + + + + The CRS knob changes the tuning of oscillator 3 in semitone steps. + Otočný ovladač CRS mění ladění oscilátoru 3 v půltónových krocích. + + + + + + + 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. + FTL a FTR změní jemné ladění oscilátoru pro levý a pravý kanál. To přidává oscilátoru stereo rozladění, které rozšíří stereo obraz a vytvoří dojem prostoru. + + + + + + The SPO knob modifies the difference in phase between left and right channels. Higher difference creates a wider stereo image. + Otočný ovladač SPO upravuje rozdíl ve fázi mezi levým a pravým kanálem. Větší rozdíl vytváří širší stereofonní obraz. + + + + 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. + Otočný ovladač PW řídí šířku pulzu, jinak též pracovní cyklus, oscilátoru 1. Oscilátor 1 je digitální generátor pulzních vln, který nevytváří pásmově omezený výstup, což znamená, že jej sice můžete použít jako zdroj slyšitelného signálu, ale způsobuje aliasing. Můžete jej ale také využít jako neslyšitelný zdroj synchronizačního signálu, který může sloužit k synchronizaci oscilátorů 2 a 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. + Zaslání synchronizačního signálu při nárůstu: je-li zapnuto, bude synchronizační signál zasílán pokaždé, když bude stav oscilátoru 1 změněn na vyšší, např. když se amplituda změní z -1 na 1. Výška, fáze a šířka pulzu oscilátoru 1 mohou mít vliv na časování synchronizace, ale jejich množství zde nemá žádný efekt. Synchronizační signály jsou odesílány nezávisle pro levý a pravý kanál. + + + + 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. + Zaslání synchronizačního signálu při poklesu: je-li zapnuto, bude synchronizační signál zasílán pokaždé, když bude stav oscilátoru 1 změněn na nižší, např. když se amplituda změní z 1 na -1. Výška, fáze a šířka pulzu oscilátoru 1 mohou mít vliv na časování synchronizace, ale jejich množství zde nemá žádný efekt. Synchronizační signály jsou odesílány nezávisle pro levý a pravý kanál. + + + + + Hard sync: Every time the oscillator receives a sync signal from oscillator 1, its phase is reset to 0 + whatever its phase offset is. + Pevná synchronizace: pokaždé, když oscilátor přijme synchronizační signál z oscilátoru 1, jeho fáze bude nastavena na 0, bez ohledu na jeho fázový posun. + + + + + Reverse sync: Every time the oscillator receives a sync signal from oscillator 1, the amplitude of the oscillator gets inverted. + Reverzní synchronizace: pokaždé, když oscilátor přijme synchronizační signál z oscilátoru 1, jeho amplituda bude převrácena. + + + + Choose waveform for oscillator 2. + Vyberte vlnu pro oscilátor 2. + + + + Choose waveform for oscillator 3's first sub-osc. Oscillator 3 can smoothly interpolate between two different waveforms. + Vyberte vlnu pro první suboscilátor oscilátoru 3. Oscilátor 3 může plynule interpolovat mezi dvěma různými vlnovými průběhy. + + + + Choose waveform for oscillator 3's second sub-osc. Oscillator 3 can smoothly interpolate between two different waveforms. + Vyberte vlnu pro druhý suboscilátor oscilátoru 3. Oscilátor 3 může plynule interpolovat mezi dvěma různými vlnovými průběhy. + + + + 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. + Otočný ovladač SUB mění poměr směšování mezi dvěma suboscilátory oscilátoru 3. Každý suboscilátor může být nastaven tak, aby vytvářel jiný vlnový průběh, a oscilátor 3 může plynule interpolovat mezi nimi. Všechny příchozí modulace oscilátoru 3 jsou shodným způsobem aplikovány na oba suboscilátory / vlnové průběhy. + + + + 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. + Kromě vyhrazených modulátorů Monstro umožňuje oscilátor 3 modulovat výstupem oscilátoru 2. + +Režim směšování znamená bez modulace: výstupy oscilátorů se jednoduše smíchají. + + + + 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. + Kromě vyhrazených modulátorů Monstro umožňuje oscilátor 3 modulovat výstupem oscilátoru 2. + +AM znamená amplitudovou modulaci: Amplituda (hlasitost) oscilátoru 3 je modulována oscilátorem 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. + Kromě vyhrazených modulátorů Monstro umožňuje oscilátor 3 modulovat výstupem oscilátoru 2. + +FM znamená frekvenční modulaci: frekvence (výška) oscilátoru 3 je modulována oscilátorem 2. Frekvenční modulace je implementována jako fázová modulace, která poskytuje stabilnější výslednou výšku než "čistá" frekvenční modulace. + + + + 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. + Kromě vyhrazených modulátorů Monstro umožňuje oscilátor 3 modulovat výstupem oscilátoru 2. + +PM znamená fázovou modulaci: fáze oscilátoru 3 je modulována oscilátorem 2. To se liší od frekvenční modulace tím, že fázové změny nejsou kumulativní. + + + + 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... + Vyberte tvar vlny pro LFO 1. +"Náhodná" a "Vyhlazená náhodná" jsou speciální vlny: produkují náhodný výstup, kde rychlost LFO řídí, jak často se mění stav LFO. Vyhlazená verze interpoluje mezi těmito stavy kosinovou interpolací. Tyto náhodné režimy mohou být použity k oživení vašich předvoleb – přidávají něco z analogové nepředvídatelnosti... + + + + 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... + Vyberte tvar vlny pro LFO 2. +"Náhodná" a "Vyhlazená náhodná" jsou speciální vlny: produkují náhodný výstup, kde rychlost LFO řídí, jak často se mění stav LFO. Vyhlazená verze interpoluje mezi těmito stavy kosinovou interpolací. Tyto náhodné režimy mohou být použity k oživení vašich předvoleb – přidávají něco z analogové nepředvídatelnosti... + + + + + Attack causes the LFO to come on gradually from the start of the note. + Náběh způsobí, že LFO najede postupně od začátku noty. + + + + + Rate sets the speed of the LFO, measured in milliseconds per cycle. Can be synced to tempo. + Rate nastavuje rychlost LFO, měřenou v milisekundách za cyklus. Lze synchronizovat s tempem. + + + + + PHS controls the phase offset of the LFO. + PHS řídí fázový posun LFO. + + + + + PRE, or pre-delay, delays the start of the envelope from the start of the note. 0 means no delay. + PRE nebo předzpoždění (PRE, predelay) zpozdí začátek obálky oproti začátku noty. Hodnota 0 znamená bez zpoždění. + + + + + ATT, or attack, controls how fast the envelope ramps up at start, measured in milliseconds. A value of 0 means instant. + NÁB nebo náběh určuje, jak rychle vystoupá začátek obálky do špičky, měřeno v milisekundách. Hodnota 0 znamená okamžitý náběh. + + + + + HOLD controls how long the envelope stays at peak after the attack phase. + Držení určuje, jak dlouho obálka zůstane na špičce po fázi náběhu. + + + + + 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. + ÚTL nebo útlum (DEC, decoy) řídí rychlost poklesu obálky ze špičky do nulové úrovně (měřeno v milisekundách). Aktuální útlum může být kratší, pokud je použito podržení (sustain). + + + + + 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. + POD nebo podržení (SUS, sustain) řídí úroveň podržení v obálce. Fáze útlumu (decoy) nemůže jít pod tuto úroveň, dokud je nota držená. + + + + + 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. + UVO nebo uvolnění určuje, jak dlouhé bude ukončení noty, tedy jak dlouho bude trvat zeslabení ze špičky na nulu. Skutečná délka uvolnění může být kratší v závislosti na tom, ve které fázi je nota ukončena. + + + + + 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. + Otočný ovladač sklon řídí křivku a tvar obálky. Hodnota 0 vytváří přímý nárůst i pokles. Záporné hodnoty vytvářejí křivku, která začíná pomalu, rychle dosáhne špičky a opět pomalu klesá. Pozitivní hodnoty vytvářejí křivku, která začíná a končí rychle a udržuje se v blízkosti špičky. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Modulation amount Hloubka modulace - - Fine tune left - - - - Fine tune right - - - - Mix osc 2 with osc 3 - - - - Modulate amplitude of osc 3 by osc 2 - - - - Modulate frequency of osc 3 by osc 2 - - - - Modulate phase of osc 3 by osc 2 - - MultitapEchoControlDialog + Length Délka + Step length: Délka kroku: + Dry Poměr + + Dry Gain: + Poměr zdrojového zvuku: + + + Stages Úrovně + + Lowpass stages: + Počet úrovní dolní propusti: + + + Swap inputs Přepnout vstupy - Dry gain: - - - - Low-pass stages: - - - - Swap left and right input channels for reflections - + + Swap left and right input channel for reflections + Přepnout levý a pravý vstupní kanál pro odrazy NesInstrument + + Channel 1 Coarse detune + Kanál 1 hrubé rozladění + + + + Channel 1 Volume + Hlasitost kanálu 1 + + + + Channel 1 Envelope length + Kanál 1 délka obálky + + + + Channel 1 Duty cycle + Kanál 1 pracovní cyklus + + + + Channel 1 Sweep amount + Kanál 1 množství sweepu + + + + Channel 1 Sweep rate + Kanál 1rychlost sweepu + + + Channel 2 Coarse detune Kanál 2 hrubé rozladění + Channel 2 Volume Hlasitost kanálu 2 + + Channel 2 Envelope length + Kanál 2 délka obálky + + + + Channel 2 Duty cycle + Kanál 2 pracovní cyklus + + + + Channel 2 Sweep amount + Kanál 2 množství sweepu + + + + Channel 2 Sweep rate + Kanál 2 rychlost sweepu + + + + Channel 3 Coarse detune + Kanál 3 hrubé rozladění + + + + Channel 3 Volume + Hlasitost kanálu 3 + + + + Channel 4 Volume + Hlasitost kanálu 4 + + + + Channel 4 Envelope length + Kanál 4 délka obálky + + + + Channel 4 Noise frequency + Kanál 4 frekvence šumu + + + + Channel 4 Noise frequency sweep + Kanál 4 sweep frekvence šumu + + + Master volume Hlavní hlasitost + Vibrato Vibráto - - Channel 1 coarse detune - - - - Channel 1 volume - Hlasitost kanálu 1 - - - Channel 1 envelope length - - - - Channel 1 duty cycle - - - - Channel 1 sweep amount - - - - Channel 1 sweep rate - - - - Channel 2 envelope length - - - - Channel 2 duty cycle - - - - Channel 2 sweep amount - - - - Channel 2 sweep rate - - - - Channel 3 coarse detune - - - - Channel 3 volume - Hlasitost kanálu 3 - - - Channel 4 volume - Hlasitost kanálu 4 - - - Channel 4 envelope length - - - - Channel 4 noise frequency - - - - Channel 4 noise frequency sweep - - NesInstrumentView + + + + Volume Hlasitost + + + Coarse detune Hrubé rozladění + + + Envelope length Délka obálky + Enable channel 1 Zapnout kanál 1 + Enable envelope 1 Zapnout obálku 1 + Enable envelope 1 loop Zapnout smyčku obálky 1 + Enable sweep 1 Zapnout sweep 1 + + Sweep amount Množství sweepu + + Sweep rate Rychlost sweepu + + 12.5% Duty cycle 12.5% pracovního cyklu + + 25% Duty cycle 25% pracovního cyklu + + 50% Duty cycle 50% pracovního cyklu + + 75% Duty cycle 75% pracovního cyklu + Enable channel 2 Zapnout kanál 2 + Enable envelope 2 Zapnout obálku 2 + Enable envelope 2 loop Zapnout smyčku obálky 2 + Enable sweep 2 Zapnout sweep 2 + Enable channel 3 Zapnout kanál 3 + Noise Frequency Frekvence šumu + Frequency sweep Frekvence sweepu + Enable channel 4 Zapnout kanál 4 + Enable envelope 4 Zapnout obálku 4 + Enable envelope 4 loop Zapnout smyčku obálky 4 + Quantize noise frequency when using note frequency Kvantizovat frekvenci šumu při použití frekvence noty + Use note frequency for noise Použít frekvenci pro šum + Noise mode Typ šumu + + Master Volume + Hlavní hlasitost + + + Vibrato Vibráto - - Master volume - Hlavní hlasitost - - - - OpulenzInstrument - - Patch - Patch - - - Op 1 attack - - - - Op 1 decay - - - - Op 1 sustain - - - - Op 1 release - - - - Op 1 level - - - - Op 1 level scaling - - - - Op 1 frequency multiplier - - - - Op 1 feedback - - - - 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 multiplier - - - - Op 2 key scaling rate - - - - Op 2 percussive envelope - - - - Op 2 tremolo - - - - Op 2 vibrato - - - - Op 2 waveform - - - - FM - FM - - - Vibrato depth - - - - Tremolo depth - - - - - OpulenzInstrumentView - - Attack - Náběh - - - Decay - Útlum - - - Release - Uvolnění - - - Frequency multiplier - Násobič frekvence - OscillatorObject - Osc %1 volume - Osc %1 hlasitost - - - Osc %1 panning - Osc %1 panoráma - - - Osc %1 coarse detuning - Osc %1 hrubé rozladění - - - Osc %1 fine detuning left - Osc %1 jemné rozladění vlevo - - - Osc %1 fine detuning right - Osc %1 jemné rozladění vpravo - - - Osc %1 phase-offset - Osc %1 posun fáze - - - Osc %1 stereo phase-detuning - Osc %1 rozladění stereo fáze - - - Osc %1 wave shape - Osc %1 forma vlny - - - Modulation type %1 - Typ modulace %1 - - + Osc %1 waveform Osc %1 vlna + Osc %1 harmonic Osc %1 harmonické + + + + Osc %1 volume + Osc %1 hlasitost + + + + + Osc %1 panning + Osc %1 panoráma + + + + + Osc %1 fine detuning left + Osc %1 jemné rozladění vlevo + + + + Osc %1 coarse detuning + Osc %1 hrubé rozladění + + + + Osc %1 fine detuning right + Osc %1 jemné rozladění vpravo + + + + Osc %1 phase-offset + Osc %1 posun fáze + + + + Osc %1 stereo phase-detuning + Osc %1 rozladění stereo fáze + + + + Osc %1 wave shape + Osc %1 forma vlny + + + + Modulation type %1 + Typ modulace %1 + PatchesDialog + Qsynth: Channel Preset Qsynth: Předvolba kanálu + Bank selector Výběr banky + Bank Banka + Program selector Výběr programu + Patch Patch + Name Název + OK OK + Cancel Zrušit @@ -2320,244 +6755,1727 @@ PatmanView + + Open other patch + Otevřít jiný patch + + + + Click here to open another patch-file. Loop and Tune settings are not reset. + Klepněte sem, pokud chcete otevřít další patch-soubor. Nastavení smyčky a režimu ladění zůstanou zachována. + + + Loop Smyčka + Loop mode Režim smyčky + + Here you can toggle the Loop mode. If enabled, PatMan will use the loop information available in the file. + Zde můžete přepínat režim smyčky. Je-li zapnutá, PatMan použije informace o smyčce dostupné v souboru. + + + Tune Ladění + Tune mode Režim ladění + + Here you can toggle the Tune mode. If enabled, PatMan will tune the sample to match the note's frequency. + Zde můžete přepínat režim ladění. Je-li zapnut, PatMan naladí vzorek tak, aby odpovídal frekvenci noty. + + + No file selected Není vybrán žádný soubor + Open patch file Otevřít soubor patch + Patch-Files (*.pat) Soubor patch (*.pat) + + + PatternView - Open patch - + + use mouse wheel to set velocity of a step + použijte kolečko myši pro nastavení dynamiky kroku + + + + double-click to open in Piano Roll + poklepáním otevřete v Piano rollu + + + + Open in piano-roll + Otevřít v Piano rollu + + + + Clear all notes + Vymazat všechny noty + + + + Reset name + Resetovat jméno + + + + Change name + Změnit jméno + + + + Add steps + Přidat kroky + + + + Remove steps + Odstranit kroky + + + + Clone Steps + Klonovat kroky + + + + PeakController + + + Peak Controller + Ovladač špičky + + + + Peak Controller Bug + Chyba ovladače špičky + + + + 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. + Z důvodu chyby ve starší verzi LMMS nemusí být ovladače špiček správně připojeny. Ujistěte se prosím, zda jsou ovladače špiček správně připojeny a znovu uložte tento soubor. Omlouváme se za způsobené nepříjemnosti. + + + + PeakControllerDialog + + + PEAK + ŠPIČ + + + + LFO Controller + Ovladač LFO PeakControllerEffectControlDialog + BASE ZÁKL - Modulation amount: - Hloubka modulace: - - - Attack: - Náběh: - - - Release: - Uvolnění: + + Base amount: + Základní míra: + AMNT MNOŽ + + Modulation amount: + Hloubka modulace: + + + MULT NÁSB + + Amount Multiplicator: + Násobič množství: + + + ATCK NÁBH + + Attack: + Náběh: + + + DCAY - ÚTLM + POKL - Treshold: - Práh: + + Release: + Doznění: + TRSH PRÁH - Base: - - - - Amount multiplicator: - - - - Mute output - Ztlumit výstup - - - Absolute value - + + Treshold: + Práh: PeakControllerEffectControls + Base value Základní hodnota + Modulation amount Hloubka modulace - Mute output - Ztlumit výstup - - + Attack Náběh + Release - Uvolnění + Doznění + Treshold Práh - Absolute value - + + Mute output + Ztlumit výstup - Amount multiplicator - + + Abs Value + Abs hodnota + + + + Amount Multiplicator + Násobič množství + + + + PianoRoll + + + Note Velocity + Dynamika noty + + + + Note Panning + Panoráma noty + + + + Mark/unmark current semitone + Zvýraznit/Skrýt zvolený tón + + + + Mark/unmark all corresponding octave semitones + Zvýraznit/Skrýt zvolený tón ve všech oktávách + + + + Mark current scale + Zvýraznit zvolenou stupnici + + + + Mark current chord + Zvýraznit zvolený akord + + + + Unmark all + Skrýt vše + + + + Select all notes on this key + Vybrat všechny noty zvolené výšky + + + + Note lock + Zamknout notu + + + + Last note + Podle poslední noty + + + + No scale + Žádná stupnice + + + + No chord + Žádný akord + + + + Velocity: %1% + Dynamika: %1% + + + + Panning: %1% left + Panoráma: %1% vlevo + + + + Panning: %1% right + Panoráma: %1% vpravo + + + + Panning: center + Panoráma: střed + + + + Please open a pattern by double-clicking on it! + Otevřete prosím záznam poklepáním! + + + + + Please enter a new value between %1 and %2: + Vložte prosím novou hodnotu mezi %1 a %2: + + + + PianoRollWindow + + + Play/pause current pattern (Space) + Přehrát/Pozastavit přehrávání aktuálního záznamu (mezerník) + + + + Record notes from MIDI-device/channel-piano + Nahrávat z MIDI zařízení / virtuální klávesnice + + + + Record notes from MIDI-device/channel-piano while playing song or BB track + Nahrávat z MIDI zařízení / virtuální klávesnice při přehrávání skladby nebo stopy bicích/basů + + + + Stop playing of current pattern (Space) + Zastavit přehrávání aktuálního záznamu (mezerník) + + + + Click here to play the current pattern. This is useful while editing it. The pattern is automatically looped when its end is reached. + Klepněte sem, pokud chcete přehrát aktuální záznam. To je užitečné při editaci. Záznam je automaticky přehráván ve smyčce. + + + + 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. + Klepněte sem, pokud chcete nahrávat z MIDI zařízení nebo z virtuální klávesnice příslušného kanálového okna do aktuálního záznamu. Při nahrávání se zapíší všechny zahrané noty do tohoto záznamu, a následně je můžete přehrát nebo upravit. + + + + 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. + Klepněte sem, pokud chcete nahrávat z MIDI zařízení nebo z virtuální klávesnice příslušného kanálového okna do aktuálního záznamu. Při nahrávání se zapíší všechny zahrané noty do tohoto záznamu a na pozadí uslyšíte skladbu nebo stopu bicích/basů. + + + + Click here to stop playback of current pattern. + Klepněte sem, pokud chcete zastavit přehrávání aktuálního záznamu. + + + + Edit actions + Akce úprav + + + + Draw mode (Shift+D) + Režim kreslení (Shift+D) + + + + Erase mode (Shift+E) + Režim mazání (Shift+E) + + + + Select mode (Shift+S) + Režim výběru (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. + Klepněte sem pro aktivaci režimu kreslení. V tomto režimu můžete přidávat, měnit a přesouvat noty. Toto je výchozí režim, který se používá nejčastěji. Pro aktivaci tohoto režimu můžete také stisknout "Shift+D" na klávesnici. V tomto režimu podržte %1 pro dočasné přepnutí do režimu výběru. + + + + 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. + Klepněte sem pro aktivaci režimu mazání. V tomto režimu můžete vymazávat noty. Pro aktivaci tohoto režimu můžete také stisknout tlačítko "Shift+E" na klávesnici. + + + + 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. + Klepněte sem pro aktivaci režimu výběru. V tomto režimu můžete vybírat noty. Alternativně můžete v režimu kreslení držet %1 pro dočasné přepnutí do režimu výběru. + + + + Pitch Bend mode (Shift+T) + Režim ohýbání výšky (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. + Klepněte sem pro aktivaci režimu ohýbání výšky tónu. V tomto režimu můžete klepnutím na notu otevřít její automatizované rozladění. To můžete využít ke sklouznutí z jedné noty na jinou. Pro aktivaci tohoto režimu můžete také stisknout klávesu "Shift+T" na klávesnici. + + + + Quantize + Kvantizace + + + + Copy paste controls + Ovládání kopírování a vkládání + + + + Cut selected notes (%1+X) + Vyjmout označené noty (%1+X) + + + + Copy selected notes (%1+C) + Kopírovat označené noty (%1+C) + + + + Paste notes from clipboard (%1+V) + Vložit noty ze schránky (%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. + Klepněte sem, pokud chcete označené noty vyjmout a uložit do schránky. Vložit je pak můžete kdekoliv v libovolném záznamu pomocí tlačítka Vložit. + + + + 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. + Klepněte sem, pokud chcete označené noty zkopírovat do schránky. Vložit je pak můžete kdekoliv v libovolném záznamu pomocí tlačítka Vložit. + + + + Click here and the notes from the clipboard will be pasted at the first visible measure. + Klepnete-li sem, budou noty ze schránky vloženy do prvního viditelného taktu. + + + + Timeline controls + Ovládání časové osy + + + + Zoom and note controls + Lupa a ovládání not + + + + 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. + Tímto se ovládá zvětšení osy. To může být užitečné při volbě zvětšení pro konkrétní úkol. Při běžné úpravě by mělo být zvětšení použito na vaše nejmenší noty. + + + + 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. + "Q" znamená kvantizaci, která ovládá mřížku velikosti not a kontrolní body krokování. S menšími hodnotami kvantizace můžete kreslit kratší noty v Piano rollu a přesnější kontrolní body v editoru automatizace. + + + + 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 + Tímto je možno vybrat délku nových not. "Poslední nota" znamená, že LMMS použije délku naposledy upravované noty. + + + + 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! + Funkce je přímo propojena s kontextovou nabídkou na virtuální klávesnici vlevo v Piano rollu. Poté, co jste v rozbalovací nabídce zvolili stupnici, můžete klepnout pravým tlačítkem na požadovanou klávesu na virtuální klávesnici, a pak zvolit "Zvýraznit zvolenou stupnici". LMMS zvýrazní všechny noty, které patří do zvolené stupnice, a to od klávesy, kterou jste vybrali! + + + + 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. + Vyberte si akord, který pak LMMS může nakreslit nebo zvýraznit. V rozbalovací nabídce najdete nejčastěji používané akordy. Po výběru akordu klepněte kamkoliv pro umístění akordu, klepnutím pravým tlačítkem na virtuální klávesnici pak otevřete kontextové menu a zvýrazníte akord. Chcete-li se vrátit k práci s jednotlivými notami, musíte v rozbalovací nabídce zvolit možnost "Žádný akord". + + + + + Piano-Roll - %1 + Piano roll – %1 + + + + + Piano-Roll - no pattern + Piano roll – žádný záznam + + + + PianoView + + + Base note + Základní nota + + + + Plugin + + + Plugin not found + Plugin nenalezen + + + + The plugin "%1" wasn't found or could not be loaded! +Reason: "%2" + Plugin "%1" nebyl nalezen nebo nemůže být načten! +Důvod: "%2" + + + + Error while loading plugin + Při načítání pluginu došlo k chybě + + + + Failed to load plugin "%1"! + Načtení pluginu "%1" selhalo! + + + + PluginBrowser + + + Instrument Plugins + Nástrojové pluginy + + + + Instrument browser + Prohlížeč nástrojů + + + + Drag an instrument into either the Song-Editor, the Beat+Bassline Editor or into an existing instrument track. + Nástroj přetáhněte do editoru skladby, editoru bicích/basů nebo do existující nástrojové stopy. + + + + PluginFactory + + + Plugin not found. + Plugin nebyl nalezen. + + + + LMMS plugin %1 does not have a plugin descriptor named %2! + U LMMS pluginu %1 chybí popisovač pluginu s názvem %2! + + + + ProjectNotes + + + Project Notes + Poznámky k projektu + + + + Enter project notes here + Sem zapište poznámky k projektu + + + + Edit Actions + Provedené úpravy + + + + &Undo + &Zpět + + + + %1+Z + %1+Z + + + + &Redo + &Znovu + + + + %1+Y + %1+Z + + + + &Copy + &Kopírovat + + + + %1+C + %1+C + + + + Cu&t + &Vyjmout + + + + %1+X + %1+X + + + + &Paste + V&ložit + + + + %1+V + %1+V + + + + Format Actions + Formátování + + + + &Bold + &Tučné + + + + %1+B + %1+B + + + + &Italic + &Kurzíva + + + + %1+I + %1+I + + + + &Underline + &Podtržené + + + + %1+U + %1+U + + + + &Left + &Vlevo + + + + %1+L + %1+L + + + + C&enter + &Na střed + + + + %1+E + %1+E + + + + &Right + V&pravo + + + + %1+R + %1+R + + + + &Justify + &Do bloku + + + + %1+J + %1+J + + + + &Color... + &Barva... + + + + ProjectRenderer + + + WAV-File (*.wav) + WAV soubor (*.wav) + + + + Compressed OGG-File (*.ogg) + Komprimovaný OGG soubor (*.ogg) + + + FLAC-File (*.flac) + Soubor FLAC (*.flac) + + + + Compressed MP3-File (*.mp3) + Komprimovaný soubor MP3 (*.mp3) QWidget + + + Name: Název: + + Maker: Tvůrce: + + Copyright: Autorská práva: + + Requires Real Time: Vyžaduje běh v reálném čase: + + + + + + Yes Ano + + + + + + No Ne + + Real Time Capable: Schopnost běhu v reálném čase: + + In Place Broken: Na místě poškozeného: + + Channels In: Vstupní kanály: + + Channels Out: Výstupní kanály: + + File: %1 + Soubor: %1 + + + File: Soubor: + + + RenameDialog - File: %1 - Soubor: %1 + + Rename... + Přejmenovat... ReverbSCControlDialog + Input Vstup + + Input Gain: + Zesílení vstupu: + + + Size Velikost + Size: Velikost: + Color Barva + Color: Barva: + Output Výstup - Input gain: - Zesílení vstupu: - - - Output gain: - Zesílení výstupu: + + Output Gain: + Zesílení výstupu: ReverbSCControls + + Input Gain + Vstupní úroveň + + + Size Velikost + Color Barva - Input gain - Zesílení vstupu + + Output Gain + Zesílení výstupu + + + + SampleBuffer + + + Fail to open file + Chyba otevírání souboru - Output gain - Zesílení výstupu + + Audio files are limited to %1 MB in size and %2 minutes of playing time + Audio soubory jsou omezeny na %1 MB velikosti a %2 minut délky + + + + Open audio file + Otevřít audio soubor + + + + All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + Všechny audio soubory (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + + + + Wave-Files (*.wav) + WAV soubory (*.wav) + + + + OGG-Files (*.ogg) + OGG soubory (*.ogg) + + + + DrumSynth-Files (*.ds) + DrumSynth soubory (*.ds) + + + + FLAC-Files (*.flac) + FLAC soubory (*.flac) + + + + SPEEX-Files (*.spx) + SPEEX soubory (*.spx) + + + + VOC-Files (*.voc) + VOC soubory (*.voc) + + + + AIFF-Files (*.aif *.aiff) + Soubory AIFF (*.aif *.aiff) + + + + AU-Files (*.au) + AU soubory (*.au) + + + + RAW-Files (*.raw) + RAW soubory (*.raw) + + + + SampleTCOView + + + double-click to select sample + poklepáním vyberte sampl + + + + Delete (middle mousebutton) + Smazat (prostřední tlačítko myši) + + + + Cut + Vyjmout + + + + Copy + Kopírovat + + + + Paste + Vložit + + + + Mute/unmute (<%1> + middle click) + Ztlumit/Odtlumit (<%1> + prostřední tlačítko) + + + + SampleTrack + + + Volume + Hlasitost + + + + Panning + Panoráma + + + + + Sample track + Stopa samplů + + + + SampleTrackView + + + Track volume + Hlasitost stopy + + + + Channel volume: + Hlasitost kanálu: + + + + VOL + HLA + + + + Panning + Panoráma + + + + Panning: + Panoráma: + + + + PAN + PAN + + + + SetupDialog + + + Setup LMMS + Nastavení LMMS + + + + + General settings + Hlavní nastavení + + + + BUFFER SIZE + VELIKOST VYR. PAMĚTI + + + + + Reset to default-value + Nastavit výchozí hodnoty + + + + MISC + JINÉ + + + + Enable tooltips + Zapnout bublinovou nápovědu + + + + Show restart warning after changing settings + Zobrazit výzvu k restartu po změně nastavení + + + + Display volume as dBFS + Zobrazit hlasitost v dBFS + + + + Compress project files per default + Komprimovat soubory s projekty + + + + One instrument track window mode + Režim jedné stopy pro nástroje + + + + HQ-mode for output audio-device + HQ režim pro výstup audio zařízení + + + + Compact track buttons + Malá tlačítka u stop + + + + Sync VST plugins to host playback + Synchronizace VST pluginů s hostujícím přehráváním + + + + Enable note labels in piano roll + Povolit názvy tónů v Piano rollu + + + + Enable waveform display by default + Povolit zobrazení vlny ve výchozím nastavení + + + + Keep effects running even without input + Nechat efekty spuštěné i bez vstupu + + + + Create backup file when saving a project + Při ukládání projektu vytvořit záložní soubor + + + + Reopen last project on start + Po spuštění otevřít poslední projekt + + + + Use built-in NaN handler + Použít vestavěný NaN handler + + + + PLUGIN EMBEDDING + VLOŽENÍ PLUGINU + + + + No embedding + Nevkládat + + + + Embed using Qt API + Vložit pomocí rozhraní Qt + + + + Embed using native Win32 API + Vložit pomocí nativního rozhraní Win32 + + + + Embed using XEmbed protocol + Vložit pomocí protokolu XEmbed + + + + LANGUAGE + Jazyk + + + + + Paths + Cesty + + + + Directories + Adresáře + + + + LMMS working directory + Pracovní adresář LMMS + + + + Themes directory + Adresář pro témata + + + + Background artwork + Obrázek na pozadí + + + + VST-plugin directory + Adresář pro VST pluginy + + + + GIG directory + Adresář pro GIG + + + + SF2 directory + Adresář pro SF2 + + + + LADSPA plugin directories + Adresář pro LADSPA pluginy + + + + STK rawwave directory + Adresář pro STK rawwave + + + + Default Soundfont File + Výchozí Soundfont soubor + + + + + Performance settings + Nastavení výkonu + + + + Auto save + Automatické ukládání + + + + Enable auto-save + Povolit automatické ukládání + + + + Allow auto-save while playing + Povolit automatické ukládání během přehrávání + + + + UI effects vs. performance + Efekty uživatelského rozhraní vs. výkon + + + + Smooth scroll in Song Editor + Plynulé posouvání v Song Editoru + + + + Show playback cursor in AudioFileProcessor + Zobrazit přehrávací kurzor v AudioFileProcessoru + + + + + Audio settings + Audio nastavení + + + + AUDIO INTERFACE + AUDIO ROZHRANÍ + + + + + MIDI settings + MIDI nastavení + + + + MIDI INTERFACE + MIDI ROZHRANÍ + + + + OK + OK + + + + Cancel + Zrušit + + + + Restart LMMS + Restartovat LMMS + + + + Please note that most changes won't take effect until you restart LMMS! + Mnohé změny nastavení se projeví až po restartu LMMS! + + + + Frames: %1 +Latency: %2 ms + Rámce: %1 +Zpoždění %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. + Zde můžete nastavit interní velikost vyrovnávací paměti, která je užívána LMMS. Nízké hodnoty vedou k menšímu zpoždění, ale také způsobují nepoužitelný zvuk nebo špatný výkon, zejména na starých počítačích či systémech s jádrem nepodporujícím real time. + + + + Choose LMMS working directory + Vyberte pracovní adresář LMMS + + + + Choose your GIG directory + Vyberte svůj adresář pro GIG soubory + + + + Choose your SF2 directory + Vyberte svůj adresář pro SF2 soubory + + + + Choose your VST-plugin directory + Vyberte adresář pro VST pluginy + + + + Choose artwork-theme directory + Vyberte adresář s tématy + + + + Choose LADSPA plugin directory + Vyberte adresář pro LADSPA pluginy + + + + Choose STK rawwave directory + Vyberte adresář pro STK rawwave + + + + Choose default SoundFont + Vyberte výchozí SoundFont + + + + Choose background artwork + Vyberte obrázek na pozadí + + + + minutes + minut + + + + minute + minuta + + + + Disabled + Vypnuto + + + + Auto-save interval: %1 + Interval automatického ukládání: %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. + Nastavte čas mezi automatickým zálohováním na %1. +Nezapomeňte také svůj projekt uložit ručně. Můžete si vybrat, zda nechcete během přehrávání zakázat ukládání, což je problematické pro některé starší systémy. + + + + 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. + Zde vyberte preferované audio rozhraní. V závislosti na konfiguraci Vašeho systému při kompilaci můžete volit mezi ALSA, JACK, OSS a dalšími. Níže vidíte políčko, které nabízí možnost nastavení vybraného audio rozhraní. + + + + 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. + Zde vyberte preferované MIDI rozhraní. V závislosti na konfiguraci Vašeho systému při kompilaci můžete volit mezi ALSA OSS a dalšími. Níže vidíte políčko, které nabízí možnost nastavení vybraného MIDI rozhraní. + + + + Song + + + Tempo + Tempo + + + + Master volume + Hlavní hlasitost + + + + Master pitch + Transpozice + + + + LMMS Error report + Chybové hlášení LMMS + + + + Project saved + Projekt uložen + + + + The project %1 is now saved. + Projekt %1 je nyní uložen. + + + + Project NOT saved. + Projekt NENÍ uložen. + + + + The project %1 was not saved! + Projekt %1 nebyl uložen! + + + + Import file + Importovat soubor + + + + MIDI sequences + MIDI sekvence + + + + Hydrogen projects + Projekty Hydrogen + + + + All file types + Všechny typy souborů + + + + + Empty project + Prázdný projekt + + + + + This project is empty so exporting makes no sense. Please put some items into Song Editor first! + Tento projekt je prázdný, jeho exportování nemá smysl. Nejdříve prosím vložte nějaké položky do Editoru skladby! + + + + Select directory for writing exported tracks... + Vyberte adresář pro zápis exportovaných stop... + + + + + untitled + nepojmenovaný + + + + + Select file for project-export... + Vyberte soubor pro export projektu... + + + + Save project + Uložit projekt + + + + MIDI File (*.mid) + MIDI soubor (*.mid) + + + + The following errors occured while loading: + Během načítání se vyskytly tyto chyby: + + + + SongEditor + + + Could not open file + Nemohu otevřít soubor + + + + 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. + Nelze otevřít soubor %1. Pravděpodobně nemáte oprávnění číst tento soubor. + Ujistěte se prosím, že máte oprávnění alespoň číst tento soubor a zkuste to znovu. + + + + Could not write file + Nemohu zapsat soubor + + + + 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. + Nelze zapisovat do souboru %1. Pravděpodobně nemáte oprávnění zapisovat do tohoto souboru. Ujistěte se prosím, že máte oprávnění zapisovat do tohoto souboru a zkuse to znovu. + + + + Error in file + Chyba v souboru + + + + The file %1 seems to contain errors and therefore can't be loaded. + Soubor %1 pravděpodobně obsahuje chyby, a proto nemohl být načten. + + + + Version difference + Rozdíl verzí + + + + This %1 was created with LMMS %2. + %1 byl vytvořen v LMMS %2. + + + + template + šablona + + + + project + projekt + + + + Tempo + Tempo + + + + TEMPO/BPM + TEMPO/BPM + + + + tempo of song + tempo skladby + + + + 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). + Tempo skladby je uvedeno v úderech za minutu (BPM). Chcete-li změnit tempo skladby, změňte tuto hodnotu. Každý takt má čtyři doby (beats), takže tempo v BPM specifikuje kolik taktů / 4 bude za minutu přehráno (nebo kolik taktů bude přehráno ve čtyřech minutách). + + + + High quality mode + Režim vysoké kvality + + + + + Master volume + Hlavní hlasitost + + + + master volume + hlavní hlasitost + + + + + Master pitch + Transpozice + + + + master pitch + transpozice + + + + Value: %1% + Hodnota: %1% + + + + Value: %1 semitones + Hodnota: %1 půltónů + + + + SongEditorWindow + + + Song-Editor + Editor skladby + + + + Play song (Space) + Přehrát skladbu (mezerník) + + + + Record samples from Audio-device + Nahrát samply z audio zařízení + + + + Record samples from Audio-device while playing song or BB track + Nahrát samply z audio zařízení při přehrávání skladby nebo stopy bicích/basů + + + + Stop song (Space) + Zastavit přehrávání (mezerník) + + + + 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. + Klepněte sem, pokud chcete přehrát celou skladbu. Přehrávání začne v místě kde se nalézá zelený označovač pozice, se kterým lze též při přehrávání pohybovat. + + + + Click here, if you want to stop playing of your song. The song-position-marker will be set to the start of your song. + Klepněte sem, pokud chcete zastavit přehrávání skladby. Označovač pozice bude nastaven na začátek skladby. + + + + Track actions + Akce stopy + + + + Add beat/bassline + Přidat bicí/basy + + + + Add sample-track + Přidat stopu samplů + + + + Add automation-track + Přidat stopu automatizace + + + + Edit actions + Akce úprav + + + + Draw mode + Režim kreslení + + + + Edit mode (select and move) + Režim úprav (označit a přesunout) + + + + Timeline controls + Ovládání časové osy + + + + Zoom controls + Ovládání zvětšení SpectrumAnalyzerControlDialog + Linear spectrum Lineární spektrum + Linear Y axis Lineární osa Y @@ -2565,412 +8483,1042 @@ SpectrumAnalyzerControls + Linear spectrum Lineární spektrum + Linear Y axis Lineární osa Y + Channel mode Režim kanálu + + SubWindow + + + Close + Zavřít + + + + Maximize + Maximalizovat + + + + Restore + Obnovit + + + + TabWidget + + + + Settings for %1 + Nastavení rpo %1 + + + + TempoSyncKnob + + + + Tempo Sync + Synchronizace tempa + + + + No Sync + Nesynchronizovat + + + + Eight beats + Osm dob + + + + Whole note + Celá nota + + + + Half note + Půlová nota + + + + Quarter note + Čtvrťová nota + + + + 8th note + Osminová nota + + + + 16th note + Šestnáctinová nota + + + + 32nd note + Dvaatřicetinová nota + + + + Custom... + Vlastní... + + + + Custom + Vlastní + + + + Synced to Eight Beats + Synchronizováno k osmi dobám + + + + Synced to Whole Note + Synchronizováno k celé notě + + + + Synced to Half Note + Synchronizováno k půlové notě + + + + Synced to Quarter Note + Synchronizováno ke čtvrťové notě + + + + Synced to 8th Note + Synchronizováno k osminové notě + + + + Synced to 16th Note + Synchronizováno k šestnáctinové notě + + + + Synced to 32nd Note + Synchronizováno k dvaatřicetinové notě + + + + TimeDisplayWidget + + + click to change time units + klepněte pro změnu časových jednotek + + + + MIN + MIN + + + + SEC + S + + + + MSEC + MS + + + + BAR + TAKT + + + + BEAT + DOBA + + + + TICK + TIK + + + + TimeLineWidget + + + Enable/disable auto-scrolling + Povolit/Zakázat automatický posun + + + + Enable/disable loop-points + Povolit/Zakázat body přehrávání ve smyčce + + + + After stopping go back to begin + Po skončení přetočit zpět na začátek + + + + After stopping go back to position at which playing was started + Po skončení přetočit zpět na pozici, ze které přehrávání začalo + + + + After stopping keep position + Po skončení zachovat pozici + + + + + Hint + Rada + + + + Press <%1> to disable magnetic loop points. + Stiskněte <%1> pro vypnutí magnetických bodů smyčky. + + + + Hold <Shift> to move the begin loop point; Press <%1> to disable magnetic loop points. + Držte <Shift> pro přesouvání počátečního bodu smyčky; stiskněte <%1> pro vypnutí magnetických bodů smyčky. + + + + Track + + + Mute + Ztlumit + + + + Solo + Sólo + + TrackContainer + + Couldn't import file + Nemohu importovat soubor + + + + Couldn't find a filter for importing file %1. +You should convert this file into a format supported by LMMS using another software. + Nemohu najít filtr pro import souboru %1. +Měli byste tento soubor převést do formátu podporovaného LMMS pomocí jiného software. + + + + Couldn't open file + Nemohu otevřít soubor + + + + 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! + Nemohu otevřít soubor %1 pro čtení. +Přesvědčte se prosím, že máte právo ke čtení tohoto souboru a příslušného adresáře a zkuste to znovu! + + + + Loading project... + Načítám projekt... + + + + Cancel Zrušit + + Please wait... Prosím čekejte... + + Loading cancelled + Načítání zrušeno + + + + Project loading was cancelled. + Načítání projektu bylo zrušeno. + + + + Loading Track %1 (%2/Total %3) + Načítám Stopu %1 (%2/celkem %3) + + + Importing MIDI-file... Importuji MIDI soubor... + + TrackContentObject + + + Mute + Ztlumit + + + + TrackContentObjectView + + + Current position + Aktuální pozice + + + + + Hint + Rada + + + + Press <%1> and drag to make a copy. + K vytvoření kopie stiskněte <%1> a táhněte myší. + + + + Current length + Aktuální délka + + + + Press <%1> for free resizing. + Stiskněte <%1> pro volnou změnu velikosti. + + + + + %1:%2 (%3:%4 to %5:%6) + %1:%2 (%3:%4 do %5:%6) + + + + Delete (middle mousebutton) + Smazat (prostřední tlačítko myši) + + + + Cut + Vyjmout + + + + Copy + Kopírovat + + + + Paste + Vložit + + + + Mute/unmute (<%1> + middle click) + Ztlumit/Odtlumit (<%1> + prostřední tlačítko myši) + + + + TrackOperationsWidget + + + Press <%1> while clicking on move-grip to begin a new drag'n'drop-action. + Při klepnutí na úchop držte <%1> pro zkopírování přetahované stopy. + + + + Actions for this track + Akce pro tuto stopu + + + + Mute + Ztlumit + + + + + Solo + Sólo + + + + Mute this track + Ztlumit tuto stopu + + + + Clone this track + Klonovat tuto stopu + + + + Remove this track + Odstranit tuto stopu + + + + Clear this track + Smazat tuto stopu + + + + FX %1: %2 + Efekt %1: %2 + + + + Assign to new FX Channel + Přiřadit k novému efektovému kanálu + + + + Turn all recording on + Spustit všechna nahrávání + + + + Turn all recording off + Zastavit všechna nahrávání + + TripleOscillatorView + + Use phase modulation for modulating oscillator 1 with oscillator 2 + Použít fázovou modulaci pro modulování oscilátoru 1 oscilátorem 2 + + + + Use amplitude modulation for modulating oscillator 1 with oscillator 2 + Použít amplitudovou modulaci pro modulování oscilátoru 1 oscilátorem 2 + + + + Mix output of oscillator 1 & 2 + Smíchat výstupy oscilátorů 1 a 2 + + + Synchronize oscillator 1 with oscillator 2 Synchronizovat oscilátor 1 oscilátorem 2 + + Use frequency modulation for modulating oscillator 1 with oscillator 2 + Použít frekvenční modulaci pro modulování oscilátoru 1 oscilátorem 2 + + + + Use phase modulation for modulating oscillator 2 with oscillator 3 + Použít fázovou modulaci pro modulování oscilátoru 2 oscilátorem 3 + + + + Use amplitude modulation for modulating oscillator 2 with oscillator 3 + Použít amplitudovou modulaci pro modulování oscilátoru 2 oscilátorem 3 + + + + Mix output of oscillator 2 & 3 + Smíchat výstupy oscilátorů 2 a 3 + + + Synchronize oscillator 2 with oscillator 3 Synchronizovat oscilátor 2 oscilátorem 3 + + Use frequency modulation for modulating oscillator 2 with oscillator 3 + Použít frekvenční modulaci pro modulování oscilátoru 2 oscilátorem 3 + + + Osc %1 volume: Osc %1 hlasitost: + + 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. + Tímto otočným ovladačem můžete nastavit hlasitost oscilátoru %1. Když nastavíte hodnotu 0, oscilátor bude vypnutý. Jinak uslyšíte oscilátor tak hlasitě, jak si ho zde nastavíte. + + + Osc %1 panning: Osc %1 panoráma: + + 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. + Tímto otočným ovladačem můžete nastavit panoráma oscilátoru %1. Hodnota -100 znamená maximálně doleva, zatímco hodnota 100 přesouvá výstup oscilátoru doprava. + + + Osc %1 coarse detuning: Osc %1 hrubé rozladění: + semitones půltónů + + 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. + Tímto otočným ovladačem můžete provést hrubé rozladění oscilátoru %1. Můžete oscilátor rozladit o 24 půltónů (2 oktávy) nahoru nebo dolů. To je dobré pro vytvoření zvuku v akordu. + + + Osc %1 fine detuning left: Osc %1 jemné rozladění vlevo: + + cents centů + + 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. + Tímto otočným ovladačem můžete provést jemné rozladění oscilátoru %1 v levém kanálu. Rozsah jemného rozladění je mezi -100 a +100 centy. To je dobré pro vytvoření "tlustého" zvuku. + + + Osc %1 fine detuning right: Osc %1 jemné rozladění vpravo: + + 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. + Tímto otočným ovladačem můžete provést jemné rozladění oscilátoru %1 v pravém kanálu. Rozsah jemného rozladění je mezi -100 a +100 centy. To je dobré pro vytvoření "tlustého" zvuku. + + + Osc %1 phase-offset: Osc %1 posun fáze: + + degrees stupňů + + 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. + Tímto otočným ovladačem můžete nastavit fázový posun oscilátoru %1. To znamená, že můžete posunout bod, ve kterém oscilátor začne kmitat. Například pokud máte sinusovou vlnu s fázovým posunem 180 stupňů, vlna půjde nejdříve dolů. Totéž se stane u vlny pravoúhlé. + + + Osc %1 stereo phase-detuning: Osc %1 rozladění stereo fáze: - Modulate phase of oscillator 1 by oscillator 2 - + + 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. + Tímto otočným ovladačem můžete nastavit rozladění fáze oscilátoru %1. Rozladění stereo fáze určuje velikost rozdílu mezi fázovým posunem levého a pravého kanálu. To je velmi dobré pro vytvoření širokého stereo zvuku. - Modulate amplitude of oscillator 1 by oscillator 2 - + + Use a sine-wave for current oscillator. + Použít sinusovou vlnu pro aktuální oscilátor. - Mix output of oscillators 1 & 2 - + + Use a triangle-wave for current oscillator. + Použít trojúhelníkovou vlnu pro aktuální oscilátor. - Modulate frequency of oscillator 1 by oscillator 2 - + + Use a saw-wave for current oscillator. + Použít pilovitou vlnu pro aktuální oscilátor. - Modulate phase of oscillator 2 by oscillator 3 - + + Use a square-wave for current oscillator. + Použít pravoúhlou vlnu pro aktuální oscilátor. - Modulate amplitude of oscillator 2 by oscillator 3 - + + Use a moog-like saw-wave for current oscillator. + Použít pilovitou vlnu typu Moog pro tento oscilátor. - Mix output of oscillators 2 & 3 - + + Use an exponential wave for current oscillator. + Použít exponenciální vlnu pro aktuální oscilátor. - Modulate frequency of oscillator 2 by oscillator 3 - + + Use white-noise for current oscillator. + Použít bílý šum pro aktuální oscilátor. - Sine wave - Sinusová vlna + + Use a user-defined waveform for current oscillator. + Použít vlastní vlnu pro aktuální oscilátor. + + + + VersionedSaveDialog + + + Increment version number + Zvýšit číslo verze - Triangle wave - Trojúhelníková vlna + + Decrement version number + Snížení čísla verze - Saw wave - Pilovitá vlna - - - Square wave - Pravoúhlá vlna - - - Moog-like saw wave - - - - Exponential wave - Exponenciální vlna - - - White noise - Bílý šum - - - User-defined wave - + + already exists. Do you want to replace it? + již existuje. Přejete si jej přepsat? VestigeInstrumentView - Show/hide GUI - Zobrazit/Skrýt grafické rozhraní + + Open other VST-plugin + Otevřít jiný VST plugin - Turn off all notes - Vypnout všechny noty + + 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. + Klepněte sem, pokud chcete otevřít jiný VST plugin. Po klepnutí na toto tlačítko se objeví okno, ve kterém můžete soubor vybrat. - DLL-files (*.dll) - DLL soubory (*.dll) + + Control VST-plugin from LMMS host + Ovládání VST pluginu hostitelským programem LMMS - EXE-files (*.exe) - EXE soubory (*.exe) + + Click here, if you want to control VST-plugin from host. + Klepněte sem, pokud chcete ovládat VST plugin hostitelským programem. + + Open VST-plugin preset + Otevřít předvolbu VST pluginu + + + + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. + Klepněte sem, chcete-li otevřít jinou *.fxp, *.fxb předvolbu VST pluginu. + + + Previous (-) Předchozí (-) + + + Click here, if you want to switch to another VST-plugin preset program. + Klepněte sem, chcete-li přepnout na jiný přednastavený VST program. + + + Save preset Uložit předvolbu + + Click here, if you want to save current VST-plugin preset program. + Klepněte sem, chcete-li uložit aktuální předvolbu programu VST pluginu. + + + Next (+) Další (+) + + Click here to select presets that are currently loaded in VST. + Klepněte sem, chcete-li vybrat předvolby, které jsou aktuálně nahrány ve VST. + + + + Show/hide GUI + Zobrazit/Skrýt grafické rozhraní + + + + Click here to show or hide the graphical user interface (GUI) of your VST-plugin. + Klepněte sem pro zobrazení nebo skrytí grafického rozhraní (GUI) pro vaše VST pluginy. + + + + Turn off all notes + Vypnout všechny noty + + + + Open VST-plugin + Otevřít jiný VST plugin + + + + DLL-files (*.dll) + DLL soubory (*.dll) + + + + EXE-files (*.exe) + EXE soubory (*.exe) + + + + No VST-plugin loaded + VST plugin není nahrán + + + Preset Předvolba + by od + - VST plugin control – ovládání VST pluginu + + + VisualizationWidget - Open VST plugin - + + click to enable/disable visualization of master-output + klepněte pro zapnutí/vypnutí vizualizace hlavního výstupu - Control VST plugin from LMMS host - - - - Open VST plugin preset - - - - No VST plugin loaded - + + Click to enable + Klepněte pro zapnutí VstEffectControlDialog + Show/hide Ukázat/Skrýt + + Control VST-plugin from LMMS host + Ovládání VST pluginu hostitelským programem LMMS + + + + Click here, if you want to control VST-plugin from host. + Klepněte sem, pokud chcete ovládat VST plugin hostitelským programem. + + + + Open VST-plugin preset + Otevřít předvolbu VST pluginu + + + + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. + Klepněte sem, chcete-li otevřít jinou *.fxp, *.fxb předvolbu VST pluginu. + + + Previous (-) Předchozí (-) + + + Click here, if you want to switch to another VST-plugin preset program. + Klepněte sem, chcete-li přepnout na jiný přednastavený VST program. + + + Next (+) Další (+) + + Click here to select presets that are currently loaded in VST. + Klepněte sem, chcete-li vybrat předvolby, které jsou aktuálně nahrány ve VST. + + + Save preset Uložit předvolbu + + Click here, if you want to save current VST-plugin preset program. + Klepněte sem, chcete-li uložit aktuální předvolbu programu VST pluginu. + + + + Effect by: Efekt od: + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> - - Control VST plugin from LMMS host - - - - Open VST plugin preset - - VstPlugin - Loading plugin - Načítám plugin + + + The VST plugin %1 could not be loaded. + VST plugin %1 nelze načíst. + Open Preset Otevřít předvolbu + + Vst Plugin Preset (*.fxp *.fxb) Předvolba VST pluginu (*.fxp *.fxb) + : default : výchozí + " " + ' ' + Save Preset Uložit předvolbu + .fxp .fxp + .FXP .FXP + .FXB .FXB + .fxb .fxb - Please wait while loading VST plugin... - Počkejte prosím, než se načte VST plugin... + + Loading plugin + Načítám plugin - The VST plugin %1 could not be loaded. - VST plugin %1 nelze načíst. + + Please wait while loading VST plugin... + Počkejte prosím, než se načte VST plugin... WatsynInstrument + Volume A1 Hlasitost A1 + Volume A2 Hlasitost A2 + Volume B1 Hlasitost B1 + Volume B2 Hlasitost B2 + Panning A1 Panoráma A1 + Panning A2 Panoráma A2 + Panning B1 Panoráma B1 + Panning B2 Panoráma B2 + Freq. multiplier A1 Násobič frekv. A1 + Freq. multiplier A2 Násobič frekv. A2 + Freq. multiplier B1 Násobič frekv. B1 + Freq. multiplier B2 Násobič frekv. B2 + Left detune A1 Rozladění vlevo A1 + Left detune A2 Rozladění vlevo A2 + Left detune B1 Rozladění vlevo B1 + Left detune B2 Rozladění vlevo B2 + Right detune A1 Rozladění vpravo A1 + Right detune A2 Rozladění vpravo A2 + Right detune B1 Rozladění vpravo B1 + Right detune B2 Rozladění vpravo B2 + A-B Mix Směšovač A-B + A-B Mix envelope amount Množství obálky směšovače A-B + A-B Mix envelope attack Náběh obálky směšovače A-B + A-B Mix envelope hold - Množství držení směšovače A-B + Množství zadržení směšovače A-B + A-B Mix envelope decay - Útlum obálky směšovače A-B + Pokles obálky směšovače A-B + A1-B2 Crosstalk Přeslech A1-B2 + A2-A1 modulation Modulace A1-B2 + B2-B1 modulation Modulace B2-B1 + Selected graph Zvolený graf @@ -2978,449 +9526,442 @@ WatsynView - Select oscillator A1 - Vybrat oscilátor A1 - - - Select oscillator A2 - Vybrat oscilátor A2 - - - Select oscillator B1 - Vybrat oscilátor B1 - - - Select oscillator B2 - Vybrat oscilátor B2 - - - Mix output of A2 to A1 - Přimíchat výstup A1 do A2 - - - Mix output of B2 to B1 - Přimíchat výstup B1 do B2 - - - Draw your own waveform here by dragging your mouse on this graph. - Kreslení vlastní křivky tahem myši na tomto grafu. - - - Load waveform - Načíst vlnu - - - Phase left - Fáze vlevo - - - Phase right - Fáze vpravo - - - Normalize - Normalizovat - - - Invert - Převrátit - - - Smooth - Uhladit - - - Sine wave - Sinusová vlna - - - Triangle wave - Trojúhelníková vlna - - - Square wave - Pravoúhlá vlna - - + + + + Volume Hlasitost + + + + Panning Panoráma + + + + Freq. multiplier Násobič frekv. + + + + Left detune Rozladění vlevo + + + + + + + + cents centů + + + + Right detune Rozladění vpravo + A-B Mix Směšovač A-B + Mix envelope amount Množství obálky směšovače + Mix envelope attack Náběh obálky směšovače + Mix envelope hold - Držení obálky směšovače + Zadržení obálky směšovače + Mix envelope decay - Útlum obálky směšovače + Pokles obálky směšovače + Crosstalk Přeslech - Modulate amplitude of A1 by output of A2 - + + Select oscillator A1 + Vybrat oscilátor A1 - Ring modulate A1 and A2 - + + Select oscillator A2 + Vybrat oscilátor A2 - Modulate phase of A1 by output of A2 - + + Select oscillator B1 + Vybrat oscilátor B1 - Modulate amplitude of B1 by output of B2 - + + Select oscillator B2 + Vybrat oscilátor B2 - Ring modulate B1 and B2 - + + Mix output of A2 to A1 + Přimíchat výstup A1 do A2 - Modulate phase of B1 by output of B2 - + + Modulate amplitude of A1 with output of A2 + Modulovat amplitudu A1 výstupem A2 - Load a waveform from a sample file - + + Ring-modulate A1 and A2 + Kruhově modulovat A1 a A2 - Shift phase by -15 degrees - + + Modulate phase of A1 with output of A2 + Modulovat fázi A1 výstupem A2 - Shift phase by +15 degrees - + + Mix output of B2 to B1 + Přimíchat výstup B1 do B2 - Saw wave - Pilovitá vlna - - - - Xpressive - - Selected graph - Zvolený graf + + Modulate amplitude of B1 with output of B2 + Modulovat amplitudu B1 výstupem B2 - A1 - A1 + + Ring-modulate B1 and B2 + Kruhově modulovat B1 a B2 - A2 - A2 + + Modulate phase of B1 with output of B2 + Modulovat fázi B1 výstupem B2 - A3 - A3 - - - W1 smoothing - W1 vyhlazování - - - W2 smoothing - W2 vyhlazování - - - W3 smoothing - W3 vyhlazování - - - Panning 1 - - - - Panning 2 - - - - Rel trans - - - - - XpressiveView - + + + + Draw your own waveform here by dragging your mouse on this graph. - Kreslení vlastní křivky tahem myši na tomto grafu. + Kreslení vlastní křivky tahem myši na tomto grafu. - Select oscillator W1 - Vybrat oscilátor W1 + + Load waveform + Načíst vlnu - Select oscillator W2 - Vybrat oscilátor W2 + + Click to load a waveform from a sample file + Klepněte pro načtení vlny ze souboru samplů - Select oscillator W3 - Vybrat oscilátor W3 + + Phase left + Fáze vlevo - Select output O1 - + + Click to shift phase by -15 degrees + Klepněte pro posun fáze o -15 stupňů - Select output O2 - + + Phase right + Fáze vpravo - Open help window - Otevřít okno nápovědy + + Click to shift phase by +15 degrees + Klepněte pro posun fáze o +15 stupňů + + Normalize + Normalizovat + + + + Click to normalize + Klepněte pro normalizaci + + + + Invert + Převrátit + + + + Click to invert + Klepněte pro převrácení + + + + Smooth + Uhladit + + + + Click to smooth + Klepněte pro vyhlazení + + + Sine wave - Sinusová vlna + Sinusová vlna - Moog-saw wave - - - - Exponential wave - Exponenciální vlna - - - Saw wave - Pilovitá vlna - - - User-defined wave - + + Click for sine wave + Klepněte pro sinusovou vlnu + + Triangle wave - Trojúhelníková vlna + Trojúhelníková vlna + + Click for triangle wave + Klepněte pro trojúhelníkovou vlnu + + + + Click for saw wave + Klepněte pro pilovitou vlnu + + + Square wave - Pravoúhlá vlna + Pravoúhlá vlna - White noise - Bílý šum - - - WaveInterpolate - Interpolace vlnění - - - ExpressionValid - Platnost výrazu - - - General purpose 1: - Celkový účel 1: - - - General purpose 2: - Celkový účel 2: - - - General purpose 3: - Celkový účel 3: - - - O1 panning: - O1 vyvážení: - - - O2 panning: - O2 vyvážení: - - - Release transition: - Přechod mezi uvolněním: - - - Smoothness - Hladkost + + Click for square wave + Klepněte pro pravoúhlou vlnu ZynAddSubFxInstrument + Portamento Portamento + + Filter Frequency + Frekvence filtru + + + + Filter Resonance + Rezonance filtru + + + Bandwidth Šířka pásma - Filter frequency - + + FM Gain + Zesílení FM - Filter resonance - + + Resonance Center Frequency + Střední frekvence rezonance - FM gain - + + Resonance Bandwidth + Šířka pásma rezonance - Resonance center frequency - - - - Resonance bandwidth - - - - Forward MIDI control change events - + + Forward MIDI Control Change Events + Odesílat události MIDI Control Change ZynAddSubFxView - Show GUI - Ukázar grafické rozhraní - - + Portamento: Portamento: + PORT PORT + + Filter Frequency: + Frekvence filtru: + + + FREQ FREKV + + Filter Resonance: + Rezonance filtru: + + + RES REZ + Bandwidth: Šířka pásma: + BW ŠP + + FM Gain: + Zesílení FM: + + + FM GAIN ZISK FM + Resonance center frequency: Střední frekvence rezonance: + RES CF SF REZ + Resonance bandwidth: Šířka pásma rezonance: + RES BW ŠP REZ - Filter frequency: - + + Forward MIDI Control Changes + Odesílat MIDI Control Change - Filter resonance: - + + Show GUI + Ukázar grafické rozhraní - FM gain: - - - - Forward MIDI control changes - + + Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. + Klepněte sem pro zobrazení nebo skrytí grafického uživatelského rozhraní (GUI) ZynAddSubFX. audioFileProcessor + Amplify Zesílení + Start of sample Začátek samplu + End of sample Konec samplu - Reverse sample - Přehrávat pozpátku - - - Stutter - Pokračování v přehrávání samplu při změně noty - - + Loopback point Začátek smyčky + + Reverse sample + Přehrávat pozpátku + + + Loop mode Režim smyčky + + Stutter + Pokračování v přehrávání samplu při změně noty + + + Interpolation mode Režim interpolace + None Žádný + Linear Lineární + Sinc Sinusový + Sample not found: %1 Vzorek nenalezen: %1 @@ -3428,272 +9969,446 @@ bitInvader - Sample length - + + Samplelength + Délka samplu bitInvaderView - Sine wave - Sinusová vlna - - - Triangle wave - Trojúhelníková vlna - - - Saw wave - Pilovitá vlna - - - Square wave - Pravoúhlá vlna - - - Interpolation - Interpolovat - - - Normalize - Normalizovat + + Sample Length + Délka samplu + Draw your own waveform here by dragging your mouse on this graph. Kreslení vlastní křivky tahem myši na tomto grafu. - Sample length - + + Sine wave + Sinusová vlna - White noise - Bílý šum + + Click for a sine-wave. + Klepněte sem pro sinusovou vlnu. - User-defined wave - + + Triangle wave + Trojúhelníková vlna - Smooth waveform - + + Click here for a triangle-wave. + Klepněte sem pro trojúhelníkovou vlnu. + + + + Saw wave + Pilovitá vlna + + + + Click here for a saw-wave. + Klepněte sem pro pilovitou vlnu. + + + + Square wave + Pravoúhlá vlna + + + + Click here for a square-wave. + Klepněte sem pro pravoúhlou vlnu. + + + + White noise wave + Bílý šum + + + + Click here for white-noise. + Klepněte sem pro bílý šum. + + + + User defined wave + Vlna definovaná uživatelem + + + + Click here for a user-defined shape. + Klepněte sem pro uživatelem definovaný tvar. + + + + Smooth + Vyhladit + + + + Click here to smooth waveform. + Klepněte sem pro vyhlazení vlny. + + + + Interpolation + Interpolovat + + + + Normalize + Normalizovat dynProcControlDialog + INPUT VSTUP + Input gain: Zesílení vstupu: + OUTPUT VÝSTUP + Output gain: Zesílení výstupu: + ATTACK NÁBĚH + Peak attack time: Délka náběhu špičky: + RELEASE UVOLNĚNÍ + Peak release time: Délka uvolnění špičky: + + Reset waveform + Obnovení vlny + + + + Click here to reset the wavegraph back to default + Klepněte sem pro obnovení zobrazení křivky zpět do výchozího stavu + + + + Smooth waveform + Vyhlazení vlny + + + + Click here to apply smoothing to wavegraph + Klepněte sem pro vyhlazení křivky + + + + Increase wavegraph amplitude by 1dB + Zvýšení amplitudy křivky o 1 dB + + + + Click here to increase wavegraph amplitude by 1dB + Klepněte sem pro zvýšení amplitudy křivky o 1 dB + + + + Decrease wavegraph amplitude by 1dB + Snížení amplitudy křivky o 1 dB + + + + Click here to decrease wavegraph amplitude by 1dB + Klepněte sem pro snížení amplitudy křivky o 1 dB + + + + Stereomode Maximum + Režim maximálního sterea + + + Process based on the maximum of both stereo channels Zpracování vycházející z maxima obou stereo kanálů + + Stereomode Average + Režim průměru sterea + + + Process based on the average of both stereo channels Zpracování vycházející z průměru obou stereo kanálů + + Stereomode Unlinked + Režim nepropojeného sterea + + + Process each stereo channel independently Zpracování každého stereo kanálu zvlášť - - Reset wavegraph - - - - Smooth wavegraph - - - - Increase wavegraph amplitude by 1 dB - - - - Decrease wavegraph amplitude by 1 dB - - - - Stereo mode: maximum - - - - Stereo mode: average - - - - Stereo mode: unlinked - - dynProcControls + Input gain Zesílení vstupu + Output gain Zesílení výstupu + Attack time Doba náběhu + Release time - Délka uvolnění + Délka doznění + Stereo mode Režim sterea + + fxLineLcdSpinBox + + + Assign to: + Přiřadit k: + + + + New FX Channel + Nový efektový kanál + + + + graphModel + + + Graph + Graf + + kickerInstrument + Start frequency Počáteční frekvence + End frequency Konečná frekvence - Gain - Zisk - - + Length Délka + + Distortion Start + Začátek zkreslení + + + + Distortion End + Konec zkreslení + + + + Gain + Zisk + + + + Envelope Slope + Sklon frekvence + + + Noise Šum + Click Klik + + Frequency Slope + Sklon frekvence + + + Start from note Začít od noty + End to note Skončit na notě - - Start distortion - - - - End distortion - - - - Envelope slope - - - - Frequency slope - - kickerInstrumentView + Start frequency: Počáteční frekvence: + End frequency: Konečná frekvence: + + Frequency Slope: + Sklon frekvence: + + + Gain: Zisk: + + Envelope Length: + Délka obálky: + + + + Envelope Slope: + Sklon obálky: + + + Click: Klik: + Noise: Šum: - Frequency slope: - + + Distortion Start: + Začátek zkreslení: - Envelope length: - - - - Envelope slope: - - - - Start distortion: - - - - End distortion: - + + Distortion End: + Konec zkreslení: ladspaBrowserView + + Available Effects Dostupné efekty + + Unavailable Effects Nedostupné efekty + + Instruments Nástroje + + Analysis Tools Analyzační nástroje + + Don't know Neznámé + + 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. + Toto dialogové okno zobrazuje informace o všech LADSPA pluginech, které bylo LMMS schopno nalézt. Zásuvné moduly jsou rozděleny do pěti kategorií podle portů a názvů. + + +K dispozici jsou ty efekty, které mohou být použity v LMMS. Aby v LMMS bylo možné užít efektu, musí se o efekt skutečně jednat, to znamená, že musí mít oba vstupní a výstupní kanály. LMMS identifikuje vstupní kanál jako audio podle "n" v názvu. Výstupní kanály jsou identifikovány pole označení písmeny "out". Kromě toho efekt musí mít stejný počet vstupů a výstupů a být real time kompatibilní. + +Nedostupné efekty jsou ty, které byly identifikovány jako efekty, ale buď nemají stejný počet vstupních a výstupních kanálů nebo nejsou real time kompatibilní. + +Nástroje jsou pluginy u kterých byly identifikovány pouze výstupní kanály. + +Analyzační nástroje jsou pluginy u kterých byly identifikovány pouze vstupní kanály. + +Neznámé jsou pluginy, pro které nebyly identifikovány žádné vstupní nebo výstupní kanály. + +Poklepáním na kterýkoliv modul se zobrazí informace o portech. + + + Type: Typ: @@ -3701,10 +10416,12 @@ ladspaDescription + Plugins Pluginy + Description Popis @@ -3712,66 +10429,83 @@ ladspaPortDialog + Ports Porty + Name Název + Rate Druh + Direction Směr + Type Typ + Min < Default < Max Min < Výchozí < Max + Logarithmic Logaritmický + SR Dependent SR závislý + Audio Zvuk + Control Ovládání + Input Vstup + Output Výstup + Toggled Zapnuto + Integer Celočíselný + Float S plovoucí čárkou + + Yes Ano @@ -3779,46 +10513,57 @@ lb302Synth + VCF Cutoff Frequency VCF frekvence vypnutí + VCF Resonance VCF rezonance + VCF Envelope Mod VCF modulace obálky + VCF Envelope Decay VCF útlum obálky + Distortion Zkreslení + Waveform Vlna + Slide Decay Útlum sklouznutí + Slide Sklouznutí + Accent Důraz + Dead Dead + 24dB/oct Filter Filtr 24dB/okt @@ -3826,122 +10571,153 @@ lb302SynthView + Cutoff Freq: Frekvence odstřihnutí: + Resonance: Rezonance: + Env Mod: Modulace obálky: + Decay: Útlum: + 303-es-que, 24dB/octave, 3 pole filter 3pólový filtr 303-es-que, 24dB/okt + Slide Decay: Útlum sklouznutí: + DIST: Zkreslení: + Saw wave Pilovitá vlna + Click here for a saw-wave. Klepněte sem pro pilovitou vlnu. + Triangle wave Trojúhelníková vlna + Click here for a triangle-wave. Klepněte sem pro trojúhelníkovou vlnu. + Square wave Pravoúhlá vlna + Click here for a square-wave. Klepněte sem pro pravoúhlou vlnu. + Rounded square wave Oblá pravoúhlá vlna + Click here for a square-wave with a rounded end. Klepněte sem pro pravoúhlou vlnu s oblým zakončením. + Moog wave Vlna typu Moog + Click here for a moog-like wave. Klepněte sem pro vlnu typu Moog. + Sine wave Sinusová vlna + Click for a sine-wave. Klepněte sem pro sinusovou vlnu. + + White noise wave Bílý šum + Click here for an exponential wave. Klepněte sem pro exponenciální vlnu. + Click here for white-noise. Klepněte sem pro bílý šum. + Bandlimited saw wave Pásmově omezená pilovitá vlna + Click here for bandlimited saw wave. Klepněte sem pro pásmově omezenou pilovitou vlnu. + Bandlimited square wave Pásmově zúžená pravoúhlá vlna + Click here for bandlimited square wave. Klepněte sem pro pásmově zúženou pravoúhlou vlnu. + Bandlimited triangle wave Pásmově zúžená trojúhelníková vlna + Click here for bandlimited triangle wave. Klepněte sem pro pásmově zúženou trojúhelníkovou vlnu. + Bandlimited moog saw wave Pásmově zúžená pilovitá vlna typu Moog + Click here for bandlimited moog saw wave. Klepněte sem pro úzkopásmovou pilovitou vlnu typu Moog. @@ -3949,286 +10725,562 @@ malletsInstrument + Hardness Tvrdost + Position Pozice + + Vibrato Gain + Zisk vibráta + + + + Vibrato Freq + Frekvence vibráta + + + + Stick Mix + Mix paliček + + + Modulator Modulátor + Crossfade Prolínání (crossfade) + + LFO Speed + LFO Rychlost + + + + LFO Depth + LFO Hloubka + + + ADSR ADSR + Pressure Tlak + Motion Pohyb + Speed Rychlost + Bowed Smyčcem + Spread Šíře + Marimba Marimba + Vibraphone Vibrafon + Agogo Agogo + + Wood1 + Dřevo1 + + + Reso Rezo + + Wood2 + Dřevo2 + + + Beats Údery + + Two Fixed + Dvě spojené + + + Clump Svazek + + Tubular Bells + Trubicové zvony + + + + Uniform Bar + Obyčejná tyč + + + + Tuned Bar + Laděná tyč + + + Glass Sklo - Vibrato gain - - - - Vibrato frequency - - - - Stick mix - - - - LFO speed - Rychlost LFO - - - LFO depth - - - - Wood 1 - - - - Wood 2 - - - - Two fixed - - - - Tubular bells - - - - Uniform bar - - - - Tuned bar - - - - Tibetan bowl - + + Tibetan Bowl + Tibetská zpívající mísa malletsInstrumentView + Instrument Nástroj + Spread Šíře + Spread: Šíře: - Hardness - Tvrdost - - - Hardness: - Tvrdost: - - - Position - Pozice - - - Position: - Pozice: - - - Modulator - Modulátor - - - Modulator: - Modulátor: - - - Crossfade - Prolínání (crossfade) - - - Crossfade: - Prolínání (crossfade): - - - ADSR - ADSR - - - ADSR: - ADSR: - - - Pressure - Tlak - - - Pressure: - Tlak: - - - Speed - Rychlost - - - Speed: - Rychlost: - - + Missing files Chybějící soubory + Your Stk-installation seems to be incomplete. Please make sure the full Stk-package is installed! Zdá se, že instalace Stk není kompletní. Ujistěte se prosím, že je nainstalován celý balík Stk! - Vibrato gain - + + Hardness + Tvrdost - Vibrato gain: - + + Hardness: + Tvrdost: - Vibrato frequency - + + Position + Pozice - Vibrato frequency: - + + Position: + Pozice: - Stick mix - + + Vib Gain + Vib zisk - Stick mix: - + + Vib Gain: + Vib zisk: - LFO speed - Rychlost LFO + + Vib Freq + Vib frekv - LFO speed: - Rychlost LFO: + + Vib Freq: + Vib frekv: - LFO depth - + + Stick Mix + Mix paliček - LFO depth: - + + Stick Mix: + Mix paliček: + + + + Modulator + Modulátor + + + + Modulator: + Modulátor: + + + + Crossfade + Prolínání (crossfade) + + + + Crossfade: + Prolínání (crossfade): + + + + LFO Speed + LFO Rychlost + + + + LFO Speed: + LFO Rychlost: + + + + LFO Depth + LFO Hloubka + + + + LFO Depth: + LFO Hloubka: + + + + ADSR + ADSR + + + + ADSR: + ADSR: + + + + Pressure + Tlak + + + + Pressure: + Tlak: + + + + Speed + Rychlost + + + + Speed: + Rychlost: manageVSTEffectView + - VST parameter control - řízení parametrů VST + + VST Sync + VST synch + + + + Click here if you want to synchronize all parameters with VST plugin. + Klepněte sem, chcete-li synchronizovat všechny parametry s VST pluginem. + + + + Automated Automaticky + + Click here if you want to display automated parameters only. + Klepněte sem, pokud chcete pouze zobrazit parametry automatizace. + + + Close Zavřít - VST sync - + + Close VST effect knob-controller window. + Zavřít okno otočných ovladačů VST efektu. manageVestigeInstrumentView + + - VST plugin control - ovládání VST pluginu + VST Sync VST synch + + Click here if you want to synchronize all parameters with VST plugin. + Klepněte sem, chcete-li synchronizovat všechny parametry s VST pluginem. + + + + Automated Automaticky + + Click here if you want to display automated parameters only. + Klepněte sem, pokud chcete pouze zobrazit parametry automatizace. + + + Close Zavřít + + + Close VST plugin knob-controller window. + Zavřít okno otočných ovladačů VST pluginu. + + + + opl2instrument + + + Patch + Patch + + + + Op 1 Attack + Op 1 náběh + + + + Op 1 Decay + Op 1 útlum + + + + Op 1 Sustain + Op 1 vydržení + + + + Op 1 Release + Op 1 uvolnění + + + + Op 1 Level + Op 1 úroveň + + + + Op 1 Level Scaling + Op 1 škálování úrovně + + + + Op 1 Frequency Multiple + Op 1 násobení frekvence + + + + Op 1 Feedback + Op 1 zpětná vazba + + + + Op 1 Key Scaling Rate + Op 1 rychlost podle výšky klávesy + + + + Op 1 Percussive Envelope + Op 1 perkusivní obálka + + + + Op 1 Tremolo + Op 1 tremolo + + + + Op 1 Vibrato + Op 1 vibrato + + + + Op 1 Waveform + Op 1 vlna + + + + Op 2 Attack + Op 2 náběh + + + + Op 2 Decay + Op 2 útlum + + + + Op 2 Sustain + Op 2 vydržení + + + + Op 2 Release + Op 2 uvolnění + + + + Op 2 Level + Op 2 úroveň + + + + Op 2 Level Scaling + Op 2 škálování úrovně + + + + Op 2 Frequency Multiple + Op 2 násobení frekvence + + + + Op 2 Key Scaling Rate + Op 2 rychlost podle výšky klávesy + + + + Op 2 Percussive Envelope + Op 2 perkusivní obálka + + + + Op 2 Tremolo + Op 2 tremolo + + + + Op 2 Vibrato + Op 2 vibrato + + + + Op 2 Waveform + Op 2 tvar vlny + + + + FM + FM + + + + Vibrato Depth + Hloubka vibráta + + + + Tremolo Depth + Hloubka tremola + + + + opl2instrumentView + + + + Attack + Náběh + + + + + Decay + Útlum + + + + + Release + Doznění + + + + + Frequency multiplier + Násobič frekvence + organicInstrument + Distortion Zkreslení + Volume Hlasitost @@ -4236,73 +11288,458 @@ organicInstrumentView + Distortion: Zkreslení: + + The distortion knob adds distortion to the output of the instrument. + Otočný ovladač zkreslení přidá zkreslení k výstupu nástroje. + + + Volume: Hlasitost: + + The volume knob controls the volume of the output of the instrument. It is cumulative with the instrument window's volume control. + Otočný ovladač hlasitosti ovládá hlasitost výstupu nástroje. Sčítá se s ovládáním hlasitosti okna nástroje. + + + Randomise Nastavit náhodně + + The randomize button randomizes all knobs except the harmonics,main volume and distortion knobs. + Tlačítko Randomize náhodně nastaví všechny ovladače kromě ovladače harmonických, hlavní hlasitosti a zkreslení. + + + + Osc %1 waveform: Osc %1 vlna: + Osc %1 volume: Osc %1 hlasitost: + Osc %1 panning: Osc %1 panoráma: - cents - centů - - + Osc %1 stereo detuning Osc %1 rozladění sterea + + cents + centů + + + Osc %1 harmonic: Osc %1 harmonické: + + FreeBoyInstrument + + + Sweep time + Trvání sweepu + + + + Sweep direction + Směr sweepu + + + + Sweep RtShift amount + Úroveň pro změnu frekvence sweepu + + + + + Wave Pattern Duty + Pracovní cyklus vlnového patternu + + + + Channel 1 volume + Hlasitost kanálu 1 + + + + + + Volume sweep direction + Směr hlasitosti sweepu + + + + + + Length of each step in sweep + Délka každého kroku ve sweepu + + + + Channel 2 volume + Hlasitost kanálu 2 + + + + Channel 3 volume + Hlasitost kanálu 3 + + + + Channel 4 volume + Hlasitost kanálu 4 + + + + Shift Register width + Posun šířky registru + + + + Right Output level + Úroveň pravého výstupu + + + + Left Output level + Úroveň levého výstupu + + + + Channel 1 to SO2 (Left) + Kanál 1 do SO2 (pravý) + + + + Channel 2 to SO2 (Left) + Kanál 2 do SO2 (pravý) + + + + Channel 3 to SO2 (Left) + Kanál 3 do SO2 (pravý) + + + + Channel 4 to SO2 (Left) + Kanál 4 do SO2 (pravý) + + + + Channel 1 to SO1 (Right) + Kanál 1 do SO1 (pravý) + + + + Channel 2 to SO1 (Right) + Kanál 2 do SO1 (pravý) + + + + Channel 3 to SO1 (Right) + Kanál 3 do SO1 (pravý) + + + + Channel 4 to SO1 (Right) + Kanál 4 do SO1 (pravý) + + + + Treble + Výšky + + + + Bass + Basy + + + + FreeBoyInstrumentView + + + Sweep Time: + Trvání sweepu: + + + + Sweep Time + Trvání sweepu + + + + The amount of increase or decrease in frequency + Množství zvýšení nebo snížení frekvence + + + + Sweep RtShift amount: + Úroveň pro změnu frekvence sweepu: + + + + Sweep RtShift amount + Úroveň pro změnu frekvence sweepu + + + + The rate at which increase or decrease in frequency occurs + Úroveň, při které dojde ke zvýšení nebo snížení frekvence + + + + + Wave pattern duty: + Pracovní cyklus vlnového patternu: + + + + Wave Pattern Duty + Pracovní cyklus vlnového patternu + + + + + The duty cycle is the ratio of the duration (time) that a signal is ON versus the total period of the signal. + Pracovní cyklus je poměr mezi dobou trvání (časem), kdy je signál zapnut, a celkovou délkou signálu. + + + + + Square Channel 1 Volume: + Hlasitost pulzního kanálu 1: + + + + Square Channel 1 Volume + Hlasitost pulzního kanálu 1 + + + + + + Length of each step in sweep: + Délka každého kroku ve sweepu: + + + + + + Length of each step in sweep + Délka každého kroku ve sweepu + + + + + + The delay between step change + Zpoždění mezi změnou kroku + + + + Wave pattern duty + Pracovní cyklus vlnového patternu + + + + Square Channel 2 Volume: + Hlasitost pulzního kanálu 2: + + + + + Square Channel 2 Volume + Hlasitost pulzního kanálu 2 + + + + Wave Channel Volume: + Hlasitost vlnového kanálu: + + + + + Wave Channel Volume + Hlasitost vlnového kanálu + + + + Noise Channel Volume: + Hlasitost šumového kanálu: + + + + + Noise Channel Volume + Hlasitost šumového kanálu + + + + SO1 Volume (Right): + Hlasitost SO1 (pravý): + + + + SO1 Volume (Right) + Hlasitost SO1 (pravý) + + + + SO2 Volume (Left): + Hlasitost SO2 (levý): + + + + SO2 Volume (Left) + Hlasitost SO2 (levý) + + + + Treble: + Výšky: + + + + Treble + Výšky + + + + Bass: + Basy: + + + + Bass + Basy + + + + Sweep Direction + Směr sweepu + + + + + + + + Volume Sweep Direction + Směr hlasitosti sweepu + + + + Shift Register Width + Posun šířky registru + + + + Channel1 to SO1 (Right) + Kanál 1 do SO1 (pravý) + + + + Channel2 to SO1 (Right) + Kanál 2 do SO1 (pravý) + + + + Channel3 to SO1 (Right) + Kanál 3 do SO1 (pravý) + + + + Channel4 to SO1 (Right) + Kanál 4 do SO1 (pravý) + + + + Channel1 to SO2 (Left) + Kanál 1 do SO2 (levý) + + + + Channel2 to SO2 (Left) + Kanál 2 do SO2 (levý) + + + + Channel3 to SO2 (Left) + Kanál 3 do SO2 (levý) + + + + Channel4 to SO2 (Left) + Kanál 4 do SO2 (levý) + + + + Wave Pattern + Vlnový pattern + + + + Draw the wave here + Nakreslete vlnu zde + + patchesDialog + Qsynth: Channel Preset Qsynth: Předvolba kanálu + Bank selector Výběr banky + Bank Banka + Program selector Výběr programu + Patch Patch + Name Název + OK OK + Cancel Zrušit @@ -4310,182 +11747,231 @@ pluginBrowser - Incomplete monophonic imitation tb303 - Nekompletní monofonní imitace tb303 + + no description + bez popisu - Plugin for freely manipulating stereo output - Plugin pro volné úpravy stereo výstupu + + A native amplifier plugin + Nativní plugin zesilovače - Plugin for controlling knobs with sound peaks - Plugin pro řízení otočných ovladačů zvukovými špičkami + + Simple sampler with various settings for using samples (e.g. drums) in an instrument-track + Jednoduchý sampler s bohatým nastavením pro používání samplů (např. bicích nástrojů) v nástrojové stopě - Plugin for enhancing stereo separation of a stereo input file - Plugin pro zlepšení stereo separace vstupních stereo souborů + + Boost your bass the fast and simple way + Zesílení vašeho basu rychlým a snadným způsobem + + Customizable wavetable synthesizer + Upravitelný tabulkový syntezátor + + + + An oversampling bitcrusher + Bitcrusher založený na převzorkování + + + + Carla Patchbay Instrument + Nástroj Carla Patchbay + + + + Carla Rack Instrument + Nástroj Carla Rack + + + + A 4-band Crossover Equalizer + 4 pásmový crossover ekvalizér + + + + A native delay plugin + Nativní plugin delay + + + + A Dual filter plugin + Plugin duální filtr + + + + plugin for processing dynamics in a flexible way + plugin pro flexibilní práci s dynamikou + + + + A native eq plugin + Nativní plugin ekvalizér + + + + A native flanger plugin + Nativní plugin flanger + + + + Player for GIG files + Přehrávač GIG souborů + + + + Filter for importing Hydrogen files into LMMS + Filtr pro import souborů Hydrogen do LMMS + + + + Versatile drum synthesizer + Univerzální syntezátor bicích nástrojů + + + List installed LADSPA plugins Seznam nainstalovaných LADSPA pluginů - GUS-compatible patch instrument - GUS kompatibilní patch instrument - - - Additive Synthesizer for organ-like sounds - Aditivní syntezátor pro zvuky podobné varhanám - - - Tuneful things to bang on - Melodické bicí nástroje - - - VST-host for using VST(i)-plugins within LMMS - VST host pro užití VST(i) pluginů v LMMS - - - Vibrating string modeler - Vibrační modelátor strun - - + plugin for using arbitrary LADSPA-effects inside LMMS. plugin pro užití libovolných LADSPA efektů uvnitř LMMS. + + Incomplete monophonic imitation tb303 + Nekompletní monofonní imitace tb303 + + + + Filter for exporting MIDI-files from LMMS + Filtr pro export souborů MIDI z LMMS + + + Filter for importing MIDI-files into LMMS Filtr pro import MIDI souborů do LMMS + + Monstrous 3-oscillator synth with modulation matrix + 3oscilátorový syntezátor Monstrous s modulační matricí + + + + A multitap echo delay plugin + Plugin multi-tap delay + + + + A NES-like synthesizer + Syntetizér typu NES + + + + 2-operator FM Synth + 2 operátorová FM syntéza + + + + Additive Synthesizer for organ-like sounds + Aditivní syntezátor pro zvuky podobné varhanám + + + + Emulation of GameBoy (TM) APU + Emulace APU GameBoye (TM) + + + + GUS-compatible patch instrument + GUS kompatibilní patch instrument + + + + Plugin for controlling knobs with sound peaks + Plugin pro řízení otočných ovladačů zvukovými špičkami + + + + Reverb algorithm by Sean Costello + Algoritmus dozvuku od Seana Costello + + + + Player for SoundFont files + Přehrávač SoundFont souborů + + + + LMMS port of sfxr + LMMS port sfxr + + + Emulation of the MOS6581 and MOS8580 SID. This chip was used in the Commodore 64 computer. Emulace MOS6581 a MOS8580 SID. Tento čip byl používán v počítačích Commodore 64. - Player for SoundFont files - Přehrávač SoundFont souborů - - - Emulation of GameBoy (TM) APU - Emulace APU GameBoye (TM) - - - Customizable wavetable synthesizer - Upravitelný tabulkový syntezátor - - - Embedded ZynAddSubFX - Vestavěný ZynAddSubFX - - - 2-operator FM Synth - 2 operátorová FM syntéza - - - Filter for importing Hydrogen files into LMMS - Filtr pro import souborů Hydrogen do LMMS - - - LMMS port of sfxr - LMMS port sfxr - - - Monstrous 3-oscillator synth with modulation matrix - 3oscilátorový syntezátor Monstrous s modulační matricí - - - Three powerful oscillators you can modulate in several ways - 3 silné oscilátory, které můžete různými způsoby modulovat - - - A native amplifier plugin - Nativní plugin zesilovače - - - Carla Rack Instrument - Nástroj Carla Rack - - - 4-oscillator modulatable wavetable synth - 4oscilátorový modulovatelný tabulkový syntezátor - - - plugin for waveshaping - plugin pro tvarování vln - - - Boost your bass the fast and simple way - Zesílení vašeho basu rychlým a snadným způsobem - - - Versatile drum synthesizer - Univerzální syntezátor bicích nástrojů - - - Simple sampler with various settings for using samples (e.g. drums) in an instrument-track - Jednoduchý sampler s bohatým nastavením pro používání samplů (např. bicích nástrojů) v nástrojové stopě - - - plugin for processing dynamics in a flexible way - plugin pro flexibilní práci s dynamikou - - - Carla Patchbay Instrument - Nástroj Carla Patchbay - - - plugin for using arbitrary VST effects inside LMMS. - Plugin pro použití libovolného VST efektu v LMMS. - - + Graphical spectrum analyzer plugin Plugin pro grafickou analýzu spektra - A NES-like synthesizer - Syntetizér typu NES + + Plugin for enhancing stereo separation of a stereo input file + Plugin pro zlepšení stereo separace vstupních stereo souborů - A native delay plugin - Nativní plugin delay + + Plugin for freely manipulating stereo output + Plugin pro volné úpravy stereo výstupu - Player for GIG files - Přehrávač GIG souborů + + Tuneful things to bang on + Melodické bicí nástroje - A multitap echo delay plugin - Plugin multi-tap delay + + Three powerful oscillators you can modulate in several ways + 3 silné oscilátory, které můžete různými způsoby modulovat - A native flanger plugin - Nativní plugin flanger + + VST-host for using VST(i)-plugins within LMMS + VST host pro užití VST(i) pluginů v LMMS - An oversampling bitcrusher - Bitcrusher založený na převzorkování + + Vibrating string modeler + Vibrační modelátor strun - A native eq plugin - Nativní plugin ekvalizér + + plugin for using arbitrary VST effects inside LMMS. + Plugin pro použití libovolného VST efektu v LMMS. - A 4-band Crossover Equalizer - 4 pásmový crossover ekvalizér + + 4-oscillator modulatable wavetable synth + 4oscilátorový modulovatelný tabulkový syntezátor - A Dual filter plugin - Plugin duální filtr + + plugin for waveshaping + plugin pro tvarování vln - Filter for exporting MIDI-files from LMMS - Filtr pro export souborů MIDI z LMMS - - - Reverb algorithm by Sean Costello - Algoritmus dozvuku od Seana Costello + + Embedded ZynAddSubFX + Vestavěný ZynAddSubFX Mathematical expression parser @@ -4495,264 +11981,400 @@ Tento čip byl používán v počítačích Commodore 64. sf2Instrument + Bank Banka + Patch Patch + Gain Zisk + Reverb Dozvuk + + Reverb Roomsize + Velikost dozvukového prostoru + + + + Reverb Damping + Útlum dozvuku + + + + Reverb Width + Délka dozvuku + + + + Reverb Level + Úroveň dozvuku + + + Chorus Chorus + + Chorus Lines + Počet linií chorusu + + + + Chorus Level + Úroveň chorusu + + + + Chorus Speed + Rychlost chorusu + + + + Chorus Depth + Hloubka chorusu + + + A soundfont %1 could not be loaded. Soundfont %1 nelze načíst. - - Reverb room size - - - - Reverb damping - - - - Reverb width - - - - Reverb level - - - - Chorus voices - - - - Chorus level - - - - Chorus speed - - - - Chorus depth - - sf2InstrumentView + + Open other SoundFont file + Otevřít jiný SoundFont soubor + + + + Click here to open another SF2 file + Klepněte sem pro otevření jiného SF2 souboru + + + + Choose the patch + Vybrat patch + + + + Gain + Zesílení + + + Apply reverb (if supported) Použít dozvuk (je-li podporován) + + This button enables the reverb effect. This is useful for cool effects, but only works on files that support it. + Tímto tlačítkem zapnete efekt dozvuk (reverb). Ten lze použít pro výborné efekty, ale funguje pouze se soubory, které jej podporují. + + + + Reverb Roomsize: + Velikost dozvukového prostoru: + + + + Reverb Damping: + Útlum dozvuku: + + + + Reverb Width: + Délka dozvuku: + + + + Reverb Level: + Úroveň dozvuku: + + + Apply chorus (if supported) Použít chorus (je-li podporován) + + This button enables the chorus effect. This is useful for cool echo effects, but only works on files that support it. + Tímto tlačítkem zapnete efekt chorus. Ten lze použít pro výborné echo efekty, ale funguje pouze se soubory, které jej podporují. + + + + Chorus Lines: + Počet linií chorusu: + + + + Chorus Level: + Úroveň chorusu: + + + + Chorus Speed: + Rychlost chorusu: + + + + Chorus Depth: + Hloubka chorusu: + + + Open SoundFont file Otevřít SoundFont soubor - Choose patch - - - - Gain: - - - - Room size: - - - - Damping: - - - - Width: - Šířka: - - - Level: - - - - Voices: - - - - Speed: - Rychlost: - - - Depth: - Hloubka: - - - SoundFont Files (*.sf2 *.sf3) - + + SoundFont2 Files (*.sf2) + Soubory SoundFont2 (*.sf2) sfxrInstrument - Wave - + + Wave Form + Vlna sidInstrument + + Cutoff + Oříznutí + + + Resonance Rezonance + Filter type Typ filtru + Voice 3 off Vypnout hlas 3 + Volume Hlasitost + Chip model Model čipu - - Cutoff frequency - Frekvence oříznutí - sidInstrumentView + Volume: Hlasitost: + Resonance: Rezonance: + + Cutoff frequency: Frekvence oříznutí: + + High-Pass filter + Filtr typu horní propust + + + + Band-Pass filter + Filtr typu pásmová propust + + + + Low-Pass filter + Filtr typu dolní propust + + + + Voice3 Off + Vypnout hlas 3 + + + MOS6581 SID MOS6581 SID + MOS8580 SID MOS8580 SID + + Attack: Náběh: + + Attack rate determines how rapidly the output of Voice %1 rises from zero to peak amplitude. + Rychlost náběhu určuje, jak rychle výstup hlasu %1 stoupne z nuly na špičkovou amplitudu. + + + + Decay: Útlum: + + Decay rate determines how rapidly the output falls from the peak amplitude to the selected Sustain level. + Rychlost útlumu (decay) určuje, jak rychle poklesne výstup ze špičky na zvolenou úroveň vydržení (sustain). + + + Sustain: Vydržení: + + Output of Voice %1 will remain at the selected Sustain amplitude as long as the note is held. + Výstup hlasu %1 zůstane na zvolené úrovni Vydržení po celou dobu, kdy bude nota držena. + + + + Release: Uvolnění: + + The output of of Voice %1 will fall from Sustain amplitude to zero amplitude at the selected Release rate. + Výstup hlasu %1 poklesne z úrovně vydržení (sustain) na nulovou amplitudu zvolenou rychlostí uvolnění (release). + + + + Pulse Width: Délka pulzu: + + 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. + Rozlišení šířky pulsu umožňuje plynulé vyhlazení šířky, aby nebylo rozeznatelné krokování. Pulzní vlna na oscilátoru %1 musí být zvolena tak, aby měla slyšitelný efekt. + + + Coarse: Ladění: + + The Coarse detuning allows to detune Voice %1 one octave up or down. + Hrubé rozladění umožní rozladit hlas %1 až o jednu oktávu nahoru nebo dolů. + + + + Pulse Wave + Pulzní vlna + + + + Triangle Wave + Trojúhelníková vlna + + + + SawTooth + Pilovitá vlna + + + Noise Šum + Sync Synch + + Sync synchronizes the fundamental frequency of Oscillator %1 with the fundamental frequency of Oscillator %2 producing "Hard Sync" effects. + Synchronizace synchronizuje základní frekvenci oscilátoru %1 se základní frekvencí oscilátoru %2 pomocí efektu pevné (Hard Sync) synchronizace. + + + + Ring-Mod + Kruhová modulace + + + + Ring-mod replaces the Triangle Waveform output of Oscillator %1 with a "Ring Modulated" combination of Oscillators %1 and %2. + Kruhová modulace nahradí výstup trojúhelníkové vlny na oscilátoru %1 "kruhově modulovanou" kombinací oscilátorů %1 a %2. + + + Filtered Filtrování + + 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. + Pokud je zapnuto filtrování, hlas %1 bude zpracován filtrem. Pokud je filtrování vypnuto, hlas %1 se objeví přímo na výstupu a filtr na něj nebude mít žádný efekt. + + + Test Test - High-pass filter - - - - Band-pass filter - - - - Low-pass filter - - - - Voice 3 off - - - - Pulse wave - - - - Triangle wave - Trojúhelníková vlna - - - Saw wave - Pilovitá vlna - - - Ring modulation - - - - Pulse width: - + + Test, when set, resets and locks Oscillator %1 at zero until Test is turned off. + Test, když je nastaven, resetuje a zablokuje oscilátor %1 na nule, dokud se test nevypne. stereoEnhancerControlDialog - Width: - Šířka: + + WIDE + ŠÍŘKA - WIDTH - + + Width: + Šířka: stereoEnhancerControls + Width Šířka @@ -4760,18 +12382,22 @@ Tento čip byl používán v počítačích Commodore 64. stereoMatrixControlDialog + Left to Left Vol: Levý do levého – hlasitost: + Left to Right Vol: Levý do pravého – hlasitost: + Right to Left Vol: Pravý do levého – hlasitost: + Right to Right Vol: Pravý do pravého – hlasitost: @@ -4779,18 +12405,22 @@ Tento čip byl používán v počítačích Commodore 64. stereoMatrixControls + Left to Left Levý do levého + Left to Right Levý do pravého + Right to Left Pravý do levého + Right to Right Pravý do pravého @@ -4798,191 +12428,373 @@ Tento čip byl používán v počítačích Commodore 64. vestigeInstrument + Loading plugin Načítám plugin - Please wait while loading the VST plugin... - + + Please wait while loading VST-plugin... + Počkejte prosím, než se načte VST plugin... vibed + String %1 volume Hlasitost struny %1 + String %1 stiffness Tvrdost struny %1 + Pick %1 position Místo drnknutí %1 + Pickup %1 position Umístění snímače %1 + + Pan %1 + Pan %1 + + + + Detune %1 + Rozladění %1 + + + + Fuzziness %1 + Roztřepení %1 + + + + Length %1 + Délka %1 + + + Impulse %1 Impulz %1 - String %1 panning - - - - String %1 detune - - - - String %1 fuzziness - - - - String %1 length - - - - String %1 - + + Octave %1 + Oktáva %1 vibedView + + Volume: + Hlasitost: + + + + The 'V' knob sets the volume of the selected string. + Otočný ovladač "V" nastavuje hlasitost vybrané struny. + + + String stiffness: Tvrdost struny: + + 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. + Otočný ovladač "S" nastavuje tvrdost vybrané struny. Tvrdost struny ovlivňuje délku doznívání struny. Čím nižší hodnota, tím déle bude struna znít. + + + Pick position: Místo drnknutí: + + 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. + Otočný ovladač "P" nastavuje místo, ve kterém se na vybrané struně drnkne. Nižší nastavení znamená drnknutí blíže ke kobylce. + + + Pickup position: Pozice snímače: + + 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. + Otočný ovladač "PU" nastavuje umístění snímače pro vybranou strunu. Nižší nastavení znamená snímač blíže u kobylky. + + + + Pan: + Panoráma: + + + + The Pan knob determines the location of the selected string in the stereo field. + Otočný ovladač "Pan" určuje pozici vybrané struny ve stereo prostoru. + + + + Detune: + Rozladění: + + + + 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. + Otočný ovladač "Detune" mění ladění vybrané struny. Hodnoty nižší než nula způsobí plochý zvuk, hodnoty vyšší než nula způsobí ostřejší zvuk. + + + + Fuzziness: + Roztřepení: + + + + 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'. + Otočný ovladač "Slap" přidává ke zvuku vybrané struny jemné roztřepení, které je nejvíce patrné při náběhu tónu, ačkoliv lze také použít pro vytvoření více "kovového" zvuku struny. + + + + Length: + Délka: + + + + 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. + Otočný ovladač "Lenght" nastavuje délku vybrané struny. Delší struny budou znít déle a jasněji, nicméně však spotřebují více CPU cyklů. + + + + Impulse or initial state + Impulz nebo výchozí stav + + + + 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. + Přepínač "IMP" určuje, zda vlna v grafu bude považována za impulz přenášený na strunu drnknutím nebo za počáteční stav struny. + + + Octave Oktáva + + 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. + Volič "Octave" se používá k výběru harmonického tónu, na kterém bude struna znít. Například "-2" znamená, že struna bude znít dvě oktávy pod základním tónem, "F" znamená, že zní základní tón a "6" znamená, že struna bude znít šest oktáv nad základním tónem. + + + Impulse Editor Editor impulzu + + 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. + Editor vlny poskytuje kontrolu nad výchozím stavem nebo impulzem, který je použit k rozvibrování struny. Tlačítka na pravé straně grafu inicializují vlnový průběh vybraného typu. Tlačítko "?" načte vlnu ze souboru – bude načteno pouze prvních 128 vzorků. + +Vlna může být také nakreslena v grafu. + +Tlačítko "S" vyhladí vlnu. + +Tlačítko "N" normalizuje vlnu. + + + + 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. + Vibed simuluje až devět nezávisle vibrujících strun. Volič "String" vám umožní vybrat, kterou strunu budete upravovat. Pomocí voliče "Imp" vyberete, jestli graf představuje impulz nebo výchozí stav struny. Voličem "Octave" vyberete, na kterém harmonickém tónu má struna vibrovat. + +Graf vám umožňuje řízení výchozího stavu nebo impulzu použitého pro nastavení pohybu struny. + +Otočný ovladač "V" řídí hlasitost. Ovladač "S" nastavuje tvrdost struny. Ovladač "P" určuje pozici drnknutí. Ovladač "PU" nastavuje pozici snímače. + +"Pan" a "Detune" snad není třeba vysvětlovat. Ovladač "Slap" přidá ke zvuku struny jemné rozostření. + +Ovladač "Lenght" určuje délku struny. + +LED v pravém dolním rohu editoru vlny určuje, jestli bude struna v aktuálním nástroji aktivní. + + + Enable waveform Zapnout vlnu + + Click here to enable/disable waveform. + Klepněte sem pro zapnutí/vypnutí vlny. + + + String Struna + + 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. + Volič strun se užívá k výběru struny, které bude upravována. Nástroj Vibed může obsahovat maximálně devět nezávisle vibrujících strun. LED v pravém dolním rohu editoru tvaru vlny indikuje, zda je vybraná struna aktivní. + + + Sine wave Sinusová vlna + + Use a sine-wave for current oscillator. + Použít sinusovou vlnu pro aktuální oscilátor. + + + Triangle wave Trojúhelníková vlna + + Use a triangle-wave for current oscillator. + Použít trojúhelníkovou vlnu pro aktuální oscilátor. + + + Saw wave Pilovitá vlna + + Use a saw-wave for current oscillator. + Použít pilovitou vlnu pro aktuální oscilátor. + + + Square wave Pravoúhlá vlna - String volume: - + + Use a square-wave for current oscillator. + Použít pravoúhlou vlnu pro aktuální oscilátor. - String panning: - + + White noise wave + Bílý šum - String detune: - + + Use white-noise for current oscillator. + Použít bílý šum pro aktuální oscilátor. - String fuzziness: - + + User defined wave + Vlna definovaná uživatelem - String length: - + + Use a user-defined waveform for current oscillator. + Použít vlastní vlnu pro aktuální oscilátor. - Impulse - + + Smooth + Vyhladit - Enable/disable string - + + Click here to smooth waveform. + Klepněte sem pro vyhlazení vlny. - White noise - Bílý šum + + Normalize + Normalizovat - User-defined wave - - - - Smooth waveform - - - - Normalize waveform - + + Click here to normalize waveform. + Klepněte sem pro normalizaci vlny. voiceObject + Voice %1 pulse width Hlas %1 šířka pulzu + Voice %1 attack Hlas %1 náběh + Voice %1 decay Hlas %1 útlum + Voice %1 sustain Hlas %1 vydržení + Voice %1 release Hlas %1 uvolnění + Voice %1 coarse detuning Hlas %1 hrubé ladění + Voice %1 wave shape Hlas %1 tvar vlny + Voice %1 sync Hlas %1 synchronizace + Voice %1 ring modulate Hlas %1 kruhová modulace + Voice %1 filtered Hlas %1 filtrování + Voice %1 test Hlas %1 test @@ -4990,53 +12802,85 @@ Tento čip byl používán v počítačích Commodore 64. waveShaperControlDialog + INPUT VSTUP + Input gain: Zesílení vstupu: + OUTPUT VÝSTUP + Output gain: Zesílení výstupu: + + Reset waveform + Obnovení vlny + + + + Click here to reset the wavegraph back to default + Klepněte sem pro obnovení zobrazení křivky zpět do výchozího stavu + + + + Smooth waveform + Vyhlazení vlny + + + + Click here to apply smoothing to wavegraph + Klepněte sem pro vyhlazení křivky + + + + Increase graph amplitude by 1dB + Zvýši amplitudu grafu o 1dB + + + + Click here to increase wavegraph amplitude by 1dB + Klepněte sem pro zvýšení amplitudy křivky o 1 dB + + + + Decrease graph amplitude by 1dB + Snížit amplitudu grafu o 1dB + + + + Click here to decrease wavegraph amplitude by 1dB + Klepněte sem pro snížení amplitudy křivky o 1 dB + + + Clip input - Vstup klipu + Ořezat vstup - Reset wavegraph - - - - Smooth wavegraph - - - - Increase wavegraph amplitude by 1 dB - - - - Decrease wavegraph amplitude by 1 dB - - - - Clip input signal to 0 dB - + + Clip input signal to 0dB + Vstupní úroveň klipu 0dB waveShaperControls + Input gain Zesílení vstupu + Output gain Zesílení výstupu diff --git a/data/locale/en.ts b/data/locale/en.ts index 1c9f2ee8f..f20bfaac2 100644 --- a/data/locale/en.ts +++ b/data/locale/en.ts @@ -1,37 +1,114 @@ + + AboutDialog + + + About LMMS + + + + + LMMS + + + + + Version %1 (%2/%3, Qt %4, %5). + + + + + About + + + + + LMMS - easy music production for everyone. + + + + + Copyright © %1. + + + + + <html><head/><body><p><a href="https://lmms.io"><span style=" text-decoration: underline; color:#33cc33;">https://lmms.io</span></a></p></body></html> + + + + + Authors + + + + + Involved + + + + + Contributors ordered by number of commits: + + + + + Translation + + + + + 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! + + + + + License + + + AmplifierControlDialog + VOL + Volume: + PAN + Panning: + LEFT + Left gain: + RIGHT + Right gain: @@ -39,95 +116,609 @@ AmplifierControls + Volume + Panning + Left gain + Right gain + + AudioAlsaSetupWidget + + + DEVICE + + + + + CHANNELS + + + AudioFileProcessorView + Open sample + Reverse sample + Disable loop + Enable loop + + Enable ping-pong loop + + + + Continue sample playback across notes + Amplify: + Start point: + End point: + Loopback point: - - Enable ping-pong loop - - AudioFileProcessorWaveView + Sample length: + + AudioJack + + + JACK client restarted + + + + + 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. + + + + + JACK server down + + + + + 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. + + + + + CLIENT-NAME + + + + + CHANNELS + + + + + AudioOss + + + DEVICE + + + + + CHANNELS + + + + + AudioPortAudio::setupWidget + + + BACKEND + + + + + DEVICE + + + + + AudioPulseAudio + + + DEVICE + + + + + CHANNELS + + + + + AudioSdl::setupWidget + + + DEVICE + + + + + AudioSndio + + + DEVICE + + + + + CHANNELS + + + + + AudioSoundIo::setupWidget + + + BACKEND + + + + + DEVICE + + + + + AutomatableModel + + + &Reset (%1%2) + + + + + &Copy value (%1%2) + + + + + &Paste value (%1%2) + + + + + &Paste value + + + + + Edit song-global automation + + + + + Remove song-global automation + + + + + Remove all linked controls + + + + + Connected to %1 + + + + + Connected to controller + + + + + Edit connection... + + + + + Remove connection + + + + + Connect to controller... + + + + + AutomationEditor + + + Please open an automation pattern with the context menu of a control! + + + + + Values copied + + + + + All selected values were copied to the clipboard. + + + + + AutomationEditorWindow + + + Play/pause current pattern (Space) + + + + + Stop playing of current pattern (Space) + + + + + Edit actions + + + + + Draw mode (Shift+D) + + + + + Erase mode (Shift+E) + + + + + Flip vertically + + + + + Flip horizontally + + + + + Interpolation controls + + + + + Discrete progression + + + + + Linear progression + + + + + Cubic Hermite progression + + + + + Tension value for spline + + + + + Tension: + + + + + Cut selected values (%1+X) + + + + + Copy selected values (%1+C) + + + + + Paste values from clipboard (%1+V) + + + + + Zoom controls + + + + + Horizontal zooming + + + + + Vertical zooming + + + + + Quantization controls + + + + + Quantization + + + + + + Automation Editor - no pattern + + + + + + Automation Editor - %1 + + + + + Model is already connected to this pattern. + + + + + AutomationPattern + + + Drag a control while pressing <%1> + + + + + AutomationPatternView + + + Open in Automation editor + + + + + Clear + + + + + Reset name + + + + + Change name + + + + + Set/clear record + + + + + Flip Vertically (Visible) + + + + + Flip Horizontally (Visible) + + + + + %1 Connections + + + + + Disconnect "%1" + + + + + Model is already connected to this pattern. + + + + + AutomationTrack + + + Automation track + + + + + BBEditor + + + Beat+Bassline Editor + + + + + Play/pause current beat/bassline (Space) + + + + + Stop playback of current beat/bassline (Space) + + + + + Beat selector + + + + + Track and step actions + + + + + Add beat/bassline + + + + + Add sample-track + + + + + Add automation-track + + + + + Remove steps + + + + + Add steps + + + + + Clone Steps + + + + + BBTCOView + + + Open in Beat+Bassline-Editor + + + + + Reset name + + + + + Change name + + + + + Change color + + + + + Reset color to default + + + + + BBTrack + + + Beat/Bassline %1 + + + + + Clone of %1 + + + BassBoosterControlDialog + FREQ + Frequency: + GAIN + Gain: + RATIO + Ratio: @@ -135,14 +726,17 @@ BassBoosterControls + Frequency + Gain + Ratio @@ -150,78 +744,98 @@ BitcrushControlDialog + IN + OUT + + GAIN + Input gain: + NOISE + Input noise: + Output gain: + CLIP + Output clip: + Rate enabled + Enable sample-rate crushing + Depth enabled + Enable bit-depth crushing + FREQ + Sample rate: + STEREO + Stereo difference: + QUANT + Levels: @@ -229,38 +843,47 @@ BitcrushControls + Input gain + Input noise + Output gain + Output clip + Sample rate + Stereo difference + Levels + Rate enabled + Depth enabled @@ -268,85 +891,243 @@ CarlaInstrumentView + Show GUI + + Controller + + + Controller %1 + + + + + ControllerConnectionDialog + + + Connection Settings + + + + + MIDI CONTROLLER + + + + + Input channel + + + + + CHANNEL + + + + + Input controller + + + + + CONTROLLER + + + + + + Auto Detect + + + + + MIDI-devices to receive MIDI-events from + + + + + USER CONTROLLER + + + + + MAPPING FUNCTION + + + + + OK + + + + + Cancel + + + + + LMMS + + + + + Cycle Detected. + + + + + ControllerRackView + + + Controller Rack + + + + + Add + + + + + Confirm Delete + + + + + Confirm delete? There are existing connection(s) associated with this controller. There is no way to undo. + + + + + ControllerView + + + Controls + + + + + Rename controller + + + + + Enter the new name for this controller + + + + + LFO + + + + + &Remove this controller + + + + + Re&name this controller + + + CrossoverEQControlDialog + Band 1/2 crossover: + Band 2/3 crossover: + Band 3/4 crossover: + Band 1 gain + Band 1 gain: + Band 2 gain + Band 2 gain: + Band 3 gain + Band 3 gain: + Band 4 gain + Band 4 gain: + Band 1 mute + Mute band 1 + Band 2 mute + Mute band 2 + Band 3 mute + Mute band 3 + Band 4 mute + Mute band 4 @@ -354,22 +1135,27 @@ DelayControls + Delay samples + Feedback + LFO frequency + LFO amount + Output gain @@ -377,42 +1163,52 @@ DelayControlsDialog + DELAY + Delay time + FDBK + Feedback amount + RATE + LFO frequency + AMNT + LFO amount + Out gain + Gain @@ -420,50 +1216,68 @@ DualFilterControlDialog + + FREQ + + Cutoff frequency + + RESO + + Resonance + + GAIN + + Gain + MIX + Mix + Filter 1 enabled + Filter 2 enabled + Enable/disable filter 1 + Enable/disable filter 2 @@ -471,305 +1285,763 @@ DualFilterControls + Filter 1 enabled + Filter 1 type + Cutoff frequency 1 + Q/Resonance 1 + Gain 1 + Mix + Filter 2 enabled + Filter 2 type + Cutoff frequency 2 + Q/Resonance 2 + Gain 2 + + Low-pass + + Hi-pass + + Band-pass csg + + Band-pass czpg + + Notch + + All-pass + + Moog + + 2x Low-pass + + RC Low-pass 12 dB/oct + + RC Band-pass 12 dB/oct + + RC High-pass 12 dB/oct + + RC Low-pass 24 dB/oct + + RC Band-pass 24 dB/oct + + RC High-pass 24 dB/oct + + Vocal Formant + + 2x Moog + + SV Low-pass + + SV Band-pass + + SV High-pass + + SV Notch + + Fast Formant + + Tripole + + Editor + + + Transport controls + + + + + Play (Space) + + + + + Stop (Space) + + + + + Record + + + + + Record while playing + + + + + Toggle Step Recording + + + + + Effect + + + Effect enabled + + + + + Wet/Dry mix + + + + + Gate + + + + + Decay + + + + + EffectChain + + + Effects enabled + + + + + EffectRackView + + + EFFECTS CHAIN + + + + + Add effect + + + + + EffectSelectDialog + + + Add effect + + + + + + Name + + + + + Type + + + + + Description + + + + + Author + + + + + EffectView + + + On/Off + + + + + W/D + + + + + Wet Level: + + + + + DECAY + + + + + Time: + + + + + GATE + + + + + Gate: + + + + + Controls + + + + + Move &up + + + + + Move &down + + + + + &Remove this plugin + + + + + EnvelopeAndLfoParameters + + + Env pre-delay + + + + + Env attack + + + + + Env hold + + + + + Env decay + + + + + Env sustain + + + + + Env release + + + + + Env mod amount + + + + + LFO pre-delay + + + + + LFO attack + + + + + LFO frequency + + + + + LFO mod amount + + + + + LFO wave shape + + + + + LFO frequency x 100 + + + + + Modulate env amount + + + + + EnvelopeAndLfoView + + + + DEL + + + + + + Pre-delay: + + + + + + ATT + + + + + + Attack: + + + + + HOLD + + + + + Hold: + + + + + DEC + + + + + Decay: + + + + + SUST + + + + + Sustain: + + + + + REL + + + + + Release: + + + + + + AMT + + + + + + Modulation amount: + + + + + SPD + + + + + Frequency: + + + + + FREQ x 100 + + + + + Multiply LFO frequency by 100 + + + + + MODULATE ENV AMOUNT + + + + + Control envelope amount by this LFO + + + + + ms/LFO: + + + + + Hint + + + + + Drag and drop a sample into this window. + + + EqControls + Input gain + Output gain + Low-shelf gain + Peak 1 gain + Peak 2 gain + Peak 3 gain + Peak 4 gain + High-shelf gain + HP res + Low-shelf res + Peak 1 BW + Peak 2 BW + Peak 3 BW + Peak 4 BW + High-shelf res + LP res + HP freq + Low-shelf freq + Peak 1 freq + Peak 2 freq + Peak 3 freq + Peak 4 freq + High-shelf freq + LP freq + HP active + Low-shelf active + Peak 1 active + Peak 2 active + Peak 3 active + Peak 4 active + High-shelf active + LP active + LP 12 + LP 24 + LP 48 + HP 12 + HP 24 + HP 48 + Low-pass type + High-pass type + Analyse IN + Analyse OUT @@ -777,70 +2049,89 @@ EqControlsDialog + HP + Low-shelf + Peak 1 + Peak 2 + Peak 3 + Peak 4 + High-shelf + LP + Input gain + + + Gain + Output gain + Bandwidth: + Octave + Resonance : + Frequency: + LP group + HP group @@ -848,41 +2139,391 @@ EqHandle + Reso: + BW: + + Freq: + + ExportProjectDialog + + + Export project + + + + + Export as loop (remove extra bar) + + + + + Export between loop markers + + + + + Render Looped Section: + + + + + time(s) + + + + + File format settings + + + + + File format: + + + + + Sampling rate: + + + + + 44100 Hz + + + + + 48000 Hz + + + + + 88200 Hz + + + + + 96000 Hz + + + + + 192000 Hz + + + + + Bit depth: + + + + + 16 Bit integer + + + + + 24 Bit integer + + + + + 32 Bit float + + + + + Stereo mode: + + + + + Mono + + + + + Stereo + + + + + Joint stereo + + + + + Compression level: + + + + + Bitrate: + + + + + 64 KBit/s + + + + + 128 KBit/s + + + + + 160 KBit/s + + + + + 192 KBit/s + + + + + 256 KBit/s + + + + + 320 KBit/s + + + + + Use variable bitrate + + + + + Quality settings + + + + + Interpolation: + + + + + Zero order hold + + + + + Sinc worst (fastest) + + + + + Sinc medium (recommended) + + + + + Sinc best (slowest) + + + + + Oversampling: + + + + + 1x (None) + + + + + 2x + + + + + 4x + + + + + 8x + + + + + Start + + + + + Cancel + + + + + 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! + + + + + Export project to %1 + + + + + ( Fastest - biggest ) + + + + + ( Slowest - smallest ) + + + + + Error + + + + + Error while determining file-encoder device. Please try to choose a different output format. + + + + + Rendering: %1% + + + + + Fader + + + + Set value + + + + + + Please enter a new value between %1 and %2: + + + + + FileBrowser + + + Browser + + + + + Search + + + + + Refresh list + + + + + FileBrowserTreeWidget + + + Send to active instrument-track + + + + + Open in new instrument-track/Song Editor + + + + + Open in new instrument-track/B+B Editor + + + + + Loading sample + + + + + Please wait, loading sample for preview... + + + + + Error + + + + + does not appear to be a valid + + + + + file + + + + + --- Factory files --- + + + FlangerControls + Delay samples + LFO frequency + Seconds + Regen + Noise + Invert @@ -890,46 +2531,57 @@ FlangerControlsDialog + DELAY + Delay time: + RATE + Period: + AMNT + Amount: + FDBK + Feedback amount: + NOISE + White noise amount: + Invert @@ -937,94 +2589,122 @@ FreeBoyInstrument + Sweep time + Sweep direction + Sweep rate shift amount + + Wave pattern duty cycle + Channel 1 volume + + + Volume sweep direction + + + Length of each step in sweep + Channel 2 volume + Channel 3 volume + Channel 4 volume + Shift Register width + Right output level + Left output level + Channel 1 to SO2 (Left) + Channel 2 to SO2 (Left) + Channel 3 to SO2 (Left) + Channel 4 to SO2 (Left) + Channel 1 to SO1 (Right) + Channel 2 to SO1 (Right) + Channel 3 to SO1 (Right) + Channel 4 to SO1 (Right) + Treble + Bass @@ -1032,161 +2712,328 @@ FreeBoyInstrumentView + Sweep time: + Sweep time + Sweep rate shift amount: + Sweep rate shift amount + + Wave pattern duty cycle: + + Wave pattern duty cycle + Square channel 1 volume: + Square channel 1 volume + + + Length of each step in sweep: + + + Length of each step in sweep + Square channel 2 volume: + Square channel 2 volume + Wave pattern channel volume: + Wave pattern 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 + Channel 1 to SO1 (Right) + Channel 2 to SO1 (Right) + Channel 3 to SO1 (Right) + Channel 4 to SO1 (Right) + Channel 1 to SO2 (Left) + Channel 2 to SO2 (Left) + Channel 3 to SO2 (Left) + Channel 4 to SO2 (Left) + Wave pattern graph + + FxLine + + + Channel send amount + + + + + Move &left + + + + + Move &right + + + + + Rename &channel + + + + + R&emove channel + + + + + Remove &unused channels + + + + + FxLineLcdSpinBox + + + Assign to: + + + + + New FX Channel + + + + + FxMixer + + + Master + + + + + + + FX %1 + + + + + Volume + + + + + Mute + + + + + Solo + + + + + FxMixerView + + + FX-Mixer + + + + + FX Fader %1 + + + + + Mute + + + + + Mute this FX channel + + + + + Solo + + + + + Solo FX channel + + + + + FxRoute + + + + Amount to send from channel %1 to channel %2 + + + GigInstrument + Bank + Patch + Gain @@ -1194,537 +3041,2824 @@ GigInstrumentView + + Open GIG file + Choose patch + Gain: + GIG Files (*.gig) + + 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 + + + + + InstrumentFunctionArpeggio + + + Arpeggio + + + + + Arpeggio type + + + + + Arpeggio range + + + + + Cycle steps + + + + + Skip rate + + + + + Miss rate + + + + + Arpeggio time + + + + + Arpeggio gate + + + + + Arpeggio direction + + + + + Arpeggio mode + + + + + Up + + + + + Down + + + + + Up and down + + + + + Down and up + + + + + Random + + + + + Free + + + + + Sort + + + + + Sync + + + + + InstrumentFunctionArpeggioView + + + ARPEGGIO + + + + + RANGE + + + + + Arpeggio range: + + + + + octave(s) + + + + + CYCLE + + + + + Cycle notes: + + + + + note(s) + + + + + SKIP + + + + + Skip rate: + + + + + + + % + + + + + MISS + + + + + Miss rate: + + + + + TIME + + + + + Arpeggio time: + + + + + ms + + + + + GATE + + + + + Arpeggio gate: + + + + + Chord: + + + + + Direction: + + + + + Mode: + + + + + InstrumentFunctionNoteStacking + + + octave + + + + + + Major + + + + + Majb5 + + + + + minor + + + + + minb5 + + + + + sus2 + + + + + sus4 + + + + + aug + + + + + augsus4 + + + + + tri + + + + + 6 + + + + + 6sus4 + + + + + 6add9 + + + + + m6 + + + + + m6add9 + + + + + 7 + + + + + 7sus4 + + + + + 7#5 + + + + + 7b5 + + + + + 7#9 + + + + + 7b9 + + + + + 7#5#9 + + + + + 7#5b9 + + + + + 7b5b9 + + + + + 7add11 + + + + + 7add13 + + + + + 7#11 + + + + + Maj7 + + + + + Maj7b5 + + + + + Maj7#5 + + + + + Maj7#11 + + + + + Maj7add13 + + + + + m7 + + + + + m7b5 + + + + + m7b9 + + + + + m7add11 + + + + + m7add13 + + + + + m-Maj7 + + + + + m-Maj7add11 + + + + + m-Maj7add13 + + + + + 9 + + + + + 9sus4 + + + + + add9 + + + + + 9#5 + + + + + 9b5 + + + + + 9#11 + + + + + 9b13 + + + + + Maj9 + + + + + Maj9sus4 + + + + + Maj9#5 + + + + + Maj9#11 + + + + + m9 + + + + + madd9 + + + + + m9b5 + + + + + m9-Maj7 + + + + + 11 + + + + + 11b9 + + + + + Maj11 + + + + + m11 + + + + + m-Maj11 + + + + + 13 + + + + + 13#9 + + + + + 13b9 + + + + + 13b5b9 + + + + + Maj13 + + + + + m13 + + + + + m-Maj13 + + + + + Harmonic minor + + + + + Melodic minor + + + + + Whole tone + + + + + Diminished + + + + + Major pentatonic + + + + + Minor pentatonic + + + + + Jap in sen + + + + + Major bebop + + + + + Dominant bebop + + + + + Blues + + + + + Arabic + + + + + Enigmatic + + + + + Neopolitan + + + + + Neopolitan minor + + + + + Hungarian minor + + + + + Dorian + + + + + Phrygian + + + + + Lydian + + + + + Mixolydian + + + + + Aeolian + + + + + Locrian + + + + + Minor + + + + + Chromatic + + + + + Half-Whole Diminished + + + + + 5 + + + + + Phrygian dominant + + + + + Persian + + + + + Chords + + + + + Chord type + + + + + Chord range + + + + + InstrumentFunctionNoteStackingView + + + STACKING + + + + + Chord: + + + + + RANGE + + + + + Chord range: + + + + + octave(s) + + + + + InstrumentMidiIOView + + + ENABLE MIDI INPUT + + + + + + CHANNEL + + + + + + VELOCITY + + + + + ENABLE MIDI OUTPUT + + + + + PROGRAM + + + + + NOTE + + + + + MIDI devices to receive MIDI events from + + + + + MIDI devices to send MIDI events to + + + + + CUSTOM BASE VELOCITY + + + + + Specify the velocity normalization base for MIDI-based instruments at 100% note velocity. + + + + + BASE VELOCITY + + + + + InstrumentMiscView + + + MASTER PITCH + + + + + Enables the use of master pitch + + + + + InstrumentSoundShaping + + + VOLUME + + + + + Volume + + + + + CUTOFF + + + + + + Cutoff frequency + + + + + RESO + + + + + Resonance + + + + + Envelopes/LFOs + + + + + Filter type + + + + + Q/Resonance + + + + + Low-pass + + + + + Hi-pass + + + + + Band-pass csg + + + + + Band-pass czpg + + + + + Notch + + + + + All-pass + + + + + Moog + + + + + 2x Low-pass + + + + + RC Low-pass 12 dB/oct + + + + + RC Band-pass 12 dB/oct + + + + + RC High-pass 12 dB/oct + + + + + RC Low-pass 24 dB/oct + + + + + RC Band-pass 24 dB/oct + + + + + RC High-pass 24 dB/oct + + + + + Vocal Formant + + + + + 2x Moog + + + + + SV Low-pass + + + + + SV Band-pass + + + + + SV High-pass + + + + + SV Notch + + + + + Fast Formant + + + + + Tripole + + + + + InstrumentSoundShapingView + + + TARGET + + + + + FILTER + + + + + FREQ + + + + + Cutoff frequency: + + + + + Hz + + + + + Q/RESO + + + + + Q/Resonance: + + + + + 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 + + + + + Base note + + + + + Volume + + + + + Panning + + + + + Pitch + + + + + Pitch range + + + + + FX channel + + + + + Master pitch + + + + + Default preset + + InstrumentTrackView + + + Volume + + + + + Volume: + + + + + VOL + + + + + Panning + + + + + Panning: + + + + + PAN + + + + + MIDI + + + + + Input + + + + + Output + + + + + FX %1: %2 + + + + + InstrumentTrackWindow + + + GENERAL SETTINGS + + + + + 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 + + + + + SAVE + + + + + Envelope, filter & LFO + + + + + Chord stacking & arpeggio + + + + + Effects + + + + + MIDI + + + + + Miscellaneous + + + + + Save preset + + + + + XML preset file (*.xpf) + + + + + Plugin + + + + + Knob + + + Set linear + + + + + Set logarithmic + + + + + + Set value + + + + + Please enter a new value between -96.0 dBFS and 6.0 dBFS: + + + + + Please enter a new value between %1 and %2: + + + + + LadspaControl + + + Link channels + + + LadspaControlDialog + Link Channels + Channel + + LadspaControlView + + + Link channels + + + + + Value: + + + LadspaEffect + Unknown LADSPA plugin %1 requested. + + LcdSpinBox + + + Set value + + + + + Please enter a new value between %1 and %2: + + + + + LeftRightNav + + + + + Previous + + + + + + + Next + + + + + Previous (%1) + + + + + Next (%1) + + + + + LfoController + + + LFO Controller + + + + + Base value + + + + + Oscillator speed + + + + + Oscillator amount + + + + + Oscillator phase + + + + + Oscillator waveform + + + + + Frequency Multiplier + + + + + LfoControllerDialog + + + LFO + + + + + BASE + + + + + Base: + + + + + FREQ + + + + + LFO frequency: + + + + + AMNT + + + + + Modulation amount: + + + + + PHS + + + + + Phase offset: + + + + + degrees + + + + + Sine wave + + + + + Triangle wave + + + + + Saw wave + + + + + Square wave + + + + + Moog saw wave + + + + + Exponential wave + + + + + White noise + + + + + User-defined shape. +Double click to pick a file. + + + + + Mutliply modulation frequency by 1 + + + + + Mutliply modulation frequency by 100 + + + + + Divide modulation frequency by 100 + + + + + LmmsCore + + + Generating wavetables + + + + + Initializing data structures + + + + + Opening audio and midi devices + + + + + Launching mixer threads + + + + + 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 + + + + + Preparing plugin browser + + + + + Preparing file browsers + + + + + My Projects + + + + + My Samples + + + + + My Presets + + + + + My Home + + + + + Root directory + + + + + Volumes + + + + + My Computer + + + + + Loading background artwork + + + + + &File + + + + + &New + + + + + New from template + + + + + &Open... + + + + + &Recently Opened Projects + + + + + &Save + + + + + Save &As... + + + + + Save as New &Version + + + + + Save as default template + + + + + Import... + + + + + E&xport... + + + + + E&xport Tracks... + + + + + Export &MIDI... + + + + + &Quit + + + + + &Edit + + + + + Undo + + + + + Redo + + + + + Settings + + + + + &View + + + + + &Tools + + + + + &Help + + + + + Online Help + + + + + Help + + + + + About + + + + + Create new project + + + + + Create new project from template + + + + + Open existing project + + + + + Recently opened projects + + + + + Save current project + + + + + Export current project + + + + + Metronome + + + + + + Song Editor + + + + + + Beat+Bassline Editor + + + + + + Piano Roll + + + + + + Automation Editor + + + + + + FX Mixer + + + + + Show/hide controller rack + + + + + Show/hide project notes + + + + + 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. + + + + + Controller Rack + + + + + Project Notes + + + + + Volume as dBFS + + + + + Smooth scroll + + + + + Enable note labels in piano roll + + + + + MIDI File (*.mid) + + + + + + untitled + + + + + + Select file for project-export... + + + + + Select directory for writing exported tracks... + + + + + Save project + + + + + 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 + + + + + MeterDialog + + + + Meter Numerator + + + + + Meter numerator + + + + + + Meter Denominator + + + + + Meter denominator + + + + + TIME SIG + + + + + MeterModel + + + Numerator + + + + + Denominator + + + + + MidiController + + + MIDI Controller + + + + + unnamed_midi_controller + + + MidiImport + + Setup incomplete + You have not 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 + + MidiJack + + + JACK server down + When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (title) + + + + + 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 + + + + + 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 + + + + + MidiSetupWidget + + + DEVICE + + + MonstroInstrument + Osc 1 volume + Osc 1 panning + 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 + Osc 2 panning + 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 + Osc 3 panning + 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 + LFO 1 attack + LFO 1 rate + LFO 1 phase + LFO 2 waveform + LFO 2 attack + LFO 2 rate + LFO 2 phase + Env 1 pre-delay + Env 1 attack + 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 + Osc 2+3 modulation + Selected view + Osc 1 - Vol env 1 + Osc 1 - Vol env 2 + Osc 1 - Vol LFO 1 + Osc 1 - Vol LFO 2 + Osc 2 - Vol env 1 + Osc 2 - Vol env 2 + Osc 2 - Vol LFO 1 + Osc 2 - Vol LFO 2 + Osc 3 - Vol env 1 + Osc 3 - Vol env 2 + Osc 3 - Vol LFO 1 + Osc 3 - Vol LFO 2 + Osc 1 - Phs env 1 + Osc 1 - Phs env 2 + Osc 1 - Phs LFO 1 + Osc 1 - Phs LFO 2 + Osc 2 - Phs env 1 + Osc 2 - Phs env 2 + Osc 2 - Phs LFO 1 + Osc 2 - Phs LFO 2 + Osc 3 - Phs env 1 + Osc 3 - Phs env 2 + Osc 3 - Phs LFO 1 + Osc 3 - Phs LFO 2 + Osc 1 - Pit env 1 + Osc 1 - Pit env 2 + Osc 1 - Pit LFO 1 + Osc 1 - Pit LFO 2 + Osc 2 - Pit env 1 + Osc 2 - Pit env 2 + Osc 2 - Pit LFO 1 + Osc 2 - Pit LFO 2 + Osc 3 - Pit env 1 + Osc 3 - Pit env 2 + Osc 3 - Pit LFO 1 + Osc 3 - Pit LFO 2 + Osc 1 - PW env 1 + Osc 1 - PW env 2 + Osc 1 - PW LFO 1 + Osc 1 - PW LFO 2 + Osc 3 - Sub env 1 + Osc 3 - Sub env 2 + Osc 3 - Sub LFO 1 + Osc 3 - Sub LFO 2 + + Sine wave + Bandlimited Triangle wave + Bandlimited Saw wave + Bandlimited Ramp wave + Bandlimited Square wave + Bandlimited Moog saw wave + + Soft square wave + Absolute sine wave + + Exponential wave + White noise + Digital Triangle wave + Digital Saw wave + Digital Ramp wave + Digital Square wave + Digital Moog saw wave + Triangle wave + Saw wave + Ramp wave + Square wave + Moog saw wave + Abs. sine wave + Random + Random smooth @@ -1732,134 +5866,240 @@ MonstroView + Operators view + Matrix view + + + Volume + + + Panning + + + Coarse detune + + + semitones + + Fine tune left + + + + cents + + Fine tune 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 + + Rate + + Phase + + Pre-delay + + Hold + + Decay + + Sustain + + Release + + Slope + Mix osc 2 with osc 3 + Modulate amplitude of osc 3 by osc 2 + Modulate frequency of osc 3 by osc 2 + Modulate phase of osc 3 by osc 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Modulation amount @@ -1867,34 +6107,42 @@ MultitapEchoControlDialog + Length + Step length: + Dry + Dry gain: + Stages + Low-pass stages: + Swap inputs + Swap left and right input channels for reflections @@ -1902,82 +6150,102 @@ NesInstrument + Channel 1 coarse detune + Channel 1 volume + Channel 1 envelope length + Channel 1 duty cycle + Channel 1 sweep amount + Channel 1 sweep rate + Channel 2 Coarse detune + Channel 2 Volume + Channel 2 envelope length + Channel 2 duty cycle + Channel 2 sweep amount + Channel 2 sweep rate + Channel 3 coarse detune + Channel 3 volume + Channel 4 volume + Channel 4 envelope length + Channel 4 noise frequency + Channel 4 noise frequency sweep + Master volume + Vibrato @@ -1985,114 +6253,155 @@ NesInstrumentView + + + + Volume + + + Coarse detune + + + Envelope length + Enable channel 1 + Enable envelope 1 + Enable envelope 1 loop + Enable sweep 1 + + Sweep amount + + Sweep rate + + 12.5% Duty cycle + + 25% Duty cycle + + 50% Duty cycle + + 75% Duty cycle + Enable channel 2 + Enable envelope 2 + Enable envelope 2 loop + Enable sweep 2 + Enable channel 3 + Noise Frequency + Frequency sweep + Enable channel 4 + Enable envelope 4 + Enable envelope 4 loop + Quantize noise frequency when using note frequency + Use note frequency for noise + Noise mode + Master volume + Vibrato @@ -2100,118 +6409,147 @@ OpulenzInstrument + Patch + Op 1 attack + Op 1 decay + Op 1 sustain + Op 1 release + Op 1 level + Op 1 level scaling + Op 1 frequency multiplier + Op 1 feedback + 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 multiplier + Op 2 key scaling rate + Op 2 percussive envelope + Op 2 tremolo + Op 2 vibrato + Op 2 waveform + FM + Vibrato depth + Tremolo depth @@ -2219,18 +6557,26 @@ OpulenzInstrumentView + + Attack + + Decay + + Release + + Frequency multiplier @@ -2238,46 +6584,60 @@ OscillatorObject + Osc %1 waveform + Osc %1 harmonic + + Osc %1 volume + + Osc %1 panning + + 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 + Modulation type %1 @@ -2285,34 +6645,42 @@ PatchesDialog + Qsynth: Channel Preset + Bank selector + Bank + Program selector + Patch + Name + OK + Cancel @@ -2320,93 +6688,189 @@ PatmanView + Open patch + Loop + Loop mode + Tune + Tune mode + No file selected + Open patch file + Patch-Files (*.pat) + + PatternView + + + Open in piano-roll + + + + + Set as ghost in piano-roll + + + + + Clear all notes + + + + + Reset name + + + + + Change name + + + + + Add steps + + + + + Remove steps + + + + + Clone Steps + + + + + 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. + + + + + PeakControllerDialog + + + PEAK + + + + + LFO Controller + + + PeakControllerEffectControlDialog + BASE + Base: + AMNT + Modulation amount: + MULT + Amount multiplicator: + ATCK + Attack: + DCAY + Release: + TRSH + Treshold: + Mute output + Absolute value @@ -2414,120 +6878,633 @@ PeakControllerEffectControls + Base value + Modulation amount + Attack + Release + Treshold + Mute output + Absolute value + Amount multiplicator + + 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: + + + + + 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 + + + + + Record notes from MIDI-device/channel-piano, one step at the time + + + + + Stop playing of current pattern (Space) + + + + + Edit actions + + + + + Draw mode (Shift+D) + + + + + Erase mode (Shift+E) + + + + + Select mode (Shift+S) + + + + + Pitch Bend mode (Shift+T) + + + + + Quantize + + + + + Copy paste controls + + + + + Cut (%1+X) + + + + + Copy (%1+C) + + + + + Paste (%1+V) + + + + + Timeline controls + + + + + Zoom and note controls + + + + + Horizontal zooming + + + + + Quantization + + + + + Note length + + + + + Scale + + + + + Chord + + + + + Clear ghost notes + + + + + + Piano-Roll - %1 + + + + + + Piano-Roll - no pattern + + + + + PianoView + + + Base note + + + + + Plugin + + + Plugin not found + + + + + The plugin "%1" wasn't found or could not be loaded! +Reason: "%2" + + + + + Error while loading plugin + + + + + Failed to load plugin "%1"! + + + + + PluginBrowser + + + Instrument Plugins + + + + + Instrument browser + + + + + Drag an instrument into either the Song-Editor, the Beat+Bassline Editor or into an existing instrument track. + + + + + PluginFactory + + + Plugin not found. + + + + + LMMS plugin %1 does not have a plugin descriptor named %2! + + + + + ProjectNotes + + + Project Notes + + + + + Enter project notes here + + + + + Edit Actions + + + + + &Undo + + + + + %1+Z + + + + + &Redo + + + + + %1+Y + + + + + &Copy + + + + + %1+C + + + + + Cu&t + + + + + %1+X + + + + + &Paste + + + + + %1+V + + + + + Format Actions + + + + + &Bold + + + + + %1+B + + + + + &Italic + + + + + %1+I + + + + + &Underline + + + + + %1+U + + + + + &Left + + + + + %1+L + + + + + C&enter + + + + + %1+E + + + + + &Right + + + + + %1+R + + + + + &Justify + + + + + %1+J + + + + + &Color... + + + + + ProjectRenderer + + + WAV (*.wav) + + + + + FLAC (*.flac) + + + + + OGG (*.ogg) + + + + + MP3 (*.mp3) + + + QWidget + + + Name: + + Maker: + + Copyright: + + Requires Real Time: + + + + + + Yes + + + + + + No + + Real Time Capable: + + In Place Broken: + + Channels In: + + Channels Out: + File: %1 + File: + + RenameDialog + + + Rename... + + + ReverbSCControlDialog + Input + Input gain: + Size + Size: + Color + Color: + Output + Output gain: @@ -2535,268 +7512,1640 @@ ReverbSCControls + Input gain + Size + Color + Output gain - SpectrumAnalyzerControlDialog + SaControls - Linear spectrum + + Pause - Linear Y axis + + Reference freeze + + + + + Waterfall + + + + + Averaging + + + + + Stereo + + + + + Peak hold + + + + + Logarithmic frequency + + + + + Logarithmic amplitude + + + + + Frequency range + + + + + Amplitude range + + + + + FFT block size + + + + + FFT window type + + + + + + Full (auto) + + + + + + Audible + + + + + Bass + + + + + Mids + + + + + High + + + + + Extended + + + + + + Default + + + + + Noise + + + + + (High time res.) + + + + + (High freq. res.) + + + + + Rectangular (Off) + + + + + + Blackman-Harris (Default) + + + + + Hamming + + + + + Hanning - SpectrumAnalyzerControls + SaControlsDialog - Linear spectrum + + Pause - Linear Y axis + + Pause data acquisition - Channel mode + + Reference freeze + + + + + Freeze current input as a reference / disable falloff in peak-hold mode. + + + + + Waterfall + + + + + Display real-time spectrogram + + + + + Averaging + + + + + Enable exponential moving average + + + + + Stereo + + + + + Display stereo channels separately + + + + + Peak hold + + + + + Display envelope of peak values + + + + + Logarithmic frequency + + + + + Switch between logarithmic and linear frequency scale + + + + + + Frequency range + + + + + Logarithmic amplitude + + + + + Switch between logarithmic and linear amplitude scale + + + + + + Amplitude range + + + + + FFT block bize + + + + + FFT block size + + + + + + FFT window type + + + + + 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) + + + + + SampleTCOView + + + Double-click to open sample + + + + + Delete (middle mousebutton) + + + + + Cut + + + + + Copy + + + + + Paste + + + + + Mute/unmute (<%1> + middle click) + + + + + SampleTrack + + + Volume + + + + + Panning + + + + + FX channel + + + + + + Sample track + + + + + SampleTrackView + + + Track volume + + + + + Channel volume: + + + + + VOL + + + + + Panning + + + + + Panning: + + + + + PAN + + + + + FX %1: %2 + + + + + SampleTrackWindow + + + GENERAL SETTINGS + + + + + Sample volume + + + + + Volume: + + + + + VOL + + + + + Panning + + + + + Panning: + + + + + PAN + + + + + FX channel + + + + + FX + + + + + SaveOptionsWidget + + + Discard MIDI connections + + + + + SetupDialog + + + Setup LMMS + + + + + + General settings + + + + + BUFFER SIZE + + + + + + Reset to default value + + + + + MISC + + + + + Use built-in NaN handler + + + + + PLUGIN EMBEDDING + + + + + No embedding + + + + + Embed using Qt API + + + + + Embed using native Win32 API + + + + + Embed using XEmbed protocol + + + + + Keep plugin windows on top when not embedded + + + + + LANGUAGE + + + + + + Paths + + + + + Directories + + + + + + 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 + + + + + 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 + + + + + Song + + + Tempo + + + + + Master volume + + + + + Master pitch + + + + + LMMS Error report + + + + + The following errors occured while loading: + + + + + 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 + + + + + Tempo + + + + + TEMPO + + + + + Tempo in BPM + + + + + High quality mode + + + + + + + Master volume + + + + + + + Master pitch + + + + + Value: %1% + + + + + Value: %1 semitones + + + + + SongEditorWindow + + + Song-Editor + + + + + Play song (Space) + + + + + Record samples from Audio-device + + + + + Record samples from Audio-device while playing song or BB track + + + + + Stop song (Space) + + + + + Track actions + + + + + Add beat/bassline + + + + + Add sample-track + + + + + Add automation-track + + + + + Edit actions + + + + + Draw mode + + + + + Edit mode (select and move) + + + + + Timeline controls + + + + + Zoom controls + + + + + Horizontal zooming + + + + + StepRecorderWidget + + + Hint + + + + + Move recording curser using <Left/Right> arrows + + + + + SubWindow + + + Close + + + + + Maximize + + + + + Restore + + + + + TabWidget + + + + Settings for %1 + + + + + TempoSyncKnob + + + + Tempo Sync + + + + + No Sync + + + + + Eight beats + + + + + Whole note + + + + + Half note + + + + + Quarter note + + + + + 8th note + + + + + 16th note + + + + + 32nd note + + + + + Custom... + + + + + Custom + + + + + 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 + + + Time units + + + + + MIN + + + + + SEC + + + + + MSEC + + + + + BAR + + + + + BEAT + + + + + TICK + + + + + TimeLineWidget + + + Auto scrolling + + + + + Loop points + + + + + After stopping go back to begin + + + + + After stopping go back to position at which playing was started + + + + + After stopping keep position + + + + + + Hint + + + + + Press <%1> to disable magnetic loop points. + + + + + Hold <Shift> to move the begin loop point; Press <%1> to disable magnetic loop points. + + + + + Track + + + Mute + + + + + Solo TrackContainer + + Couldn't import file + + + + + Couldn't find a filter for importing file %1. +You should convert this file into a format supported by LMMS using another software. + + + + + Couldn't open file + + + + + 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! + + + + + Loading project... + + + + + Cancel + + Please wait... + + Loading cancelled + + + + + Project loading was cancelled. + + + + + Loading Track %1 (%2/Total %3) + + + + Importing MIDI-file... + + TrackContentObject + + + Mute + + + + + TrackContentObjectView + + + Current position + + + + + Current length + + + + + + %1:%2 (%3:%4 to %5:%6) + + + + + Press <%1> and drag to make a copy. + + + + + Press <%1> for free resizing. + + + + + Hint + + + + + Delete (middle mousebutton) + + + + + Cut + + + + + Copy + + + + + Paste + + + + + Mute/unmute (<%1> + middle click) + + + + + TrackOperationsWidget + + + Press <%1> while clicking on move-grip to begin a new drag'n'drop action. + + + + + Actions + + + + + + Mute + + + + + + Solo + + + + + 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 + + + TripleOscillatorView + Modulate phase of oscillator 1 by oscillator 2 + Modulate amplitude of oscillator 1 by oscillator 2 + Mix output of oscillators 1 & 2 + Synchronize oscillator 1 with oscillator 2 + Modulate frequency of oscillator 1 by oscillator 2 + Modulate phase of oscillator 2 by oscillator 3 + Modulate amplitude of oscillator 2 by oscillator 3 + Mix output of oscillators 2 & 3 + Synchronize oscillator 2 with oscillator 3 + Modulate frequency of oscillator 2 by oscillator 3 + Osc %1 volume: + Osc %1 panning: + Osc %1 coarse detuning: + semitones + Osc %1 fine detuning left: + + cents + Osc %1 fine detuning right: + Osc %1 phase-offset: + + degrees + Osc %1 stereo phase-detuning: + Sine wave + Triangle wave + Saw wave + Square wave + Moog-like saw wave + Exponential wave + White noise + User-defined wave + + VersionedSaveDialog + + + Increment version number + + + + + Decrement version number + + + + + Save Options + + + + + already exists. Do you want to replace it? + + + VestigeInstrumentView + + Open VST plugin + Control VST plugin from LMMS host + Open VST plugin preset + Previous (-) + Save preset + Next (+) + Show/hide GUI + Turn off all notes + DLL-files (*.dll) + EXE-files (*.exe) + No VST plugin loaded + Preset + by + - VST plugin control + + VisualizationWidget + + + Oscilloscope + + + + + Click to enable + + + VstEffectControlDialog + Show/hide + Control VST plugin from LMMS host + Open VST plugin preset + Previous (-) + Next (+) + Save preset + + Effect by: + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> @@ -2804,54 +9153,69 @@ 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... @@ -2859,118 +9223,147 @@ WatsynInstrument + Volume A1 + Volume A2 + Volume B1 + Volume B2 + Panning A1 + Panning A2 + Panning B1 + Panning 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 + Right detune B1 + Right detune B2 + 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 + B2-B1 modulation + Selected graph @@ -2978,154 +9371,224 @@ WatsynView + + + + Volume + + + + Panning + + + + Freq. multiplier + + + + Left detune + + + + + + + + cents + + + + Right detune + A-B Mix + Mix envelope amount + Mix envelope attack + Mix envelope hold + Mix envelope decay + Crosstalk + Select oscillator A1 + Select oscillator A2 + Select oscillator B1 + Select oscillator B2 + Mix output of A2 to A1 + Modulate amplitude of A1 by output of A2 + Ring modulate A1 and A2 + Modulate phase of A1 by output of A2 + Mix output of B2 to B1 + Modulate amplitude of B1 by output of B2 + Ring modulate B1 and B2 + Modulate phase of B1 by output of B2 + + + + Draw your own waveform here by dragging your mouse on this graph. + Load waveform + Load a waveform from a sample file + Phase left + Shift phase by -15 degrees + Phase right + Shift phase by +15 degrees + + Normalize + + Invert + + Smooth + + Sine wave + + + Triangle wave + Saw wave + + Square wave @@ -3133,42 +9596,52 @@ Xpressive + Selected graph + A1 + A2 + A3 + W1 smoothing + W2 smoothing + W3 smoothing + Panning 1 + Panning 2 + Rel trans @@ -3176,98 +9649,130 @@ XpressiveView + Draw your own waveform here by dragging your mouse on this graph. + Select oscillator W1 + Select oscillator W2 + Select oscillator W3 + Select output O1 + Select output O2 + Open help window + + Sine wave + + Moog-saw wave + + Exponential wave + + Saw wave + + User-defined wave + + Triangle wave + + Square wave + + White noise + WaveInterpolate + ExpressionValid + General purpose 1: + General purpose 2: + General purpose 3: + O1 panning: + O2 panning: + Release transition: + Smoothness @@ -3275,34 +9780,42 @@ ZynAddSubFxInstrument + Portamento + Filter frequency + Filter resonance + Bandwidth + FM gain + Resonance center frequency + Resonance bandwidth + Forward MIDI control change events @@ -3310,66 +9823,82 @@ 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 @@ -3377,50 +9906,62 @@ audioFileProcessor + Amplify + Start of sample + End of sample + Loopback point + Reverse sample + Loop mode + Stutter + Interpolation mode + None + Linear + Sinc + Sample not found: %1 @@ -3428,6 +9969,7 @@ bitInvader + Sample length @@ -3435,46 +9977,64 @@ bitInvaderView + Sample length + Draw your own waveform here by dragging your mouse on this graph. + + Sine wave + + Triangle wave + + Saw wave + + Square wave + + White noise + + User-defined wave + + Smooth waveform + Interpolation + Normalize @@ -3482,74 +10042,96 @@ dynProcControlDialog + INPUT + Input gain: + OUTPUT + Output gain: + ATTACK + Peak attack time: + RELEASE + Peak release time: + + Reset wavegraph + + Smooth wavegraph + + Increase wavegraph amplitude by 1 dB + + Decrease wavegraph amplitude by 1 dB + Stereo mode: maximum + Process based on the maximum of both stereo channels + Stereo mode: average + Process based on the average of both stereo channels + Stereo mode: unlinked + Process each stereo channel independently @@ -3557,73 +10139,98 @@ dynProcControls + Input gain + Output gain + Attack time + Release time + Stereo mode + + graphModel + + + Graph + + + kickerInstrument + Start frequency + End frequency + Length + Start distortion + End distortion + Gain + Envelope slope + Noise + Click + Frequency slope + Start from note + End to note @@ -3631,42 +10238,52 @@ kickerInstrumentView + Start frequency: + End frequency: + Frequency slope: + Gain: + Envelope length: + Envelope slope: + Click: + Noise: + Start distortion: + End distortion: @@ -3674,26 +10291,37 @@ ladspaBrowserView + + Available Effects + + Unavailable Effects + + Instruments + + Analysis Tools + + Don't know + Type: @@ -3701,10 +10329,12 @@ ladspaDescription + Plugins + Description @@ -3712,66 +10342,83 @@ ladspaPortDialog + Ports + Name + Rate + Direction + Type + Min < Default < Max + Logarithmic + SR Dependent + Audio + Control + Input + Output + Toggled + Integer + Float + + Yes @@ -3779,46 +10426,57 @@ lb302Synth + VCF Cutoff Frequency + VCF Resonance + VCF Envelope Mod + VCF Envelope Decay + Distortion + Waveform + Slide Decay + Slide + Accent + Dead + 24dB/oct Filter @@ -3826,122 +10484,153 @@ lb302SynthView + Cutoff Freq: + Resonance: + Env Mod: + Decay: + 303-es-que, 24dB/octave, 3 pole filter + Slide Decay: + DIST: + Saw wave + Click here for a saw-wave. + Triangle wave + Click here for a triangle-wave. + Square wave + Click here for a square-wave. + Rounded square wave + Click here for a square-wave with a rounded end. + Moog wave + Click here for a moog-like wave. + Sine wave + Click for a sine-wave. + + White noise wave + Click here for an exponential wave. + Click here for white-noise. + 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. @@ -3949,118 +10638,147 @@ malletsInstrument + Hardness + Position + Vibrato gain + Vibrato frequency + Stick mix + Modulator + Crossfade + LFO speed + LFO depth + ADSR + Pressure + Motion + Speed + Bowed + Spread + Marimba + Vibraphone + Agogo + Wood 1 + Reso + Wood 2 + Beats + Two fixed + Clump + Tubular bells + Uniform bar + Tuned bar + Glass + Tibetan bowl @@ -4068,118 +10786,147 @@ malletsInstrumentView + Instrument + Spread + Spread: + Missing files + Your Stk-installation seems to be incomplete. Please make sure the full Stk-package is installed! + Hardness + Hardness: + Position + Position: + Vibrato gain + Vibrato gain: + Vibrato frequency + Vibrato frequency: + Stick mix + Stick mix: + Modulator + Modulator: + Crossfade + Crossfade: + LFO speed + LFO speed: + LFO depth + LFO depth: + ADSR + ADSR: + Pressure + Pressure: + Speed + Speed: @@ -4187,18 +10934,23 @@ manageVSTEffectView + - VST parameter control + VST sync + + Automated + Close @@ -4206,18 +10958,24 @@ manageVestigeInstrumentView + + - VST plugin control + VST Sync + + Automated + Close @@ -4225,10 +10983,12 @@ organicInstrument + Distortion + Volume @@ -4236,38 +10996,48 @@ organicInstrumentView + Distortion: + Volume: + Randomise + + Osc %1 waveform: + Osc %1 volume: + Osc %1 panning: + Osc %1 stereo detuning + cents + Osc %1 harmonic: @@ -4275,34 +11045,42 @@ patchesDialog + Qsynth: Channel Preset + Bank selector + Bank + Program selector + Patch + Name + OK + Cancel @@ -4310,242 +11088,306 @@ pluginBrowser + + no description + + + + A native amplifier plugin + Simple sampler with various settings for using samples (e.g. drums) in an instrument-track + Boost your bass the fast and simple way + Customizable wavetable synthesizer + An oversampling bitcrusher + Carla Patchbay Instrument + Carla Rack Instrument + A 4-band Crossover Equalizer + A native delay plugin + A Dual filter plugin + plugin for processing dynamics in a flexible way + A native eq plugin + A native flanger plugin + Emulation of GameBoy (TM) APU + Player for GIG files + Filter for importing Hydrogen files into LMMS + Versatile drum synthesizer + List installed LADSPA plugins + plugin for using arbitrary LADSPA-effects inside LMMS. + Incomplete monophonic imitation tb303 + Filter for exporting MIDI-files from LMMS + Filter for importing MIDI-files into LMMS + Monstrous 3-oscillator synth with modulation matrix + A multitap echo delay plugin + A NES-like synthesizer + 2-operator FM Synth + Additive Synthesizer for organ-like sounds + GUS-compatible patch instrument + Plugin for controlling knobs with sound peaks + Reverb algorithm by Sean Costello + Player for SoundFont files + LMMS port of sfxr + Emulation of the MOS6581 and MOS8580 SID. This chip was used in the Commodore 64 computer. - Graphical spectrum analyzer plugin - - - + Plugin for enhancing stereo separation of a stereo input file + Plugin for freely manipulating stereo output + Tuneful things to bang on + Three powerful oscillators you can modulate in several ways + VST-host for using VST(i)-plugins within LMMS + Vibrating string modeler + plugin for using arbitrary VST effects inside LMMS. + 4-oscillator modulatable wavetable synth + plugin for waveshaping + Mathematical expression parser + Embedded ZynAddSubFX + + + A graphical spectrum analyzer. + + sf2Instrument + Bank + Patch + Gain + Reverb + Reverb room size + Reverb damping + Reverb width + Reverb level + Chorus + Chorus voices + Chorus level + Chorus speed + Chorus depth + A soundfont %1 could not be loaded. @@ -4553,54 +11395,69 @@ This chip was used in the Commodore 64 computer. sf2InstrumentView + + Open SoundFont file + Choose patch + Gain: + Apply reverb (if supported) + Room size: + Damping: + Width: + + Level: + Apply chorus (if supported) + Voices: + Speed: + Depth: + SoundFont Files (*.sf2 *.sf3) @@ -4608,6 +11465,7 @@ This chip was used in the Commodore 64 computer. sfxrInstrument + Wave @@ -4615,26 +11473,32 @@ This chip was used in the Commodore 64 computer. sidInstrument + Cutoff frequency + Resonance + Filter type + Voice 3 off + Volume + Chip model @@ -4642,98 +11506,126 @@ This chip was used in the Commodore 64 computer. sidInstrumentView + Volume: + Resonance: + + Cutoff frequency: + High-pass filter + Band-pass filter + Low-pass filter + Voice 3 off + MOS6581 SID + MOS8580 SID + + Attack: + + Decay: + Sustain: + + Release: + Pulse Width: + Coarse: + Pulse wave + Triangle wave + Saw wave + Noise + Sync + Ring modulation + Filtered + Test + Pulse width: @@ -4741,10 +11633,12 @@ This chip was used in the Commodore 64 computer. stereoEnhancerControlDialog + WIDTH + Width: @@ -4752,6 +11646,7 @@ This chip was used in the Commodore 64 computer. stereoEnhancerControls + Width @@ -4759,18 +11654,22 @@ This chip was used in the Commodore 64 computer. stereoMatrixControlDialog + Left to Left Vol: + Left to Right Vol: + Right to Left Vol: + Right to Right Vol: @@ -4778,29 +11677,52 @@ This chip was used in the Commodore 64 computer. stereoMatrixControls + Left to Left + Left to Right + Right to Left + Right to Right + + testcontext + + + + test string + + + + + + test plural %n + + + + + vestigeInstrument + Loading plugin + Please wait while loading the VST plugin... @@ -4808,42 +11730,52 @@ This chip was used in the Commodore 64 computer. vibed + String %1 volume + String %1 stiffness + Pick %1 position + Pickup %1 position + String %1 panning + String %1 detune + String %1 fuzziness + String %1 length + Impulse %1 + String %1 @@ -4851,90 +11783,120 @@ This chip was used in the Commodore 64 computer. vibedView + String volume: + String stiffness: + Pick position: + Pickup position: + String panning: + String detune: + String fuzziness: + String length: + Impulse + Octave + Impulse Editor + Enable waveform + Enable/disable string + String + + Sine wave + + Triangle wave + + Saw wave + + Square wave + + White noise + + User-defined wave + + Smooth waveform + + Normalize waveform @@ -4942,46 +11904,57 @@ This chip was used in the Commodore 64 computer. voiceObject + Voice %1 pulse width + Voice %1 attack + Voice %1 decay + Voice %1 sustain + Voice %1 release + Voice %1 coarse detuning + Voice %1 wave shape + Voice %1 sync + Voice %1 ring modulate + Voice %1 filtered + Voice %1 test @@ -4989,42 +11962,56 @@ This chip was used in the Commodore 64 computer. waveShaperControlDialog + INPUT + Input gain: + OUTPUT + Output gain: + + Reset wavegraph + + Smooth wavegraph + + Increase wavegraph amplitude by 1 dB + + Decrease wavegraph amplitude by 1 dB + Clip input + Clip input signal to 0 dB @@ -5032,10 +12019,12 @@ This chip was used in the Commodore 64 computer. waveShaperControls + Input gain + Output gain diff --git a/data/locale/ko.ts b/data/locale/ko.ts index 796ccb3c2..a6b450a9e 100644 --- a/data/locale/ko.ts +++ b/data/locale/ko.ts @@ -1,15 +1,74 @@ + + AboutDialog + + About LMMS + LMMS에 대하여 + + + LMMS + LMMS + + + About + 정보 + + + Authors + 개발자 + + + Involved + 기여자 + + + Contributors ordered by number of commits: + 기여자 (기여 순으로 정렬): + + + Translation + 번역 + + + License + 라이선스 + + + Version %1 (%2/%3, Qt %4, %5). + 버전 %1 (%2/%3, Qt %4, %5). + + + LMMS - easy music production for everyone. + LMMS - 누구나 쉽게 할 수 있는 음악 제작. + + + Copyright © %1. + Copyright © %1. + + + <html><head/><body><p><a href="https://lmms.io"><span style=" text-decoration: underline; color:#33cc33;">https://lmms.io</span></a></p></body></html> + <html><head/><body><p><a href="https://lmms.io"><span style=" text-decoration: underline; color:#33cc33;">https://lmms.io</span></a></p></body></html> + + + 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! + 송현진 (Hyunjin Song) <tteu.ingog@gmail.com> +방성범 (Bang Seongbeom) <bangseongbeom@gmail.com> + +LMMS를 다른 언어로 번역하고 싶다거나 기존 번역을 개선하고 싶다면 저희를 도와주세요! LMMS 관리자와의 연락을 통해 참여하실 수 있습니다. + + AmplifierControlDialog VOL - 볼륨 + 음량 Volume: - 볼륨: + 음량: PAN @@ -40,7 +99,7 @@ AmplifierControls Volume - 볼륨 + 음량 Panning @@ -55,20 +114,23 @@ 오른쪽 이득 + + AudioAlsaSetupWidget + + DEVICE + 장치 + + + CHANNELS + 채널 + + AudioFileProcessorView Reverse sample 샘플 역으로 - - Amplify: - 증폭: - - - Continue sample playback across notes - 샘플을 여러 음표에 걸쳐 계속 재생 - Disable loop 반복 비활성화 @@ -77,25 +139,33 @@ Enable loop 반복 활성화 + + Continue sample playback across notes + 샘플을 여러 음표에 걸쳐 계속 재생 + + + Amplify: + 증폭: + Loopback point: 루프 시작점: Open sample - + 샘플 열기 Enable ping-pong loop - + 양방향 반복 활성화 Start point: - + 시작점: End point: - + 끝점: @@ -105,6 +175,398 @@ 샘플 길이: + + AudioJack + + JACK client restarted + JACK 클라이언트 다시 시작됨 + + + 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와 JACK과의 연결이 끊겼습니다. LMMS의 JACK 드라이버를 다시 시작합니다. 수동으로 연결을 시도할 수도 있습니다. + + + JACK server down + JACK 서버 다운됨 + + + 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. + JACK 서버가 종료된 것 같습니다. 더 이상 작업을 진행할 수 없습니다. 프로젝트를 저장한 뒤 JACK과 LMMS를 다시 시작하세요. + + + CLIENT-NAME + 클라이언트 이름 + + + CHANNELS + 채널 + + + + AudioOss + + DEVICE + 장치 + + + CHANNELS + 채널 + + + + AudioPortAudio::setupWidget + + BACKEND + 드라이버 + + + DEVICE + 장치 + + + + AudioPulseAudio + + DEVICE + 장치 + + + CHANNELS + 채널 + + + + AudioSdl::setupWidget + + DEVICE + 장치 + + + + AudioSndio + + DEVICE + 장치 + + + CHANNELS + 채널 + + + + AudioSoundIo::setupWidget + + BACKEND + 드라이버 + + + DEVICE + 장치 + + + + AutomatableModel + + &Reset (%1%2) + 초기화 (%1%2)(&R) + + + &Copy value (%1%2) + 값 복사 (%1%2)(&C) + + + &Paste value (%1%2) + 값 붙여넣기 (%1%2)(&P) + + + Edit song-global automation + 전역 오토메이션 편집 + + + Remove song-global automation + 전역 오토메이션 제거 + + + Remove all linked controls + 연결 제거 + + + Connected to %1 + %1에 연결됨 + + + Connected to controller + 컨트롤러에 연결됨 + + + Edit connection... + 연결 편집... + + + Remove connection + 연결 제거 + + + Connect to controller... + 컨트롤러에 연결... + + + &Paste value + 값 붙여넣기(&P) + + + + AutomationEditor + + Please open an automation pattern with the context menu of a control! + 컨트롤의 컨텍스트 메뉴에서 오토메이션 패턴을 여시기 바랍니다! + + + Values copied + 값 복사됨 + + + All selected values were copied to the clipboard. + 선택한 모든 값이 클립보드에 복사되었습니다. + + + + AutomationEditorWindow + + Play/pause current pattern (Space) + 현재 패턴 재생/일시정지 (Space) + + + Stop playing of current pattern (Space) + 현재 패턴 정지 (Space) + + + Edit actions + 편집 동작 + + + Draw mode (Shift+D) + 그리기 모드 (Shift+D) + + + Erase mode (Shift+E) + 지우기 모드 (Shift+E) + + + Flip vertically + 상하 반전 + + + Flip horizontally + 좌우 반전 + + + Interpolation controls + + + + Discrete progression + 이산적 진행 + + + Linear progression + 선형 진행 + + + Cubic Hermite progression + 3차 에르미트 진행 + + + Tension value for spline + + + + Tension: + 장력: + + + Cut selected values (%1+X) + 선택된 값 잘라내기 (%1+X) + + + Copy selected values (%1+C) + 선택된 값 복사 (%1+C) + + + Paste values from clipboard (%1+V) + 선택된 값 붙여넣기 (%1+V) + + + Zoom controls + + + + Quantization controls + + + + Quantization + + + + Automation Editor - no pattern + 오토메이션 편집기 - 패턴 없음 + + + Automation Editor - %1 + 오토메이션 편집기 - %1 + + + Model is already connected to this pattern. + 대상이 이미 패턴에 연결되어 있습니다. + + + Horizontal zooming + + + + Vertical zooming + + + + + AutomationPattern + + Drag a control while pressing <%1> + <%1> 키를 누른 채로 드래그 + + + + AutomationPatternView + + Open in Automation editor + 오토메이션 편집기에서 열기 + + + Clear + 지우기 + + + Reset name + 이름 초기화 + + + Change name + 이름 바꾸기 + + + Set/clear record + 녹음 설정/해제 + + + Flip Vertically (Visible) + 상하 반전 + + + Flip Horizontally (Visible) + 좌우 반전 + + + %1 Connections + %1개의 연결 + + + Disconnect "%1" + "%1" 연결 해제 + + + Model is already connected to this pattern. + 대상이 이미 패턴과 연결되어 있습니다. + + + + AutomationTrack + + Automation track + 오토메이션 트랙 + + + + BBEditor + + Beat+Bassline Editor + 비트/베이스 라인 편집기 + + + Play/pause current beat/bassline (Space) + 현재 비트/베이스 라인 재생/일시정지 (Space) + + + Stop playback of current beat/bassline (Space) + 현재 비트/베이스 라인 정지 (Space) + + + Beat selector + 비트 선택기 + + + Track and step actions + + + + Add beat/bassline + 비트/베이스 라인 추가 + + + Add sample-track + 샘플 트랙 추가 + + + Add automation-track + 오토메이션 트랙 추가 + + + Remove steps + + + + Add steps + + + + Clone Steps + + + + + BBTCOView + + Open in Beat+Bassline-Editor + 비트/베이스 라인 편집기에서 열기 + + + Reset name + 이름 초기화 + + + Change name + 이름 바꾸기 + + + Change color + 색상 바꾸기 + + + Reset color to default + 색상을 기본값으로 되돌리기 + + + + BBTrack + + Beat/Bassline %1 + 비트/베이스 라인 %1 + + + Clone of %1 + %1의 복제 + + BassBoosterControlDialog @@ -125,11 +587,11 @@ RATIO - + 비율 Ratio: - + 비율: @@ -144,7 +606,7 @@ Ratio - + 비율 @@ -161,41 +623,41 @@ GAIN 이득 - - CLIP - - - - Sample rate: - 샘플 레이트: - - - Stereo difference: - - - - Levels: - - NOISE 잡음 + + CLIP + 클리핑 + FREQ 주파수 + + Sample rate: + 샘플 레이트: + STEREO 스테레오 + + Stereo difference: + 좌우 차이: + QUANT + + Levels: + + Input gain: - 입력 이득: + 입력 이득: Input noise: @@ -203,7 +665,7 @@ Output gain: - 출력 이득: + 출력 이득: Output clip: @@ -230,7 +692,7 @@ BitcrushControls Input gain - 입력 이득 + 입력 이득 Input noise @@ -238,7 +700,7 @@ Output gain - 출력 이득 + 출력 이득 Output clip @@ -272,6 +734,118 @@ GUI 표시 + + Controller + + Controller %1 + 컨트롤러 %1 + + + + ControllerConnectionDialog + + Connection Settings + 연결 설정 + + + MIDI CONTROLLER + MIDI 컨트롤러 + + + Input channel + 입력 채널 + + + CHANNEL + 채널 + + + Input controller + 입력 컨트롤러 + + + CONTROLLER + 컨트롤러 + + + Auto Detect + 자동 감지 + + + MIDI-devices to receive MIDI-events from + + + + USER CONTROLLER + 사용자 지정 컨트롤러 + + + MAPPING FUNCTION + 매핑 함수 + + + OK + 확인 + + + Cancel + 취소 + + + LMMS + LMMS + + + Cycle Detected. + 순환 연결이 감지되었습니다. + + + + ControllerRackView + + Controller Rack + 컨트롤러 랙 + + + Add + 추가 + + + Confirm Delete + 삭제 확인 + + + Confirm delete? There are existing connection(s) associated with this controller. There is no way to undo. + 정말 삭제하시겠습니까? 이 컨트롤러와의 연결이 존재합니다. 이 동작은 취소할 수 없습니다. + + + + ControllerView + + Controls + 컨트롤 + + + Rename controller + 컨트롤러 이름 바꾸기 + + + Enter the new name for this controller + 컨트롤러의 새 이름을 입력하세요 + + + LFO + LFO + + + &Remove this controller + 컨트롤러 제거(&R) + + + Re&name this controller + 컨트롤러 이름 바꾸기(&N) + + CrossoverEQControlDialog @@ -367,7 +941,7 @@ LFO frequency - + LFO 주파수 LFO amount @@ -376,17 +950,13 @@ DelayControlsDialog - - Gain - 이득 - DELAY - + 지연 FDBK - + 피드백 RATE @@ -396,6 +966,10 @@ AMNT + + Gain + 이득 + Delay time @@ -414,19 +988,11 @@ Out gain - + 출력 이득 DualFilterControlDialog - - Filter 1 enabled - 필터 1 활성화됨 - - - Filter 2 enabled - 필터 2 활성화됨 - FREQ 주파수 @@ -459,6 +1025,14 @@ Mix + + Filter 1 enabled + 필터 1 활성화됨 + + + Filter 2 enabled + 필터 2 활성화됨 + Enable/disable filter 1 @@ -480,11 +1054,11 @@ Q/Resonance 1 - + 필터 1 Q/공명 Gain 1 - + 이득 1 Mix @@ -500,27 +1074,27 @@ Q/Resonance 2 - + Q/공명 2 Gain 2 - + 이득 2 Notch - + 노치 Moog - + Moog 2x Moog - + 2x Moog SV Notch - + SV 노치 Fast Formant @@ -603,6 +1177,294 @@ + + Editor + + Transport controls + + + + Play (Space) + 재생 (Space) + + + Stop (Space) + 정지 (Space) + + + Record + 녹음 + + + Record while playing + 재생하면서 녹음 + + + Toggle Step Recording + + + + + Effect + + Effect enabled + 효과 활성화됨 + + + Wet/Dry mix + + + + Gate + 게이트 + + + Decay + + + + + EffectChain + + Effects enabled + 효과 활성화됨 + + + + EffectRackView + + EFFECTS CHAIN + 효과 체인 + + + Add effect + 효과 추가 + + + + EffectSelectDialog + + Add effect + 효과 추가 + + + Name + 이름 + + + Type + 형태 + + + Description + 요약 + + + Author + 개발자 + + + + EffectView + + On/Off + 켬/끔 + + + W/D + + + + Wet Level: + + + + DECAY + + + + Time: + + + + GATE + 게이트 + + + Gate: + 게이트: + + + Controls + 컨트롤 + + + Move &up + 위로 이동(&U) + + + Move &down + 아래로 이동(&D) + + + &Remove this plugin + 플러그인 제거(&R) + + + + EnvelopeAndLfoParameters + + Env pre-delay + + + + Env attack + + + + Env hold + + + + Env decay + + + + Env sustain + + + + Env release + + + + Env mod amount + + + + LFO pre-delay + + + + LFO attack + + + + LFO frequency + + + + LFO mod amount + + + + LFO wave shape + + + + LFO frequency x 100 + + + + Modulate env amount + + + + + EnvelopeAndLfoView + + DEL + + + + ATT + + + + Attack: + + + + HOLD + + + + Hold: + + + + DEC + 감쇠 + + + Decay: + 감쇠: + + + SUST + + + + Sustain: + + + + REL + + + + Release: + + + + AMT + + + + Modulation amount: + + + + SPD + 속도 + + + FREQ x 100 + 주파수 x 100 + + + ms/LFO: + ms/LFO: + + + Hint + + + + Pre-delay: + + + + Frequency: + 주파수: + + + Multiply LFO frequency by 100 + + + + MODULATE ENV AMOUNT + + + + Control envelope amount by this LFO + + + + Drag and drop a sample into this window. + + + EqControls @@ -615,67 +1477,67 @@ Peak 1 gain - + 피크 1 이득 Peak 2 gain - + 피크 2 이득 Peak 3 gain - + 피크 3 이득 Peak 4 gain - + 피크 4 이득 HP res - + 고역 필터 공명 Peak 1 BW - + 피크 1 대역폭 Peak 2 BW - + 피크 2 대역폭 Peak 3 BW - + 피크 3 대역폭 Peak 4 BW - + 피크 4 대역폭 LP res - + 저역 필터 공명 HP freq - + 고역 필터 주파수 Peak 1 freq - + 피크 1 주파수 Peak 2 freq - + 피크 2 주파수 Peak 3 freq - + 피크 3 주파수 Peak 4 freq - + 피크 4 주파수 LP freq - + 저역 필터 주파수 HP active @@ -683,19 +1545,19 @@ Peak 1 active - + 피크 1 활성화 Peak 2 active - + 피크 2 활성화 Peak 3 active - + 피크 3 활성화 Peak 4 active - + 피크 4 활성화 LP active @@ -703,27 +1565,27 @@ LP 12 - + LP 12 LP 24 - + LP 24 LP 48 - + LP 48 HP 12 - + HP 12 HP 24 - + HP 24 HP 48 - + HP 48 Analyse IN @@ -782,19 +1644,19 @@ Peak 1 - + 피크 1 Peak 2 - + 피크 2 Peak 3 - + 피크 3 Peak 4 - + 피크 4 LP @@ -806,20 +1668,20 @@ Bandwidth: - + 대역폭: + + + Octave + 옥타브 Resonance : - 공명: + 공명 : Frequency: 주파수: - - Octave - 옥타브 - Low-shelf @@ -849,15 +1711,289 @@ EqHandle Reso: - 공명: + 공명: BW: - 대역폭: + 대역폭: Freq: - 주파수: + 주파수: + + + + ExportProjectDialog + + Export project + 프로젝트 내보내기 + + + File format: + 파일 형식: + + + 44100 Hz + 44100 Hz + + + 48000 Hz + 48000 Hz + + + 88200 Hz + 88200 Hz + + + 96000 Hz + 96000 Hz + + + 192000 Hz + 192000 Hz + + + Stereo mode: + 스테레오 모드: + + + Stereo + 스테레오 + + + Mono + 모노 + + + Bitrate: + 비트 레이트: + + + 64 KBit/s + 64 KBit/s + + + 128 KBit/s + 128 KBit/s + + + 160 KBit/s + 160 KBit/s + + + 192 KBit/s + 192 KBit/s + + + 256 KBit/s + 256 KBit/s + + + 320 KBit/s + 320 KBit/s + + + Use variable bitrate + 가변 비트레이트 사용 + + + Quality settings + 품질 설정 + + + Interpolation: + 보간법: + + + 1x (None) + 1x (사용하지 않음) + + + 2x + 2x + + + 4x + 4x + + + 8x + 8x + + + Export between loop markers + 반복 마커 사이 구간만 내보내기 + + + Start + 시작 + + + Cancel + 취소 + + + 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! + 파일 %1을(를) 쓰기 위하여 열 수 없습니다. +경로에 파일이 존재하고 파일에 쓸 수 있는 권한이 있는지 확인 후 다시 시도하시기 바랍니다! + + + Export project to %1 + %1(으)로 프로젝트 내보내기 + + + Error + 오류 + + + Error while determining file-encoder device. Please try to choose a different output format. + 파일 인코더를 결정하는 중 오류가 발생하였습니다. 다른 포맷을 선택하여 다시 시도해 보세요. + + + Rendering: %1% + 렌더링: %1% + + + Compression level: + + + + Export as loop (remove extra bar) + 루프 곡처럼 내보내기 (후반부 여백 제거) + + + Render Looped Section: + + + + time(s) + + + + File format settings + + + + Sampling rate: + + + + Bit depth: + + + + 16 Bit integer + 16비트 정수 + + + 24 Bit integer + 24비트 정수 + + + 32 Bit float + 32비트 실수 + + + Joint stereo + + + + Zero order hold + + + + Sinc worst (fastest) + + + + Sinc medium (recommended) + + + + Sinc best (slowest) + + + + Oversampling: + + + + ( Fastest - biggest ) + + + + ( Slowest - smallest ) + + + + + Fader + + Please enter a new value between %1 and %2: + %1부터 %2까지의 값을 입력하세요: + + + Set value + 값 설정 + + + + FileBrowser + + Browser + 탐색기 + + + Search + 검색 + + + Refresh list + 목록 새로고침 + + + + FileBrowserTreeWidget + + Send to active instrument-track + 활성화된 악기 트랙에서 열기 + + + Open in new instrument-track/Song Editor + 새로운 악기 트랙이나 노래 편집기에서 열기 + + + Open in new instrument-track/B+B Editor + 새로운 악기 트랙이나 비트/베이스 라인 편집기에서 열기 + + + Loading sample + 샘플을 로딩하는 중 + + + Please wait, loading sample for preview... + 미리보기를 위하여 샘플을 로딩하는 중입니다. 잠시 기다려 주세요... + + + Error + 오류 + + + does not appear to be a valid + + + + file + 파일 + + + --- Factory files --- + @@ -884,19 +2020,23 @@ LFO frequency - + LFO 주파수 FlangerControlsDialog DELAY - + 지연 RATE + + Period: + + AMNT @@ -907,7 +2047,7 @@ FDBK - + 피드백 NOISE @@ -917,10 +2057,6 @@ Invert 파형 반전 - - Period: - - Delay time: @@ -968,6 +2104,10 @@ Channel 4 volume + + Shift Register width + + Channel 1 to SO2 (Left) @@ -1008,10 +2148,6 @@ Bass - - Shift Register width - - Sweep rate shift amount @@ -1176,6 +2312,101 @@ + + FxLine + + Channel send amount + + + + Move &left + 왼쪽으로 이동(&L) + + + Move &right + 오른쪽으로 이동(&R) + + + Rename &channel + 채널 이름 바꾸기(&C) + + + R&emove channel + 채널 제거(&R) + + + Remove &unused channels + 사용하지 않는 채널 제거(&U) + + + + FxLineLcdSpinBox + + Assign to: + 채널 할당: + + + New FX Channel + 새 FX 채널 + + + + FxMixer + + Master + 마스터 + + + FX %1 + FX %1 + + + Volume + 음량 + + + Mute + 음소거 + + + Solo + 독주 + + + + FxMixerView + + FX-Mixer + FX-믹서 + + + FX Fader %1 + FX 페이더 %1 + + + Mute + 음소거 + + + Mute this FX channel + 이 채널 음소거 + + + Solo + 독주 + + + Solo FX channel + 이 채널 독주 + + + + FxRoute + + Amount to send from channel %1 to channel %2 + 채널 %1에서 채널 %2(으)로 보낼 양 + + GigInstrument @@ -1207,15 +2438,1062 @@ Gain: - 이득: + 이득: + + + + GuiApplication + + Working directory + 작업 경로 + + + The LMMS working directory %1 does not exist. Create it now? You can change the directory later via Edit -> Settings. + LMMS 작업 경로 %1이(가) 존재하지 않습니다. 지금 만드시겠습니까? 나중에 편집 -> 설정에서 변경할 수 있습니다. + + + Preparing UI + UI 준비 + + + Preparing song editor + 노래 편집기 준비 + + + Preparing mixer + 믹서 준비 + + + Preparing controller rack + 컨트롤러 랙 준비 + + + Preparing project notes + 프로젝트 노트 준비 + + + Preparing beat/bassline editor + 비트/베이스 라인 편집기 준비 + + + Preparing piano roll + 피아노 롤 준비 + + + Preparing automation editor + 오토메이션 편집기 준비 + + + + InstrumentFunctionArpeggio + + Arpeggio + 아르페지오 + + + Arpeggio type + 아르페지오 형태 + + + Arpeggio range + 아르페지오 범위 + + + Cycle steps + + + + Skip rate + + + + Miss rate + + + + Arpeggio time + 아르페지오 시간 + + + Arpeggio gate + 아르페지오 게이트 + + + Arpeggio direction + 아르페지오 방향 + + + Arpeggio mode + 아르페지오 모드 + + + Up + 위로 + + + Down + 아래로 + + + Up and down + 위 다음 아래 + + + Down and up + 아래 다음 위 + + + Random + 무작위 + + + Free + 자유 + + + Sort + 정렬 + + + Sync + 동기화 + + + + InstrumentFunctionArpeggioView + + ARPEGGIO + 아르페지오 + + + RANGE + 범위 + + + Arpeggio range: + 아르페지오 범위: + + + octave(s) + 옥타브 + + + CYCLE + + + + Cycle notes: + + + + note(s) + + + + SKIP + + + + Skip rate: + + + + % + % + + + MISS + + + + Miss rate: + + + + TIME + 시간 + + + Arpeggio time: + 아르페지오 시간: + + + ms + ms + + + GATE + 게이트 + + + Arpeggio gate: + 아르페지오 게이트: + + + Chord: + 코드: + + + Direction: + 방향: + + + Mode: + 모드: + + + + InstrumentFunctionNoteStacking + + octave + 옥타브 + + + Major + + + + Majb5 + + + + minor + + + + minb5 + + + + sus2 + + + + sus4 + + + + aug + + + + augsus4 + + + + tri + + + + 6 + 6 + + + 6sus4 + 6sus4 + + + 6add9 + 6add9 + + + m6 + + + + 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 + + + + Maj7b5 + + + + Maj7#5 + + + + Maj7#11 + + + + Maj7add13 + + + + m7 + + + + m7b5 + + + + m7b9 + + + + m7add11 + + + + m7add13 + + + + m-Maj7 + + + + m-Maj7add11 + + + + m-Maj7add13 + + + + 9 + 9 + + + 9sus4 + 9sus4 + + + add9 + add9 + + + 9#5 + 9#5 + + + 9b5 + 9b5 + + + 9#11 + 9#11 + + + 9b13 + 9b13 + + + Maj9 + + + + Maj9sus4 + + + + Maj9#5 + + + + Maj9#11 + + + + m9 + + + + madd9 + + + + m9b5 + + + + m9-Maj7 + + + + 11 + 11 + + + 11b9 + 11b9 + + + Maj11 + + + + m11 + + + + m-Maj11 + + + + 13 + 13 + + + 13#9 + 13#9 + + + 13b9 + 13b9 + + + 13b5b9 + 13b5b9 + + + Maj13 + + + + m13 + + + + m-Maj13 + + + + Harmonic minor + 화성 단음계 + + + Melodic minor + 가락 단음계 + + + Whole tone + + + + Diminished + + + + Major pentatonic + + + + Minor pentatonic + + + + Jap in sen + + + + Major bebop + + + + Dominant bebop + + + + Blues + + + + Arabic + + + + Enigmatic + + + + Neopolitan + + + + Neopolitan minor + + + + Hungarian minor + + + + Dorian + + + + Phrygian + + + + Lydian + + + + Mixolydian + + + + Aeolian + + + + Locrian + + + + Minor + + + + Chromatic + + + + Half-Whole Diminished + + + + 5 + 5 + + + Phrygian dominant + + + + Persian + + + + Chords + 코드 + + + Chord type + 코드 종류 + + + Chord range + 코드 범위 + + + + InstrumentFunctionNoteStackingView + + STACKING + 코드 쌓기 + + + Chord: + 코드: + + + RANGE + 범위 + + + Chord range: + 코드 범위: + + + octave(s) + 옥타브 + + + + InstrumentMidiIOView + + ENABLE MIDI INPUT + MIDI 입력 활성화 + + + CHANNEL + 채널 + + + VELOCITY + 벨로시티 + + + ENABLE MIDI OUTPUT + MIDI 출력 활성화 + + + PROGRAM + 프로그램 + + + NOTE + + + + MIDI devices to receive MIDI events from + + + + MIDI devices to send MIDI events to + + + + CUSTOM BASE VELOCITY + 사용자 지정 기준 벨로시티 + + + BASE VELOCITY + 기준 벨로시티 + + + Specify the velocity normalization base for MIDI-based instruments at 100% note velocity. + + + + + InstrumentMiscView + + MASTER PITCH + 마스터 피치 + + + Enables the use of master pitch + 마스터 피치 사용 + + + + InstrumentSoundShaping + + VOLUME + 음량 + + + Volume + 음량 + + + CUTOFF + 컷오프 + + + Cutoff frequency + 차단 주파수 + + + RESO + 공명 + + + Resonance + 공명 + + + Envelopes/LFOs + 엔벨로프/LFO + + + Filter type + 필터 종류 + + + Q/Resonance + Q/공명 + + + Notch + 노치 + + + Moog + Moog + + + 2x Moog + 2x Moog + + + SV Notch + SV 노치 + + + Fast Formant + + + + Tripole + + + + Low-pass + + + + Hi-pass + + + + Band-pass csg + + + + Band-pass czpg + + + + All-pass + + + + 2x Low-pass + + + + RC Low-pass 12 dB/oct + + + + RC Band-pass 12 dB/oct + + + + RC High-pass 12 dB/oct + + + + RC Low-pass 24 dB/oct + + + + RC Band-pass 24 dB/oct + + + + RC High-pass 24 dB/oct + + + + Vocal Formant + + + + SV Low-pass + + + + SV Band-pass + + + + SV High-pass + + + + + InstrumentSoundShapingView + + TARGET + 대상 + + + FILTER + 필터 + + + FREQ + 주파수 + + + Hz + Hz + + + Envelopes, LFOs and filters are not supported by the current instrument. + 이 악기는 엔벨로프, LFO, 필터를 지원하지 않습니다. + + + Cutoff frequency: + 차단 주파수: + + + Q/RESO + Q/공명 + + + Q/Resonance: + Q/공명: InstrumentTrack + + With this knob you can set the volume of the opened channel. + 이 노브를 이용하여 트랙의 음량을 조절할 수 있습니다. + + + unnamed_track + 이름 없는 트랙 + + + Base note + 기준 음 + + + Volume + 음량 + + + Panning + 패닝 + + + Pitch + 피치 + + + Pitch range + 피치 범위 + + + FX channel + FX 채널 + Default preset 기본 프리셋 + + Master pitch + 마스터 피치 + + + + InstrumentTrackView + + Volume + 음량 + + + Volume: + 음량: + + + VOL + 음량 + + + Panning + 패닝 + + + Panning: + 패닝: + + + PAN + 패닝 + + + MIDI + MIDI + + + Input + 입력 + + + Output + 출력 + + + FX %1: %2 + FX %1: %2 + + + + InstrumentTrackWindow + + GENERAL SETTINGS + 일반 설정 + + + Volume: + 음량: + + + VOL + 음량 + + + Panning + 패닝 + + + Panning: + 패닝: + + + PAN + 패닝 + + + Pitch + 피치 + + + Pitch: + 피치: + + + cents + 센트 + + + PITCH + 피치 + + + Pitch range (semitones) + 피치 범위(반음) + + + RANGE + 범위 + + + FX channel + FX 채널 + + + FX + FX + + + Save current instrument track settings in a preset file + 프리셋 파일에 현재 악기 트랙의 설정 저장 + + + SAVE + 저장 + + + Envelope, filter & LFO + 엔벨로프, 필터 & LFO + + + Chord stacking & arpeggio + 코드 쌓기 & 아르페지오 + + + Effects + 효과 + + + Miscellaneous + 기타 + + + Save preset + 프리셋 저장 + + + XML preset file (*.xpf) + XML 프리셋 파일 (*.xpf) + + + Plugin + 플러그인 + + + Volume + 음량 + + + MIDI + MIDI + + + + Knob + + Set linear + 선형으로 설정 + + + Set logarithmic + 로그스케일로 설정 + + + Please enter a new value between -96.0 dBFS and 6.0 dBFS: + -96.0 dBFS부터 6.0 dBFS까지의 값을 입력하세요: + + + Please enter a new value between %1 and %2: + %1부터 %2까지의 값을 입력하세요: + + + Set value + 값 설정 + + + + LadspaControl + + Link channels + 채널 링크 + LadspaControlDialog @@ -1225,7 +3503,18 @@ Channel - 채널 + 채널 + + + + LadspaControlView + + Link channels + 채널 링크 + + + Value: + 값: @@ -1235,6 +3524,601 @@ 알 수 없는 LADSPA 플러그인 %1이(가) 요청되었습니다. + + LcdSpinBox + + Please enter a new value between %1 and %2: + %1부터 %2까지의 값을 입력하세요: + + + Set value + 값 설정 + + + + LeftRightNav + + Previous + 이전 + + + Next + 다음 + + + Previous (%1) + 이전 (%1) + + + Next (%1) + 다음 (%1) + + + + LfoController + + LFO Controller + LFO 컨트롤러 + + + Base value + 기준 값 + + + Oscillator speed + + + + Oscillator amount + + + + Oscillator phase + 오실레이터 위상 + + + Oscillator waveform + 오실레이터 파형 + + + Frequency Multiplier + + + + + LfoControllerDialog + + LFO + LFO + + + BASE + 기준 + + + AMNT + + + + Modulation amount: + + + + PHS + 위상 + + + Phase offset: + 위상: + + + Base: + + + + FREQ + 주파수 + + + LFO frequency: + + + + degrees + + + + Sine wave + 사인파 + + + Triangle wave + 삼각파 + + + Saw wave + 톱니파 + + + Square wave + 사각파 + + + Moog saw wave + Moog 톱니파 + + + Exponential wave + 지수형 파형 + + + White noise + 화이트 노이즈 + + + User-defined shape. +Double click to pick a file. + + + + Mutliply modulation frequency by 1 + + + + Mutliply modulation frequency by 100 + + + + Divide modulation frequency by 100 + + + + + LmmsCore + + Generating wavetables + + + + Initializing data structures + 자료 구조 초기화 중 + + + Opening audio and midi devices + 오디오 장치와 MIDI 장치를 여는 중 + + + Launching mixer threads + 믹서 스레드를 시작하는 중 + + + + MainWindow + + Configuration file + 설정 파일 + + + Error while parsing configuration file at line %1:%2: %3 + 설정 파일 분석 중 오류 발생 (행 %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! + 파일 %1을(를) 쓰기 위하여 열 수 없습니다. +경로에 파일이 존재하고 파일에 쓸 수 있는 권한이 있는지 확인 후 다시 시도하시기 바랍니다! + + + 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? + 복구 파일이 존재합니다. 이전에 LMMS가 비정상 종료되었거나 여러 개의 LMMS 인스턴스가 동시에 실행 중인 것 같습니다. 복구 파일로부터 프로젝트를 복구하시겠습니까? + + + Recover + 복구 + + + Recover the file. Please don't run multiple instances of LMMS when you do this. + 파일을 복구합니다. 다른 LMMS 인스턴스가 실행 중이지 않은 상태에서 선택하시기 바랍니다. + + + Discard + 저장하지 않음 + + + Launch a default session and delete the restored files. This is not reversible. + 복구 파일을 삭제하고 기본 프로젝트를 불러옵니다. 이 동작은 되돌릴 수 없습니다. + + + Version %1 + 버전 %1 + + + Preparing plugin browser + 플러그인 탐색기 준비 + + + Preparing file browsers + 파일 탐색기 준비 + + + My Projects + 내 프로젝트 + + + My Samples + 내 샘플 + + + My Presets + 내 사전 설정 + + + My Home + 내 홈 디렉터리 + + + Root directory + 최상위 디렉토리 + + + Volumes + 음량 + + + My Computer + 내 컴퓨터 + + + Loading background artwork + 배경 아트워크를 불러오는 중 + + + &File + 파일(&F) + + + &New + 새로 만들기(&N) + + + New from template + 템플릿에서 새 프로젝트 생성 + + + &Open... + 열기(&O)... + + + &Recently Opened Projects + 최근에 사용한 프로젝트(&R) + + + &Save + 저장(&S) + + + Save &As... + 다른 이름으로 저장(&A)... + + + Save as New &Version + 새로운 버전으로 저장(&V) + + + Save as default template + 기본 템플릿으로 저장 + + + Import... + 가져오기... + + + E&xport... + 내보내기(&X)... + + + E&xport Tracks... + 트랙 내보내기(&X)... + + + Export &MIDI... + MIDI 내보내기(&M)... + + + &Quit + 끝내기(&Q) + + + &Edit + 편집(&E) + + + Undo + 실행 취소 + + + Redo + 다시 실행 + + + Settings + 설정 + + + &View + 보기(&V) + + + &Tools + 도구(&T) + + + &Help + 도움말(&H) + + + Online Help + 온라인 도움말 + + + Help + 도움말 + + + About + 정보 + + + Create new project + 새 프로젝트 생성 + + + Create new project from template + 템플릿에서 새 프로젝트 생성 + + + Open existing project + 기존 프로젝트 열기 + + + Recently opened projects + 최근에 사용한 프로젝트 + + + Save current project + 현재 프로젝트 저장 + + + Export current project + 현재 프로젝트 내보내기 + + + Show/hide project notes + 프로젝트 노트 보이기/숨기기 + + + Show/hide controller rack + 컨트롤러 랙 보이기/숨기기 + + + Untitled + 제목 없음 + + + Recover session. Please save your work! + 복구 세션입니다. 프로젝트 파일을 저장해 주세요! + + + LMMS %1 + 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) + LMMS (*.mmp *.mmpz) + + + Save Project + 프로젝트 저장 + + + LMMS Project + LMMS 프로젝트 + + + LMMS Project Template + LMMS 프로젝트 템플릿 + + + 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 + FX 믹서 + + + Project Notes + 프로젝트 노트 + + + Controller Rack + 컨트롤러 랙 + + + Volume as dBFS + 음량을 dBFS 단위로 표시 + + + Smooth scroll + 부드러운 스크롤 + + + Enable note labels in piano roll + 피아노 롤에 음표 라벨 표시 + + + Metronome + 메트로놈 + + + MIDI File (*.mid) + MIDI 파일(*.mid) + + + untitled + 제목 없음 + + + Select file for project-export... + 프로젝트를 내보낼 파일 선택... + + + Select directory for writing exported tracks... + 내보낼 트랙 파일들을 저장할 경로 선택... + + + Save project + 프로젝트 저장 + + + Project saved + 프로젝트 저장됨 + + + The project %1 is now saved. + 프로젝트 %1이 저장되었습니다. + + + Project NOT saved. + 프로젝트가 저장되지 않았습니다. + + + The project %1 was not saved! + 프로젝트 %1이 저장되지 않았습니다! + + + Import file + 파일 가져오기 + + + MIDI sequences + MIDI 시퀀스 + + + Hydrogen projects + Hydrogen 프로젝트 + + + All file types + 모든 파일 + + + + MeterDialog + + Meter Numerator + 박자표 분자 + + + Meter Denominator + 박자표 분모 + + + TIME SIG + 박자 + + + Meter numerator + 박자표 분자 + + + Meter denominator + 박자표 분모 + + + + MeterModel + + Numerator + 분자 + + + Denominator + 분모 + + + + MidiController + + MIDI Controller + MIDI 컨트롤러 + + + unnamed_midi_controller + 이름 없는 MIDI 컨트롤러 + + MidiImport @@ -1243,7 +4127,7 @@ 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. - + LMMS가 SoundFont2 플레이어 지원 없이 컴파일되었습니다. MIDI 파일에서 가져온 트랙은 기본적으로 SoundFont2 플레이어로 재생되므로 MIDI 파일을 가져온 뒤 재생하면 아무 소리도 재생되지 않을 것입니다. Track @@ -1254,6 +4138,73 @@ + + MidiJack + + JACK server down + When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (title) + JAK 서버 종료 + + + The JACK server seems to be shuted down. + When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (dialog message) + JACK 서버가 종료된 것 같습니다. + + + + MidiPort + + Input channel + 입력 채널 + + + Output channel + 출력 채널 + + + Input controller + 입력 컨트롤러 + + + Output controller + 출력 컨트롤러 + + + Fixed input velocity + 입력 벨로시티 고정값 + + + Fixed output velocity + 출력 벨로시티 고정값 + + + Fixed output note + 출력 음높이 고정값 + + + Output MIDI program + 출력 MIDI 프로그램 + + + Base velocity + 기준 벨로시티 + + + Receive MIDI-events + MIDI 이벤트 받기 + + + Send MIDI-events + MIDI 이벤트 보내기 + + + + MidiSetupWidget + + DEVICE + 장치 + + MonstroInstrument @@ -1270,23 +4221,23 @@ Bandlimited Triangle wave - + 대역 제한 삼각파 Bandlimited Saw wave - + 대역 제한 톱니파 Bandlimited Ramp wave - + 대역 제한 역톱니파 Bandlimited Square wave - + 대역 제한 사각파 Bandlimited Moog saw wave - + 대역 제한 Moog 톱니파 Soft square wave @@ -1298,7 +4249,7 @@ Exponential wave - + 지수형 파형 White noise @@ -1322,7 +4273,7 @@ Digital Moog saw wave - + Moog 톱니파 Triangle wave @@ -1334,7 +4285,7 @@ Ramp wave - + 역톱니파 Square wave @@ -1342,7 +4293,7 @@ Moog saw wave - + Moog 톱니파 Abs. sine wave @@ -1358,11 +4309,11 @@ Osc 1 volume - + 오실레이터 1 음량 Osc 1 panning - + 오실레이터 1 패닝 Osc 1 coarse detune @@ -1394,11 +4345,11 @@ Osc 2 volume - + 오실레이터 2 음량 Osc 2 panning - + 오실레이터 2 패닝 Osc 2 coarse detune @@ -1418,7 +4369,7 @@ Osc 2 waveform - + 오실레이터 2 파형 Osc 2 sync hard @@ -1430,11 +4381,11 @@ Osc 3 volume - + 오실레이터 3 음량 Osc 3 panning - + 오실레이터 3 패닝 Osc 3 coarse detune @@ -1446,11 +4397,11 @@ Osc 3 waveform 1 - + 오실레이터 3 파형 1 Osc 3 waveform 2 - + 오실레이터 3 파형 2 Osc 3 sync hard @@ -1741,7 +4692,7 @@ Volume - 볼륨 + 음량 Panning @@ -1884,7 +4835,7 @@ Swap inputs - + 좌우 입력 바꾸기 Dry gain: @@ -1909,9 +4860,13 @@ Channel 2 Volume + + Channel 4 Volume + + Master volume - 마스터 볼륨 + 마스터 음량 Vibrato @@ -1986,7 +4941,7 @@ NesInstrumentView Volume - 볼륨 + 음량 Coarse detune @@ -2094,7 +5049,7 @@ Master volume - 마스터 볼륨 + 마스터 음량 @@ -2205,7 +5160,7 @@ FM - + FM Vibrato depth @@ -2238,48 +5193,48 @@ OscillatorObject - Osc %1 volume + Osc %1 waveform + 오실레이터 %1 파형 + + + Osc %1 harmonic + + Osc %1 volume + 오실레이터 %1 음량 + Osc %1 panning + 오실레이터 %1 패닝 + + + Osc %1 fine detuning left Osc %1 coarse detuning - - Osc %1 fine detuning left - - Osc %1 fine detuning right Osc %1 phase-offset - + 오실레이터 %1 위상 Osc %1 stereo phase-detuning - + 오실레이터 %1 좌우 위상차 Osc %1 wave shape - - - - Modulation type %1 - - - - Osc %1 waveform 오실레이터 %1 파형 - Osc %1 harmonic - + Modulation type %1 + 변조 유형 %1 @@ -2337,7 +5292,7 @@ No file selected - + 파일이 선택되지 않음 Open patch file @@ -2352,28 +5307,81 @@ + + PatternView + + Open in piano-roll + 피아노-롤에서 열기 + + + Clear all notes + 전체 음표 지우기 + + + Reset name + 이름 초기화 + + + Change name + 이름 바꾸기 + + + Add steps + + + + Remove steps + + + + Clone Steps + + + + Set as ghost in piano-roll + + + + + 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. + 이전 버전 LMMS의 버그로 인해 피크 컨트롤러가 제대로 연결되지 않았을 수 있습니다. 피크 컨트롤러가 제대로 연결되었는지 확인 후 파일을 다시 저장해 주시기 바랍니다. 불편을 드려 죄송합니다. + + + + PeakControllerDialog + + PEAK + + + + LFO Controller + LFO 컨트롤러 + + PeakControllerEffectControlDialog BASE + 기준 + + + AMNT Modulation amount: - - Attack: - - - - Release: - - - - AMNT - - MULT @@ -2382,18 +5390,26 @@ ATCK + + Attack: + + DCAY - Treshold: + Release: TRSH + + Treshold: + + Base: @@ -2404,7 +5420,7 @@ Mute output - + 출력 음소거 Absolute value @@ -2415,16 +5431,12 @@ PeakControllerEffectControls Base value - + 기준 값 Modulation amount - - Mute output - - Attack @@ -2437,15 +5449,389 @@ Treshold + + Mute output + 출력 음소거 + Absolute value - + 절댓값 Amount multiplicator + + 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% + 벨로시티: %1% + + + Panning: %1% left + 패닝: %1% 왼쪽 + + + Panning: %1% right + 패닝: %1% 오른쪽 + + + Panning: center + 패닝: 가운데 + + + Please open a pattern by double-clicking on it! + 더블클릭하여 패턴을 열어주세요! + + + Please enter a new value between %1 and %2: + %1부터 %2까지의 값을 입력하세요: + + + + PianoRollWindow + + Play/pause current pattern (Space) + 현재 패턴 재생/일시정지 (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) + 현재 패턴 정지 (Space) + + + Edit actions + 편집 동작 + + + Draw mode (Shift+D) + 그리기 모드 (Shift+D) + + + Erase mode (Shift+E) + 지우기 모드 (Shift+E) + + + Select mode (Shift+S) + 선택 모드 (Shift+S) + + + Pitch Bend mode (Shift+T) + + + + Quantize + + + + Copy paste controls + 복사/붙여넣기 컨트롤 + + + Timeline controls + + + + Zoom and note controls + + + + Piano-Roll - %1 + 피아노-롤 - %1 + + + Piano-Roll - no pattern + 피아노-롤 - 패턴 없음 + + + Record notes from MIDI-device/channel-piano, one step at the time + + + + Cut (%1+X) + 잘라내기 (%1+X) + + + Copy (%1+C) + 복사 (%1+C) + + + Paste (%1+V) + 붙여넣기 (%1+V) + + + Horizontal zooming + + + + Quantization + + + + Note length + 음표 길이 + + + Scale + + + + Chord + + + + Clear ghost notes + + + + + PianoView + + Base note + 기준 음 + + + + Plugin + + Plugin not found + 플러그인을 찾을 수 없음 + + + The plugin "%1" wasn't found or could not be loaded! +Reason: "%2" + 플러그인 "%1"을(를) 찾을 수 없거나 읽어올 수 없습니다. +이유: %2 + + + Error while loading plugin + 플러그인 로딩 오류 + + + Failed to load plugin "%1"! + 플러그인 "%1"을(를) 로딩할 수 없습니다! + + + + PluginBrowser + + Instrument Plugins + 악기 플러그인 + + + Instrument browser + 악기 탐색기 + + + Drag an instrument into either the Song-Editor, the Beat+Bassline Editor or into an existing instrument track. + 플러그인을 노래 편집기, 비트/베이스 라인 편집기, 이미 존재하는 악기 트랙 중 하나로 드래그하세요. + + + + PluginFactory + + Plugin not found. + 플러그인을 찾을 수 없습니다. + + + LMMS plugin %1 does not have a plugin descriptor named %2! + LMMS 플러그인 %1은(는) 이름이 %2인 플러그인 디스크립터를 가지고 있지 않습니다! + + + + ProjectNotes + + Edit Actions + 편집 동작 + + + &Undo + 실행 취소(&U) + + + %1+Z + %1+Z + + + &Redo + 다시 실행(&R) + + + %1+Y + %1+Y + + + &Copy + 복사(&C) + + + %1+C + %1+C + + + Cu&t + 잘라내기(&T) + + + %1+X + %1+X + + + &Paste + 붙여넣기(&P) + + + %1+V + %1+V + + + Format Actions + 서식 동작 + + + &Bold + 굵게(&B) + + + %1+B + %1+B + + + &Italic + 기울임꼴(&I) + + + %1+I + %1+I + + + &Underline + 밑줄(&U) + + + %1+U + %1+U + + + &Left + 왼쪽 정렬(&L) + + + %1+L + %1+L + + + C&enter + 가운데 정렬(&E) + + + %1+E + %1+E + + + &Right + 오른쪽 정렬(&R) + + + %1+R + %1+R + + + &Justify + 양쪽 정렬(&J) + + + %1+J + %1+J + + + &Color... + 색(&C)... + + + Project Notes + 프로젝트 노트 + + + Enter project notes here + 여기에 프로젝트 노트를 입력하세요 + + + + ProjectRenderer + + WAV (*.wav) + WAV (*.wav) + + + FLAC (*.flac) + FLAC (*.flac) + + + OGG (*.ogg) + OGG (*.ogg) + + + MP3 (*.mp3) + MP3 (*.mp3) + + QWidget @@ -2482,19 +5868,26 @@ Channels In: - 입력 채널: + 입력 채널: Channels Out: - 출력 채널: + 출력 채널: + + + File: %1 + 파일: %1 File: 파일: + + + RenameDialog - File: %1 - 파일: %1 + Rename... + 이름 바꾸기... @@ -2505,19 +5898,19 @@ Size - + 크기 Size: - + 크기: Color - + 음색 Color: - + 음색: Output @@ -2525,30 +5918,551 @@ Input gain: - 입력 이득: + 입력 이득: Output gain: - 출력 이득: + 출력 이득: ReverbSCControls Size - + 크기 Color - + 음색 Input gain - 입력 이득 + 입력 이득 Output gain - 출력 이득 + 출력 이득 + + + + SampleBuffer + + Fail to open file + 파일을 열 수 없음 + + + Audio files are limited to %1 MB in size and %2 minutes of playing time + 오디오 파일은 %1MB보다 작고 %2분보다 짧아야 합니다 + + + Open audio file + 오디오 파일 열기 + + + All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + 모든 오디오 파일 (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + + + Wave-Files (*.wav) + Wave 파일(*.wav) + + + OGG-Files (*.ogg) + OGG 파일(*.ogg) + + + DrumSynth-Files (*.ds) + DrumSynth 파일(*.ds) + + + FLAC-Files (*.flac) + FLAC 파일(*.flac) + + + SPEEX-Files (*.spx) + SPEEX 파일(*.spx) + + + VOC-Files (*.voc) + VOC 파일(*.voc) + + + AIFF-Files (*.aif *.aiff) + AIFF 파일 (*.aif *.aiff) + + + AU-Files (*.au) + AU 파일 (*.au) + + + RAW-Files (*.raw) + RAW 파일 (*.raw) + + + + SampleTCOView + + Delete (middle mousebutton) + 삭제(마우스 가운데 버튼) + + + Cut + 잘라내기 + + + Copy + 복사 + + + Paste + 붙여넣기 + + + Mute/unmute (<%1> + middle click) + 음소거/해제 (<%1> + 마우스 가운데 버튼) + + + Double-click to open sample + 더블클릭하여 샘플 열기 + + + + SampleTrack + + Volume + 음량 + + + Panning + 패닝 + + + Sample track + 샘플 트랙 + + + FX channel + FX 채널 + + + + SampleTrackView + + Track volume + 트랙 음량 + + + Channel volume: + 채널 음량: + + + VOL + 음량 + + + Panning + 패닝 + + + Panning: + 패닝: + + + PAN + 패닝 + + + FX %1: %2 + FX %1: %2 + + + + SampleTrackWindow + + GENERAL SETTINGS + 일반 설정 + + + Sample volume + 샘플 음량 + + + Volume: + 음량: + + + VOL + 음량 + + + Panning + 패닝 + + + Panning: + 패닝: + + + PAN + 패닝 + + + FX channel + FX 채널 + + + FX + FX + + + + SaveOptionsWidget + + Discard MIDI connections + MIDI 연결 제거 + + + + SetupDialog + + Setup LMMS + LMMS 설정 + + + General settings + 일반 설정 + + + BUFFER SIZE + 버퍼 크기 + + + MISC + 기타 + + + 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 + 경로 + + + Performance settings + 성능 설정 + + + Auto save + 자동 저장 + + + Enable auto-save + 자동 저장 활성화 + + + Allow auto-save while playing + 재생 중 자동 저장 허용 + + + UI effects vs. performance + UI 효과 vs. 성능 + + + Smooth scroll in Song Editor + 노래 편집기에서 부드러운 스크롤 사용 + + + Show playback cursor in AudioFileProcessor + + + + Audio settings + 오디오 설정 + + + AUDIO INTERFACE + 오디오 인터페이스 + + + MIDI settings + MIDI 설정 + + + MIDI INTERFACE + MIDI 인터페이스 + + + OK + 확인 + + + Cancel + 취소 + + + Restart LMMS + LMMS 다시 시작 + + + Please note that most changes won't take effect until you restart LMMS! + + + + Frames: %1 +Latency: %2 ms + 프레임: %1 +시간 지연: %2 ms + + + Choose LMMS working directory + LMMS 작업 경로 선택 + + + Choose your GIG directory + GIG 경로 선택 + + + Choose your SF2 directory + SF2 경로 선택 + + + Choose your VST-plugin directory + VST 플러그인 경로 선택 + + + Choose artwork-theme directory + 아트워크 경로 선택 + + + Choose LADSPA plugin directory + LADSPA 플러그인 경로 선택 + + + Choose STK rawwave directory + + + + Choose default SoundFont + 기본 사운드폰트 설정 + + + Choose background artwork + 배경 아트워크 선택 + + + minutes + + + + minute + + + + Disabled + 비활성화됨 + + + Auto-save interval: %1 + 자동 저장 간격: %1 + + + Reset to default value + + + + Keep plugin windows on top when not embedded + + + + + Song + + Tempo + 템포 + + + Master volume + 마스터 음량 + + + Master pitch + 마스터 피치 + + + LMMS Error report + LMMS 오류 보고 + + + The following errors occured while loading: + 로딩 중 다음과 같은 오류가 발생하였습니다: + + + + 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. + 파일 %1을(를) 열 수 없습니다. 파일을 읽을 수 있는 권한이 없기 때문일 수 있습니다. 파일을 읽을 수 있는 권한이 있는지 확인 후 다시 시도하시기 바랍니다. + + + 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. + 파일 %1을(를) 쓰기 위하여 열 수 없습니다. 파일을 쓸 수 있는 권한이 없기 때문일 수 있습니다. 파일에 쓸 수 있는 권한이 있는지 확인 후 다시 시도하시기 바랍니다. + + + Error in file + 파일 오류 + + + The file %1 seems to contain errors and therefore can't be loaded. + 파일 %1에 오류가 있어 로딩에 실패하였습니다. + + + Version difference + 버전 차이 + + + This %1 was created with LMMS %2. + 이 %1은(는) LMMS %2에서 만들어졌습니다. + + + template + 템플릿 + + + project + 프로젝트 + + + Tempo + 템포 + + + High quality mode + 고음질 모드 + + + Master volume + 마스터 음량 + + + Master pitch + 마스터 피치 + + + Value: %1% + 값: %1% + + + Value: %1 semitones + 값: %1반음 + + + TEMPO + 템포 + + + Tempo in BPM + BPM 단위의 템포 + + + + SongEditorWindow + + Song-Editor + 노래 편집기 + + + Play song (Space) + 노래 재생 (Space) + + + Record samples from Audio-device + 오디오 장치로부터 샘플 녹음 + + + Record samples from Audio-device while playing song or BB track + 노래 또는 비트/베이스 라인 트랙을 재생하는 동안 오디오 장치로부터 샘플 녹음 + + + Stop song (Space) + 노래 정지 (Space) + + + Track actions + + + + Add beat/bassline + 비트/베이스 라인 추가 + + + Add sample-track + 샘플 트랙 추가 + + + Add automation-track + 오토메이션 트랙 추가 + + + Edit actions + 편집 동작 + + + Draw mode + 그리기 모드 + + + Edit mode (select and move) + 편집 모드 (선택 및 이동) + + + Timeline controls + + + + Zoom controls + + + + Horizontal zooming + @@ -2577,8 +6491,216 @@ 채널 모드 + + StepRecorderWidget + + Hint + + + + Move recording curser using <Left/Right> arrows + + + + + SubWindow + + Close + 닫기 + + + Maximize + 최대화 + + + Restore + 복원 + + + + TabWidget + + Settings for %1 + %1에 대한 설정 + + + + TempoSyncKnob + + Tempo Sync + 템포 동기화 + + + No Sync + 동기화 없음 + + + Eight beats + 여덟 박자 + + + Whole note + 온음표 + + + Half note + 2분음표 + + + Quarter note + 4분음표 + + + 8th note + 8분음표 + + + 16th note + 16분음표 + + + 32nd note + 32분음표 + + + Custom... + 사용자 지정... + + + Custom + 사용자 지정 + + + Synced to Eight Beats + 여덟 박자에 동기화됨 + + + Synced to Whole Note + 온음표에 동기화됨 + + + Synced to Half Note + 2분음표에 동기화됨 + + + Synced to Quarter Note + 4분음표에 동기화됨 + + + Synced to 8th Note + 8분음표에 동기화됨 + + + Synced to 16th Note + 16분음표에 동기화됨 + + + Synced to 32nd Note + 32분음표에 동기화됨 + + + + TimeDisplayWidget + + MIN + + + + SEC + + + + MSEC + 밀리초 + + + BAR + 마디 + + + BEAT + + + + TICK + + + + Time units + 시간 단위 + + + + TimeLineWidget + + After stopping go back to begin + 정지한 뒤 시작점으로 이동 + + + After stopping go back to position at which playing was started + 정지한 뒤 재생을 시작한 점으로 이동 + + + After stopping keep position + 정지한 후 위치 유지 + + + Hint + + + + Press <%1> to disable magnetic loop points. + <%1> 키를 눌러 반복 지점을 자유롭게 이동할 수 있습니다. + + + Hold <Shift> to move the begin loop point; Press <%1> to disable magnetic loop points. + <Shift> 키를 누르면 반복 시작점을 움직일 수 있습니다; <%1> 키를 눌러 반복 지점을 자유롭게 움직일 수 있습니다. + + + Auto scrolling + 자동 스크롤 + + + Loop points + 루프 지점 + + + + Track + + Mute + 음소거 + + + Solo + 독주 + + TrackContainer + + Couldn't import file + 파일을 가져올 수 없음 + + + Couldn't find a filter for importing file %1. +You should convert this file into a format supported by LMMS using another software. + 파일 %1을(를) 가져오기 위한 필터를 찾을 수 없습니다. +이 파일을 가져오려면 다른 프로그램을 사용하여 LMMS가 지원하는 포맷으로 변환하시기 바랍니다. + + + Couldn't open file + 파일을 열 수 없음 + + + 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! + 파일 %1을(를) 읽기 열 수 없습니다. 파일을 읽을 수 있는 권한이 있는지 확인 후 다시 시도하시기 바랍니다! + + + Loading project... + 프로젝트 로딩 중... + Cancel 취소 @@ -2587,11 +6709,124 @@ Please wait... 잠시만 기다려 주세요... + + Loading cancelled + 로딩 취소됨 + + + Project loading was cancelled. + 프로젝트 로딩이 취소되었습니다. + + + Loading Track %1 (%2/Total %3) + 트랙 %1 로딩 중 (%2/총 %3) + Importing MIDI-file... MIDI 파일을 가져오는중... + + TrackContentObject + + Mute + 음소거 + + + + TrackContentObjectView + + Current position + 현재 위치 + + + Hint + + + + Press <%1> and drag to make a copy. + <%1> 키를 누른 채 드래그하여 복사합니다. + + + Current length + 현재 길이 + + + Press <%1> for free resizing. + <%1> 키를 눌러 크기를 자유롭게 조절할 수 있습니다. + + + %1:%2 (%3:%4 to %5:%6) + %1:%2 (%3:%4부터 %5:%6까지) + + + Delete (middle mousebutton) + 삭제(마우스 가운데 버튼) + + + Cut + 잘라내기 + + + Copy + 복사 + + + Paste + 붙여넣기 + + + Mute/unmute (<%1> + middle click) + 음소거/해제 (<%1> + 마우스 가운데 버튼) + + + + TrackOperationsWidget + + Mute + 음소거 + + + Solo + 독주 + + + Clone this track + 트랙 복제 + + + Remove this track + 트랙 제거 + + + Clear this track + 트랙 초기화 + + + FX %1: %2 + FX %1: %2 + + + Assign to new FX Channel + 새 FX 채널 할당 + + + Turn all recording on + + + + Turn all recording off + + + + Press <%1> while clicking on move-grip to begin a new drag'n'drop action. + + + + Actions + + + TripleOscillatorView @@ -2604,11 +6839,11 @@ Osc %1 volume: - 오실레이터 %1 볼륨: + 오실레이터 %1 음량: Osc %1 panning: - + 오실레이터 %1 패닝: Osc %1 coarse detuning: @@ -2676,39 +6911,70 @@ Sine wave - 사인파 + 사인파 Triangle wave - 삼각파 + 삼각파 Saw wave - 톱니파 + 톱니파 Square wave - 사각파 + 사각파 Moog-like saw wave - + Moog 톱니파 Exponential wave - + 지수형 파형 White noise - 화이트 노이즈 + 화이트 노이즈 User-defined wave - + 사용자 지정 파형 + + + + VersionedSaveDialog + + Increment version number + 버전 증가 + + + Decrement version number + 버전 감소 + + + already exists. Do you want to replace it? + 이(가) 이미 존재합니다. 덮어쓰시겠습니까? + + + Save Options + 저장 옵션 VestigeInstrumentView + + Previous (-) + 이전 (-) + + + Save preset + 프리셋 저장 + + + Next (+) + 다음 (+) + Show/hide GUI GUI 보이기/숨기기 @@ -2725,18 +6991,6 @@ EXE-files (*.exe) EXE 파일 (*.exe) - - Previous (-) - 이전 (-) - - - Save preset - 프리셋 저장 - - - Next (+) - 다음 (+) - Preset 프리셋 @@ -2766,6 +7020,17 @@ + + VisualizationWidget + + Click to enable + 클릭하여 활성화 + + + Oscilloscope + 오실로스코프 + + VstEffectControlDialog @@ -2804,8 +7069,8 @@ VstPlugin - Loading plugin - 플러그인 읽는 중 + The VST plugin %1 could not be loaded. + VST 플러그인 %1을 불러올 수 없습니다. Open Preset @@ -2848,31 +7113,31 @@ .fxb - Please wait while loading VST plugin... - VST 플러그인을 읽을 동안 잠시 기다려 주세요... + Loading plugin + 플러그인 읽는 중 - The VST plugin %1 could not be loaded. - VST 플러그인 %1을 불러올 수 없습니다. + Please wait while loading VST plugin... + VST 플러그인을 읽을 동안 잠시 기다려 주세요... WatsynInstrument Volume A1 - A1 볼륨 + A1 음량 Volume A2 - A2 볼륨 + A2 음량 Volume B1 - B1 볼륨 + B1 음량 Volume B2 - B2 볼륨 + B2 음량 Panning A1 @@ -2972,11 +7237,59 @@ Selected graph - + 선택된 그래프 WatsynView + + Volume + 음량 + + + Panning + 패닝 + + + Freq. multiplier + + + + Left detune + + + + cents + 센트 + + + Right detune + + + + A-B Mix + + + + Mix envelope amount + + + + Mix envelope attack + + + + Mix envelope hold + + + + Mix envelope decay + + + + Crosstalk + + Select oscillator A1 @@ -3041,54 +7354,6 @@ Square wave 사각파 - - Volume - 볼륨 - - - Panning - 패닝 - - - Freq. multiplier - - - - Left detune - - - - cents - 센트 - - - Right detune - - - - A-B Mix - - - - Mix envelope amount - - - - Mix envelope attack - - - - Mix envelope hold - - - - Mix envelope decay - - - - Crosstalk - - Modulate amplitude of A1 by output of A2 @@ -3127,14 +7392,14 @@ Saw wave - 톱니파 + 톱니파 Xpressive Selected graph - + 선택된 그래프 A1 @@ -3177,7 +7442,7 @@ XpressiveView Draw your own waveform here by dragging your mouse on this graph. - 드래그하여 원하는 파형을 그리세요. + 드래그하여 원하는 파형을 그리세요. Select oscillator W1 @@ -3205,7 +7470,7 @@ Sine wave - 사인파 + 사인파 Moog-saw wave @@ -3213,11 +7478,11 @@ Exponential wave - + 지수형 파형 Saw wave - 톱니파 + 톱니파 User-defined wave @@ -3225,15 +7490,15 @@ Triangle wave - 삼각파 + 삼각파 Square wave - 사각파 + 사각파 White noise - 화이트 노이즈 + 화이트 노이즈 WaveInterpolate @@ -3309,10 +7574,6 @@ ZynAddSubFxView - - Show GUI - GUI 표시 - Portamento: 포르타멘토: @@ -3343,7 +7604,7 @@ Resonance center frequency: - + 공명 중심 주파수: RES CF @@ -3351,12 +7612,16 @@ Resonance bandwidth: - + 공명 대역폭: RES BW + + Show GUI + GUI 표시 + Filter frequency: @@ -3388,22 +7653,22 @@ End of sample 샘플 끝 + + Loopback point + 루프 시작점 + Reverse sample 샘플 역으로 - - Stutter - - - - Loopback point - - Loop mode 루프 모드 + + Stutter + + Interpolation mode 보간법 @@ -3418,7 +7683,7 @@ Sinc - + Sinc Sample not found: %1 @@ -3429,11 +7694,15 @@ bitInvader Sample length - + 샘플 길이 bitInvaderView + + Draw your own waveform here by dragging your mouse on this graph. + 드래그하여 원하는 파형을 그리세요. + Sine wave 사인파 @@ -3458,25 +7727,21 @@ Normalize 규격화 - - Draw your own waveform here by dragging your mouse on this graph. - 드래그하여 원하는 파형을 그리세요. - Sample length - + 샘플 길이 White noise - 화이트 노이즈 + 화이트 노이즈 User-defined wave - + 사용자 지정 파형 Smooth waveform - 파형을 부드럽게 + 파형을 부드럽게 @@ -3515,15 +7780,15 @@ Process based on the maximum of both stereo channels - + 두 채널의 최댓값을 기준으로 효과 적용 Process based on the average of both stereo channels - + 두 채널의 평균을 기준으로 효과 적용 Process each stereo channel independently - + 각각의 채널에 독립적으로 효과 적용 Reset wavegraph @@ -3577,6 +7842,13 @@ 스테레오 모드 + + graphModel + + Graph + 그래프 + + kickerInstrument @@ -3587,14 +7859,14 @@ End frequency 끝 주파수 - - Gain - 이득 - Length 길이 + + Gain + 이득 + Noise 잡음 @@ -3605,11 +7877,11 @@ Start from note - + 음표 주파수에서 시작 End to note - + 음표 주파수에서 마침 Start distortion @@ -3648,7 +7920,7 @@ Noise: - + 잡음: Frequency slope: @@ -3656,7 +7928,7 @@ Envelope length: - + 엔벨로프 길이: Envelope slope: @@ -3664,11 +7936,11 @@ Start distortion: - + 디스토션 시작 값: End distortion: - + 디스토션 끝 값: @@ -3792,7 +8064,7 @@ VCF Envelope Decay - VCF 엔벨로프 감쇄 + VCF 엔벨로프 감쇠 Distortion @@ -3839,7 +8111,7 @@ Decay: - 감쇄: + 감쇠: 303-es-que, 24dB/octave, 3 pole filter @@ -3847,7 +8119,7 @@ Slide Decay: - 슬라이드 감쇄: + 슬라이드 감쇠: DIST: @@ -3887,11 +8159,11 @@ Moog wave - 무그 파형 + Moog 톱니파 Click here for a moog-like wave. - 클릭하여 무그 파형을 선택합니다. + 클릭하여 Moog 톱니파를 선택합니다. Sine wave @@ -3915,35 +8187,35 @@ 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 - + 대역 제한 Moog 톱니파 Click here for bandlimited moog saw wave. - + 클릭하여 대역 제한 Moog 톱니파를 선택합니다. @@ -3958,7 +8230,7 @@ Modulator - 모듈레이트 + 모듈레이터 Crossfade @@ -4014,7 +8286,7 @@ Glass - + 유리 Vibrato gain @@ -4030,7 +8302,7 @@ LFO speed - + LFO 속도 LFO depth @@ -4079,6 +8351,14 @@ Spread: + + Missing files + 없는 파일 + + + Your Stk-installation seems to be incomplete. Please make sure the full Stk-package is installed! + Stk 설치가 불완전한 것 같습니다. 완전한 Stk 패키지가 설치되었는지 확인하시기 바랍니다! + Hardness @@ -4101,7 +8381,7 @@ Modulator: - + 모듈레이터: Crossfade @@ -4109,7 +8389,7 @@ Crossfade: - + 크로스페이드: ADSR @@ -4117,7 +8397,7 @@ ADSR: - + ADSR: Pressure @@ -4125,7 +8405,7 @@ Pressure: - + 압력: Speed @@ -4133,15 +8413,7 @@ Speed: - - - - Missing files - 없는 파일 - - - Your Stk-installation seems to be incomplete. Please make sure the full Stk-package is installed! - Stk 설치가 불완전한 것 같습니다. 완전한 Stk 패키지가 설치되었는지 확인하시기 바랍니다! + 속도: Vibrato gain @@ -4169,11 +8441,11 @@ LFO speed - + LFO 속도 LFO speed: - LFO 속도: + LFO 속도: LFO depth @@ -4196,11 +8468,11 @@ Close - 닫기 + 닫기 VST sync - + VST와 동기화 @@ -4211,7 +8483,7 @@ VST Sync - + VST와 동기화 Automated @@ -4219,7 +8491,7 @@ Close - 닫기 + 닫기 @@ -4230,7 +8502,7 @@ Volume - 볼륨 + 음량 @@ -4241,11 +8513,11 @@ Volume: - 볼륨: + 음량: Randomise - + 무작위 생성 Osc %1 waveform: @@ -4253,23 +8525,23 @@ Osc %1 volume: - 오실레이터 %1 볼륨: + 오실레이터 %1 음량: Osc %1 panning: + 오실레이터 %1 패닝: + + + Osc %1 stereo detuning cents 센트 - - Osc %1 stereo detuning - - Osc %1 harmonic: - + 오실레이터 %1 배음: @@ -4310,19 +8582,71 @@ pluginBrowser - Incomplete monophonic imitation tb303 + no description + 설명 없음 + + + A native amplifier plugin + 내장 증폭기 플러그인 + + + Simple sampler with various settings for using samples (e.g. drums) in an instrument-track - Plugin for freely manipulating stereo output + Boost your bass the fast and simple way - Plugin for controlling knobs with sound peaks + Customizable wavetable synthesizer - Plugin for enhancing stereo separation of a stereo input file + An oversampling bitcrusher + + + + Carla Patchbay Instrument + + + + Carla Rack Instrument + + + + A 4-band Crossover Equalizer + + + + A native delay plugin + 내장 딜레이 플러그인 + + + A Dual filter plugin + + + + plugin for processing dynamics in a flexible way + + + + A native eq plugin + 내장 EQ 플러그인 + + + A native flanger plugin + 내장 플랜저 플러그인 + + + Player for GIG files + GIG 파일 플레이어 + + + Filter for importing Hydrogen files into LMMS + Hydrogen 파일을 LMMS로 읽어오기 위한 필터 + + + Versatile drum synthesizer @@ -4330,17 +8654,90 @@ 설치된 LADSPA 플러그인 목록 - GUS-compatible patch instrument + plugin for using arbitrary LADSPA-effects inside LMMS. + LMMS에서 LADSPA 이펙트를 이용하기 위한 플러그인. + + + Incomplete monophonic imitation tb303 + + + + Filter for exporting MIDI-files from LMMS + MIDI 파일을 LMMS에서 내보내기 위한 필터 + + + Filter for importing MIDI-files into LMMS + MIDI 파일을 LMMS로 읽어오기 위한 필터 + + + Monstrous 3-oscillator synth with modulation matrix + + + + A multitap echo delay plugin + + + + A NES-like synthesizer + + + + 2-operator FM Synth Additive Synthesizer for organ-like sounds + + Emulation of GameBoy (TM) APU + GameBoy (TM) APU 에뮬레이션 + + + GUS-compatible patch instrument + + + + Plugin for controlling knobs with sound peaks + + + + Reverb algorithm by Sean Costello + Sean Costello의 리버브 알고리즘 + + + Player for SoundFont files + 사운드폰트 파일 플레이어 + + + LMMS port of sfxr + + + + Emulation of the MOS6581 and MOS8580 SID. +This chip was used in the Commodore 64 computer. + + + + Graphical spectrum analyzer plugin + 그래픽 스펙트럼 분석 플러그인 + + + Plugin for enhancing stereo separation of a stereo input file + + + + Plugin for freely manipulating stereo output + + Tuneful things to bang on + + Three powerful oscillators you can modulate in several ways + + VST-host for using VST(i)-plugins within LMMS LMMS의 VST(i) 플러그인 호스트 @@ -4350,61 +8747,8 @@ - plugin for using arbitrary LADSPA-effects inside LMMS. - LMMS에서 LADSPA 이펙트를 이용하기 위한 플러그인. - - - Filter for importing MIDI-files into LMMS - 미디 파일을 LMMS로 읽어오기 위한 필터 - - - Emulation of the MOS6581 and MOS8580 SID. -This chip was used in the Commodore 64 computer. - - - - Player for SoundFont files - 사운드폰트 파일 플레이어 - - - Emulation of GameBoy (TM) APU - - - - Customizable wavetable synthesizer - - - - Embedded ZynAddSubFX - - - - 2-operator FM Synth - - - - Filter for importing Hydrogen files into LMMS - - - - LMMS port of sfxr - - - - Monstrous 3-oscillator synth with modulation matrix - - - - Three powerful oscillators you can modulate in several ways - - - - A native amplifier plugin - - - - Carla Rack Instrument - + plugin for using arbitrary VST effects inside LMMS. + LMMS에서 VST 이펙트를 이용하기 위한 플러그인. 4-oscillator modulatable wavetable synth @@ -4415,76 +8759,8 @@ This chip was used in the Commodore 64 computer. - Boost your bass the fast and simple way - - - - Versatile drum synthesizer - - - - Simple sampler with various settings for using samples (e.g. drums) in an instrument-track - - - - plugin for processing dynamics in a flexible way - - - - Carla Patchbay Instrument - - - - plugin for using arbitrary VST effects inside LMMS. - - - - Graphical spectrum analyzer plugin - - - - A NES-like synthesizer - - - - A native delay plugin - - - - Player for GIG files - - - - A multitap echo delay plugin - - - - A native flanger plugin - - - - An oversampling bitcrusher - - - - A native eq plugin - 내장 EQ 플러그인 - - - A 4-band Crossover Equalizer - - - - A Dual filter plugin - - - - Filter for exporting MIDI-files from LMMS - - - - Reverb algorithm by Sean Costello - + Embedded ZynAddSubFX + 내장 ZynAddSubFX 플러그인 Mathematical expression parser @@ -4519,15 +8795,15 @@ This chip was used in the Commodore 64 computer. Reverb room size - + 리버브 공간 크기 Reverb damping - + 리버브 감쇠 Reverb width - + 리버브 너비 Reverb level @@ -4547,7 +8823,7 @@ This chip was used in the Commodore 64 computer. Chorus depth - + 코러스 깊이 @@ -4594,7 +8870,7 @@ This chip was used in the Commodore 64 computer. Speed: - + 속도: Depth: @@ -4609,7 +8885,7 @@ This chip was used in the Commodore 64 computer. sfxrInstrument Wave - + 파형 @@ -4628,7 +8904,7 @@ This chip was used in the Commodore 64 computer. Volume - 볼륨 + 음량 Chip model @@ -4636,14 +8912,14 @@ This chip was used in the Commodore 64 computer. Cutoff frequency - 차단 주파수 + 차단 주파수 sidInstrumentView Volume: - 볼륨: + 음량: Resonance: @@ -4655,11 +8931,11 @@ This chip was used in the Commodore 64 computer. MOS6581 SID - + MOS6581 SID MOS8580 SID - + MOS8580 SID Attack: @@ -4667,7 +8943,7 @@ This chip was used in the Commodore 64 computer. Decay: - 감쇄: + 감쇠: Sustain: @@ -4679,7 +8955,7 @@ This chip was used in the Commodore 64 computer. Pulse Width: - + 펄스 폭: Coarse: @@ -4719,15 +8995,15 @@ This chip was used in the Commodore 64 computer. Pulse wave - + 펄스파 Triangle wave - 삼각파 + 삼각파 Saw wave - 톱니파 + 톱니파 Ring modulation @@ -4735,7 +9011,7 @@ This chip was used in the Commodore 64 computer. Pulse width: - + 펄스 폭: @@ -4746,7 +9022,7 @@ This chip was used in the Commodore 64 computer. WIDTH - + 너비 @@ -4760,19 +9036,19 @@ This chip was used in the Commodore 64 computer. stereoMatrixControlDialog Left to Left Vol: - 왼쪽에서 왼쪽 볼륨: + 왼쪽에서 왼쪽 음량: Left to Right Vol: - 왼쪽에서 오른쪽 볼륨: + 왼쪽에서 오른쪽 음량: Right to Left Vol: - 오른쪽에서 왼쪽 볼륨: + 오른쪽에서 왼쪽 음량: Right to Right Vol: - 오른쪽에서 오른쪽 볼륨: + 오른쪽에서 오른쪽 음량: @@ -4794,6 +9070,19 @@ This chip was used in the Commodore 64 computer. 오른쪽에서 오른쪽 + + testcontext + + test string + + + + test plural %n + + + + + vestigeInstrument @@ -4802,14 +9091,14 @@ This chip was used in the Commodore 64 computer. Please wait while loading the VST plugin... - + VST 플러그인을 읽을 동안 잠시 기다려 주세요... vibed String %1 volume - %1번 스트링 볼륨 + %1번 현 음량 String %1 stiffness @@ -4821,7 +9110,7 @@ This chip was used in the Commodore 64 computer. Pickup %1 position - + 픽업 %1 위치 Impulse %1 @@ -4829,7 +9118,7 @@ This chip was used in the Commodore 64 computer. String %1 panning - + String %1 패닝 String %1 detune @@ -4841,11 +9130,11 @@ This chip was used in the Commodore 64 computer. String %1 length - + %1번 현 길이 String %1 - + %1번 현 @@ -4860,7 +9149,7 @@ This chip was used in the Commodore 64 computer. Pickup position: - + 픽업 위치: Octave @@ -4924,15 +9213,15 @@ This chip was used in the Commodore 64 computer. White noise - 화이트 노이즈 + 화이트 노이즈 User-defined wave - + 사용자 지정 파형 Smooth waveform - 파형을 부드럽게 + 파형을 부드럽게 Normalize waveform @@ -4943,7 +9232,7 @@ This chip was used in the Commodore 64 computer. voiceObject Voice %1 pulse width - + 소리 %1 펄스 폭 Voice %1 attack @@ -5006,15 +9295,15 @@ This chip was used in the Commodore 64 computer. Clip input - + 입력 신호 클리핑 Reset wavegraph - + 그래프 초기화 Smooth wavegraph - + 그래프를 부드럽게 Increase wavegraph amplitude by 1 dB diff --git a/data/locale/ru.ts b/data/locale/ru.ts index f4c1e6a01..c7ec3a328 100644 --- a/data/locale/ru.ts +++ b/data/locale/ru.ts @@ -1,37 +1,117 @@ - - - + + + AboutDialog + + + About LMMS + О программе LMMS + + + + LMMS + ЛММС + + + + Version %1 (%2/%3, Qt %4, %5) + Версия %1 (%2/%3, Qt %4, %5) + + + + About + Подробнее + + + + LMMS - easy music production for everyone + LMMS - лёгкое создание музыки для всех + + + + Copyright © %1 + Все права защищены © %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 + Авторы + + + + Involved + Участники + + + + Contributors ordered by number of commits: + Разработчики сортированные по числу коммитов: + + + + Translation + Перевод + + + + 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! + Если Вы заинтересованы в переводе LMMS на другой язык или хотите улучшить существующий перевод, мы приветствуем любую помощь! Просто свяжитесь с разработчиками! + +Перевод выполнили: +Alexey Kouznetsov <alexey/dot/kouznetsov/at/gmail/dot/com> +Oe Ai <oeai/at/symbiants/dot/com> + + + + License + Лицензия + + AmplifierControlDialog + VOL ГРОМ + Volume: Громкость: + PAN БАЛ + Panning: Баланс: + LEFT Лево + Left gain: Лево мощность: + RIGHT Право + Right gain: Право мощность: @@ -39,95 +119,727 @@ AmplifierControls + Volume Громкость + Panning Баланс + Left gain Лево мощн + Right gain Право мощн + + AudioAlsaSetupWidget + + + DEVICE + УСТРОЙСТВО + + + + CHANNELS + КАНАЛЫ + + AudioFileProcessorView + + Open other sample + Открыть другую запись + + + + 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. + Нажмите здесь, чтобы открыть другой звуковой файл. В новом окне диалога вы сможете выбрать нужный файл. Такие настройки, как режим повтора, точки начала/конца, усиление и прочие не сбросятся, поэтому звучание может отличаться от оригинала. + + + Reverse sample Отзеркалить запись - Amplify: - Усиление: - - - Continue sample playback across notes - Продолжить воспроизведение записи по нотам + + If you enable this button, the whole sample is reversed. This is useful for cool effects, e.g. a reversed crash. + Если включить эту кнопку, вся запись пойдёт в обратную сторону, это удобно для крутых эффектов, типа обратного грохота. + Disable loop Отключить петлю + + This button disables looping. The sample plays only once from start to end. + Эта кнопка отключает зацикливание (loop-цикл). Запись проигрывается только один раз от начала до конца. + + + + Enable loop Включить петлю + + This button enables forwards-looping. The sample loops between the end point and the loop point. + Эта кнопка включает переднюю петлю. Сэмпл кольцуется между конечной точкой и точкой петли. + + + + This button enables ping-pong-looping. The sample loops backwards and forwards between the end point and the loop point. + Эта кнопка включает пинг-понг петлю. Сэмпл кольцуется обратно и вперёд между конечной точкой и точкой петли. + + + + Continue sample playback across notes + Продолжить воспроизведение записи по нотам + + + + 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) + Включение этой опции продолжит воспроизведение записи по разным нотам - если изменить ускорение или длительность ноты остановится до конца записи, то со следующей ноты запись продолжится там, где остановилась, чтобы сбросить воспроизвдение на начало записи, вставьте ноту внизу у клавиш (<20 Гц) + + + + Amplify: + Усиление: + + + + 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!) + Эта ручка задаёт коэффициент усиления. При значении 100% исходный звук не меняется, в противном случае ― он будет ослаблен или усилен. (Обратите внимание, что исходная запись при этом останется нетронутой.) + + + + Startpoint: + Начало: + + + + With this knob you can set the point where AudioFileProcessor should begin playing your sample. + Этим регулятором можно установить точку где АудиоФайлПроцессор должен начать воспроизведение сэмпла. + + + + Endpoint: + Конец: + + + + With this knob you can set the point where AudioFileProcessor should stop playing your sample. + Этот регулятор устанавливает точку в которой АудиоФайлПроцессор должен перестать воспроизвдение сэмпла. + + + Loopback point: Точка возврата петли: - Open sample - - - - Enable ping-pong loop - - - - Start point: - - - - End point: - + + With this knob you can set the point where the loop starts. + Этот регулятор ставит точку начала петли. AudioFileProcessorWaveView + Sample length: Длина записи: + + AudioJack + + + JACK client restarted + JACK-клиент перезапущен + + + + 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 не был подключен к JACK по какой-то причине, поэтому LMMS подключение к JACK было перезапущено. Вам придётся заново вручную создать соединения. + + + + JACK server down + JACK-сервер не доступен + + + + 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. + Возможно JACK-сервер был выключен и запуск нового процесса не удался, поэтому ЛММС не может продолжить работу. Вам следует сохранить проект и перезапустить JACK и LMMS. + + + + CLIENT-NAME + ИМЯ КЛИЕНТА + + + + CHANNELS + КАНАЛЫ + + + + AudioOss::setupWidget + + + DEVICE + УСТРОЙСТВО + + + + CHANNELS + КАНАЛЫ + + + + AudioPortAudio::setupWidget + + + BACKEND + УПРАВЛЕНИЕ + + + + DEVICE + УСТРОЙСТВО + + + + AudioPulseAudio::setupWidget + + + DEVICE + УСТРОЙСТВО + + + + CHANNELS + КАНАЛЫ + + + + AudioSdl::setupWidget + + + DEVICE + УСТРОЙСТВО + + + + AudioSndio::setupWidget + + + DEVICE + УСТРОЙСТВО + + + + CHANNELS + КАНАЛЫ + + + + AudioSoundIo::setupWidget + + + BACKEND + БЭКЕНД + + + + DEVICE + УСТРОЙСТВО + + + + AutomatableModel + + + &Reset (%1%2) + &R Сбросить (%1%2) + + + + &Copy value (%1%2) + &C Копировать значение (%1%2) + + + + &Paste value (%1%2) + &P Вставить значение (%1%2) + + + + Edit song-global automation + Изменить глоабльную автоматизацию композиции + + + + Remove song-global automation + Убрать глобальную автоматизацию композиции + + + + Remove all linked controls + Убрать всё присоединенное управление + + + + Connected to %1 + Подсоединено к %1 + + + + Connected to controller + Подсоединено к контроллеру + + + + Edit connection... + Настроить соединение... + + + + Remove connection + Удалить соединение + + + + Connect to controller... + Соединить с контроллером... + + + + AutomationEditor + + + Please open an automation pattern with the context menu of a control! + Откройте редатор автоматизации через контекстное меню регулятора! + + + + Values copied + Значения скопированы + + + + All selected values were copied to the clipboard. + Все выбранные значения скопированы в буфер обмена. + + + + 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) + Режим рисования (Shift+D) + + + + Erase mode (Shift+E) + Режим стирания (Shift-E) + + + + Flip vertically + Перевернуть вертикально + + + + Flip horizontally + Перевернуть горизонтально + + + + Click here and the pattern will be inverted.The points are flipped in the y direction. + Нажмите здесь и мелодия перевернётся. Точки переворачиваются в Y направлении. + + + + Click here and the pattern will be reversed. The points are flipped in the x direction. + Нажмите здесь и мелодия перевернётся в направлении 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. + При нажатии на эту кнопку активируется режим рисования нот, в нём вы можете добавлять/перемещать и изменять длительность одиночных нот. Это основной режим и используется большую часть времени. +Для включения этого режима можно использовать комбинацию клавиш Shift+D. + + + + 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. + При нажатии на эту кнопку активируется режим стирания. В этом режиме вы можете стирать ноты по одной. +Для включения этого режима можно использовать комбинацию клавиш Shift+E. + + + + 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) + Вырезать выбранные ноты (%1+X) + + + + Copy selected values (%1+C) + Копировать выбранные ноты в буфер (%1+C) + + + + Paste values from clipboard (%1+V) + Вставить запомненные значения (%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 + Редактор автоматизации — %1 + + + + Model is already connected to this pattern. + Модель уже подключена к этому шаблону. + + + + AutomationPattern + + + Drag a control while pressing <%1> + Тяните контроль удерживая <%1> + + + + AutomationPatternView + + + double-click to open this pattern in automation editor + Дважды щёлкните мышью чтобы настроить автоматизацию этого шаблона + + + + Open in Automation editor + Открыть в редакторе автоматизации + + + + Clear + Очистить + + + + Reset name + Сбросить название + + + + Change name + Переименовать + + + + Set/clear record + Установить/очистить запись + + + + Flip Vertically (Visible) + Перевернуть вертикально (Видимое) + + + + Flip Horizontally (Visible) + Перевернуть горизонтально (Видимое) + + + + %1 Connections + Соединения %1 + + + + Disconnect "%1" + Отсоединить «%1» + + + + Model is already connected to this pattern. + Модель уже подключена к этому шаблону. + + + + AutomationTrack + + + Automation track + Дорожка автоматизации + + + + BBEditor + + + Beat+Bassline Editor + Ритм+Бас Редактор + + + + Play/pause current beat/bassline (Space) + Игра/пауза текущей линии ритма/баса (<Space>) + + + + Stop playback of current beat/bassline (Space) + Остановить воспроизведение текущей линии ритм-баса (ПРОБЕЛ) + + + + Click here to play the current beat/bassline. The beat/bassline is automatically looped when its end is reached. + Нажмите чтобы проиграть текущую линию ритм-баса. Она будет закольцована по достижении окончания. + + + + Click here to stop playing of current beat/bassline. + Остановить воспроизведение (Пробел). + + + + Beat selector + Выбор бита + + + + Track and step actions + Действия для дорожки или ее части + + + + Add beat/bassline + Добавить ритм/бас + + + + Add sample-track + Добавить дорожку записи + + + + Add automation-track + Добавить дорожку автоматизации + + + + Remove steps + Убрать такты + + + + Add steps + Добавить такты + + + + Clone Steps + Клонировать такты + + + + BBTCOView + + + Open in Beat+Bassline-Editor + Открыть в редакторе ритм + баса + + + + Reset name + Сбросить название + + + + Change name + Переименовать + + + + Change color + Изменить цвет + + + + Reset color to default + Установить цвет по умолчанию + + + + BBTrack + + + Beat/Bassline %1 + Ритм-Бас Линия %1 + + + + Clone of %1 + Копия %1 + + BassBoosterControlDialog + FREQ ЧАСТ + Frequency: Частота: + GAIN МОЩ + Gain: Мощность: + RATIO ОТН + Ratio: Отношение: @@ -135,14 +847,17 @@ BassBoosterControls + Frequency Частота + Gain Мощность + Ratio Отношение @@ -150,1043 +865,2111 @@ BitcrushControlDialog + IN - IN + ВХОД + OUT - OUT + ВЫХОД + + GAIN МОЩ - CLIP - СРЕЗ - - - Sample rate: - Частота сэмплирования: - - - Stereo difference: - Стерео разница: - - - Levels: - Уровни: + + Input Gain: + Входная мощность: + NOISE Шум + + Input Noise: + Входной шум: + + + + Output Gain: + Выходная мощность: + + + + CLIP + СРЕЗ + + + + Output Clip: + Выходная обрезка: + + + + Rate Enabled + Частота выборки включена + + + + Enable samplerate-crushing + Включить дробление частоты дискретизации + + + + Depth Enabled + Глубина включена + + + + Enable bitdepth-crushing + Включить дробление битовой глубины + + + FREQ FREQ + + Sample rate: + Частота сэмплирования: + + + STEREO СТЕРЕО + + Stereo difference: + Стерео разница: + + + QUANT - + КВАНТ - Input gain: - Входная мощность: - - - Input noise: - - - - Output gain: - Выходная мощность: - - - Output clip: - - - - Rate enabled - - - - Enable sample-rate crushing - - - - Depth enabled - - - - Enable bit-depth crushing - + + Levels: + Уровни: - BitcrushControls + CaptionMenu - Input gain - Входная мощность + + &Help + &H Справка - Input noise - - - - Output gain - Выходная мощность - - - Output clip - - - - Sample rate - - - - Stereo difference - - - - Levels - - - - Rate enabled - - - - Depth enabled - + + Help (not available) + Справка (не доступна) CarlaInstrumentView + Show GUI Показать интерфейс + + + Click here to show or hide the graphical user interface (GUI) of Carla. + Нажмите сюда, чтобы показать или скрыть графический интерфейс Карла. + + + + Controller + + + Controller %1 + Контроллер %1 + + + + ControllerConnectionDialog + + + Connection Settings + Параметры соединения + + + + MIDI CONTROLLER + MIDI-КОНТРОЛЛЕР + + + + Input channel + Канал ввода + + + + CHANNEL + КАНАЛ + + + + Input controller + Контроллер ввода + + + + CONTROLLER + КОНТРОЛЛЕР + + + + + Auto Detect + Автоопределение + + + + MIDI-devices to receive MIDI-events from + Устройства MiDi для приёма событий + + + + USER CONTROLLER + ПОЛЬЗ. КОНТРОЛЛЕР + + + + MAPPING FUNCTION + ПЕРЕОПРЕДЕЛЕНИЕ + + + + OK + ОК + + + + Cancel + Отменить + + + + LMMS + LMMS + + + + Cycle Detected. + Обнаружен цикл. + + + + ControllerRackView + + + Controller Rack + Рэка контроллеров + + + + Add + Добавить + + + + Confirm Delete + Подтвердить удаление + + + + Confirm delete? There are existing connection(s) associated with this controller. There is no way to undo. + Подтверждаете удаление? Есть возможные соединения с этим контроллером, возврата не будет. + + + + ControllerView + + + Controls + Управление + + + + Controllers are able to automate the value of a knob, slider, and other controls. + Контроллеры могут автоматизировать изменения значений регуляторов, ползунков и прочего управления. + + + + Rename controller + Переименовать контроллер + + + + Enter the new name for this controller + Введите новое название для контроллера + + + + LFO + LFO + + + + &Remove this controller + Убрать этот контроллер + + + + Re&name this controller + Переименовать этот контроллер + CrossoverEQControlDialog - Band 1/2 crossover: - + + Band 1/2 Crossover: + Полоса 1/2 кроссовер: - Band 2/3 crossover: - + + Band 2/3 Crossover: + Полоса 2/3 кроссовер: - Band 3/4 crossover: - + + Band 3/4 Crossover: + Полоса 3/4 кроссовер: - Band 1 gain - + + Band 1 Gain: + Полоса 1 усиление: - Band 1 gain: - + + Band 2 Gain: + Полоса 2 усиление: - Band 2 gain - + + Band 3 Gain: + Полоса 3 усиление: - Band 2 gain: - + + Band 4 Gain: + Полоса 4 усиление: - Band 3 gain - + + Band 1 Mute + Полоса 1 выключена - Band 3 gain: - + + Mute Band 1 + Заглушить полосу 1 - Band 4 gain - + + Band 2 Mute + Полоса 2 выключена - Band 4 gain: - + + Mute Band 2 + Заглушить полосу 2 - Band 1 mute - + + Band 3 Mute + Полоса 3 заглушена - Mute band 1 - + + Mute Band 3 + Заглушить полосу 3 - Band 2 mute - + + Band 4 Mute + Полоса 4 заглушена - Mute band 2 - - - - Band 3 mute - - - - Mute band 3 - - - - Band 4 mute - - - - Mute band 4 - + + Mute Band 4 + Заглушить полосу 4 DelayControls + + Delay Samples + Задержка сэмплов + + + Feedback Возврат + + Lfo Frequency + Частота LFO + + + + Lfo Amount + Объём LFO + + + Output gain Выходная мощность - - Delay samples - - - - LFO frequency - - - - LFO amount - - DelayControlsDialog - Gain - Усиление - - + DELAY ЗАДЕРЖ - FDBK - + + Delay Time + Время задержки + + FDBK + + + + + Feedback Amount + Объём возврата: + + + RATE ЧАСТ + + Lfo + Lfo + + + AMNT ГЛУБ - Delay time - + + Lfo Amt + Вел LFO - Feedback amount - + + Out Gain + Выходная мощность - LFO frequency - - - - LFO amount - - - - Out gain - + + Gain + Усиление DualFilterControlDialog - Filter 1 enabled - Фильтр 1 включен - - - Filter 2 enabled - Фильтр 2 включен - - + + FREQ FREQ + + Cutoff frequency Срез частот + + RESO RESO + + Resonance Резонанс + + GAIN МОЩ + + Gain УСИЛ + MIX - + МИКС + Mix - + Микс - Enable/disable filter 1 - + + Filter 1 enabled + Фильтр 1 включен - Enable/disable filter 2 - + + Filter 2 enabled + Фильтр 2 включен + + + + Click to enable/disable Filter 1 + Кликнуть для включения/выключения Фильтра 1 + + + + Click to enable/disable Filter 2 + Кликнуть для включения/выключения Фильтра 2 DualFilterControls + Filter 1 enabled Фильтр 1 включен + Filter 1 type - + Фильтр 1 тип + + Cutoff 1 frequency + Срез 1 частоты + + + Q/Resonance 1 - + + Gain 1 - + Усиление 1 + Mix - + Микс + Filter 2 enabled Фильтр 2 включен + Filter 2 type - + Фильтр 2 тип + + Cutoff 2 frequency + Срез 2 частоты + + + Q/Resonance 2 - + + Gain 2 - + Усиление 2 + + + LowPass + Низ.ЧФ + + + + + HiPass + Выс.ЧФ + + + + + BandPass csg + Сред.ЧФ csg + + + + + BandPass czpg + Сред.ЧФ czpg + + + + Notch Полосно-заграждающий + + + Allpass + Все проходят + + + + Moog Муг + + + 2x LowPass + 2х Низ.ЧФ + + + + + RC LowPass 12dB + RC Низ.ЧФ 12дБ + + + + + RC BandPass 12dB + RC Сред.ЧФ 12 дБ + + + + + RC HighPass 12dB + RC Выс.ЧФ 12дБ + + + + + RC LowPass 24dB + RC Низ.ЧФ 24дБ + + + + + RC BandPass 24dB + RC Сред.ЧФ 24дБ + + + + + RC HighPass 24dB + RC Выс.ЧФ 24дБ + + + + + Vocal Formant Filter + Фильтр Вокальной форманты + + + + 2x Moog 2x Муг + + + SV LowPass + SV Низ.ЧФ + + + + + SV BandPass + SV Сред.ЧФ + + + + + SV HighPass + SV Выс.ЧФ + + + + SV Notch - + + + Fast Formant - + + + Tripole - + Триполи + + + + Editor + + + Transport controls + Управление транспортом - Cutoff frequency 1 - + + Play (Space) + Игра (Пробел) - Cutoff frequency 2 - + + Stop (Space) + Стоп (Пробел) - Low-pass - + + Record + Запись - Hi-pass - + + Record while playing + Запись при игре + + + + Effect + + + Effect enabled + Эффект включён - Band-pass csg - + + Wet/Dry mix + Насыщенность - Band-pass czpg - + + Gate + Шлюз - All-pass - + + Decay + Затихание + + + + EffectChain + + + Effects enabled + Эффекты включёны + + + + EffectRackView + + + EFFECTS CHAIN + ЦЕПЬ ЭФФЕКТОВ - 2x Low-pass - + + Add effect + Добавить эффект + + + + EffectSelectDialog + + + Add effect + Добавить эффект - RC Low-pass 12 dB/oct - + + + Name + Имя - RC Band-pass 12 dB/oct - + + Type + Тип - RC High-pass 12 dB/oct - + + Description + Описание - RC Low-pass 24 dB/oct - + + Author + Автор + + + + EffectView + + + Toggles the effect on or off. + Вкл/выкл эффект. - RC Band-pass 24 dB/oct - + + On/Off + Вкл/Выкл - RC High-pass 24 dB/oct - + + W/D + НАСЫЩ - Vocal Formant - + + Wet Level: + Уровень насыщенности: - SV Low-pass - + + The Wet/Dry knob sets the ratio between the input signal and the effect signal that forms the output. + Регулятор насыщенности определяет долю обработанного сигнала, которая будет на выходе. - SV Band-pass - + + DECAY + ЗАТУХАНИЕ - SV High-pass - + + 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. + Decay (затихание) управляет количеством буферов тишины, которые должны пройти до конца работы плагина. Меньшие величины снижают перегрузку процессора, но вознкает риск появления потрескивания или подрезания в хвосте на передержке (delay) или эхо (reverb) эффектах. + + + + GATE + ШЛЮЗ + + + + Gate: + Шлюз: + + + + The Gate knob controls the signal level that is considered to be 'silence' while deciding when to stop processing signals. + GATE (Шлюз) определяет уровень сигнала, который будет считаться "тишиной" при определении остановки обрабатывания сигналов. + + + + 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. + +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. + Сигнал проходит последовательно через все установленные фильтры (сверху вниз). + +Переключатель Вкл/Выкл позволяет в любой момент включать/выключать фильтр. + +Регулятор (wet / dry) насыщенности определяет баланс между входящим сигналом и сигналом после эффекта, который становится выходным сигналом эффекта. Входной сигнал каждого фильтра является выходом предыдущего, так что доля чистого сигнала при прохождении по цепочке постоянно падает. + +Регулятор (decay) затихания определяет время, которое будет действовать фильтр после того как ноты были отпущены. +Эффект перестанет обрабатывать сигналы, когда грмокость упадёт ниже порога для заданной длины времени. Эта ручка (Knob) устанавливает "заданную длину времени" Чем меньше значение, тем меньше требования к ЦП, поэтому лучше ставить это число низким для большинства эффектов. однако это может вызвать обрезку звука при использовании эффектов с длительными периодами тишины, типа задержки. + +Регулятор шлюза служит для указания порога сигнала для авто-отключения эффекта, отсчёт для "заданной длины времени" начнётся как только обрабатываемый сигнал упадёт ниже указанного этим регулятором уровня. + +Кнопка „Управление“ открывает окно изменения параметров эффекта. + +Контекстное меню, вызываемое щелчком правой кнопкой мыши, позволяет менять порядок следования фильтров или удалять их вместе с другими. + + + + Move &up + &u Переместить выше + + + + Move &down + &d Переместить ниже + + + + &Remove this plugin + &R Убрать фильтр + + + + EnvelopeAndLfoParameters + + + Predelay + Задержка + + + + Attack + Вступление + + + + Hold + Удерживание + + + + Decay + Затихание + + + + Sustain + Выдержка + + + + Release + Убывание + + + + Modulation + Модуляция + + + + LFO Predelay + Задержка LFO + + + + LFO Attack + Вступление LFO + + + + LFO speed + Скорость LFO + + + + LFO Modulation + Модуляция LFO + + + + LFO Wave Shape + Форма сигнала LFO + + + + Freq x 100 + ЧАСТ x 100 + + + + Modulate Env-Amount + Модулировать огибающую + + + + EnvelopeAndLfoView + + + + DEL + DEL + + + + Predelay: + Задержка: + + + + 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: + Вступление: + + + + 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: + Удержание: + + + + 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: + Затухание: + + + + 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: + Выдержка: + + + + 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: + Убывание: + + + + 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 + AMT + + + + + Modulation amount: + Глубина модуляции: + + + + 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: + Пред. задержка 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 (LFO - НизкоЧастотный осциллятор (генератор)). Чем больше величина, тем больше времени до того как LFO начнёт работать. + + + + LFO- 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. + Используйте эту ручку для установления времени вступления этого LFO. Чем больше значение, тем дольше LFO нуждается в увеличении своей амплитуды до максимума. + + + + SPD + SPD + + + + LFO speed: + Скорость 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. + Эта ручка устанавлявает скорость текущего LFO. Чем больше значение, тем быстрее LFO осциллирует и быстрее производится эффект. + + + + 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. + Эта ручка устанавливает глубину модуляции для текущего LFO. Чем больше значение, тем в большей степени выбранная характеристика (н-р, громкость или частота среза) будет зависеть от этого LFO. + + + + Click here for a sine-wave. + Синусоида. + + + + Click here for a triangle-wave. + Сгенерировать треугольный сигнал. + + + + Click here for a saw-wave for current. + Сгенерировать зигзагообразный сигнал. + + + + Click here for a square-wave. + Сгенерировать квадрат. + + + + Click here for a user-defined wave. Afterwards, drag an according sample-file onto the LFO graph. + Задать свою форму сигнала. Впоследствии, перетащить соответствующий файл с записью в граф LFO. + + + + Click here for random wave. + Нажмите сюда для случайной волны. + + + + FREQ x 100 + ЧАСТОТА x 100 + + + + Click here if the frequency of this LFO should be multiplied by 100. + Нажмите, чтобы умножить частоту этого LFO на 100. + + + + multiply LFO-frequency by 100 + Умножить частоту LFO на 100 + + + + MODULATE ENV-AMOUNT + МОДУЛИР ОГИБАЮЩУЮ + + + + Click here to make the envelope-amount controlled by this LFO. + Нажмите сюда, чтобы глубина модуляции огибающей задавалась этим LFO. + + + + control envelope-amount by this LFO + Разрешить этому LFO задавать значение огибающей + + + + ms/LFO: + мс/LFO: + + + + Hint + Подсказка + + + + Drag a sample from somewhere and drop it in this window. + Перетащите в это окно какую-нибудь запись. EqControls + Input gain Входная мощность + Output gain Выходная мощность + + Low shelf gain + Низкая ступень усиления + + + Peak 1 gain - + Пик 1 усиление + Peak 2 gain - + Пик 2 усиление + Peak 3 gain - + Пик 3 усиление + Peak 4 gain - + Пик 4 усиление + + High Shelf gain + Высокая степень усиления + + + HP res - + ВЧ резон + + Low Shelf res + Низкая ступень резон + + + Peak 1 BW - + Пик 1 BW + Peak 2 BW - + Пик 2 BW + Peak 3 BW - + Пик 3 BW + Peak 4 BW - + Пик 4 BW + + High Shelf res + Высокая ступень резон + + + LP res - + НЧ резон + HP freq - + НЧ част + + Low Shelf freq + Низкая степень част + + + Peak 1 freq - + Пик 1 част + Peak 2 freq - + Пик 2 част + Peak 3 freq - + Пик 3 част + Peak 4 freq - + Пик 4 част + + High shelf freq + Высокая ступень част + + + LP freq - + НЧ част + HP active - + ВЧ активна + + Low shelf active + Низкая ступень активна + + + Peak 1 active - + Пик 1 активен + Peak 2 active - + Пик 2 активен + Peak 3 active - + Пик 3 активен + Peak 4 active - + Пик 3 активен + + High shelf active + Высокая степень активна + + + LP active - + НЧ активна + LP 12 - + НЧ 12 + LP 24 - + НЧ 24 + LP 48 - + НЧ 48 + HP 12 - + ВЧ 12 + HP 24 - + ВЧ 24 + HP 48 - + ВЧ 48 + + low pass type + Тип нижних частот + + + + high pass type + Тип верхних частот + + + Analyse IN - + Анализировать ВХОД + Analyse OUT - - - - Low-shelf gain - - - - High-shelf gain - - - - Low-shelf res - - - - High-shelf res - - - - Low-shelf freq - - - - High-shelf freq - - - - Low-shelf active - - - - High-shelf active - - - - Low-pass type - - - - High-pass type - + Анализировать ВЫХОД EqControlsDialog + HP - + ВЧ + + Low Shelf + Низкая ступень + + + Peak 1 - + Пик 1 + Peak 2 - + Пик 2 + Peak 3 - + Пик 3 + Peak 4 - + Пик 3 + + High Shelf + Высокая ступень + + + LP - + НЧ + + In Gain + Входная мощность + + + + + Gain Мощность + + Out Gain + Выходная мощность + + + Bandwidth: - - - - Resonance : - Резонанс: - - - Frequency: - Частота: + Полоса пропускания: + Octave Октава - Low-shelf - + + Resonance : + Резонанс: - High-shelf - + + Frequency: + Частота: - Input gain - Входная мощность + + lp grp + нч grp - Output gain - Выходная мощность - - - LP group - - - - HP group - + + hp grp + вч grp EqHandle + Reso: - + Резон: + BW: - + BW + + Freq: - + Част: + + + + ExportProjectDialog + + + Export project + Экспорт проекта + + + + Output + Вывод + + + + File format: + Формат файла: + + + + Samplerate: + Частота дискретизации: + + + + 44100 Hz + 44.1 КГц + + + + 48000 Hz + 48 КГц + + + + 88200 Hz + 88.2 КГц + + + + 96000 Hz + 96 КГц + + + + 192000 Hz + 192 КГц + + + + Depth: + Емкость: + + + + 16 Bit Integer + 16 Бит целое + + + + 24 Bit Integer + 24 бита целое + + + + 32 Bit Float + 32 Бит плавающая + + + + Stereo mode: + Режим стерео: + + + + Stereo + Стерео + + + + Joint Stereo + Объединённое стерео + + + + Mono + Моно + + + + Bitrate: + Частота бит: + + + + 64 KBit/s + 64 КБит/с + + + + 128 KBit/s + 128 КБит/с + + + + 160 KBit/s + 160 КБит/с + + + + 192 KBit/s + 192 КБит/с + + + + 256 KBit/s + 256 КБит/с + + + + 320 KBit/s + 320 КБит/с + + + + Use variable bitrate + Использовать плавающую глубину битности + + + + Quality settings + Настройки качества + + + + Interpolation: + Интерполяция: + + + + Zero Order Hold + Нулевая задержка + + + + Sinc Fastest + Синхр. Быстрая + + + + Sinc Medium (recommended) + Синхр. Средняя (рекомендовано) + + + + Sinc Best (very slow!) + Синхр. лучшая (очень медленно!) + + + + Oversampling (use with care!): + Передискретизация (использовать осторожно!): + + + + 1x (None) + 1х (Нет) + + + + 2x + + + + + 4x + + + + + 8x + + + + + Export as loop (remove end silence) + Экспортировать как петлю (убрать тишину в конце) + + + + Export between loop markers + Экспорт между метками петли + + + + Start + Начать + + + + Cancel + Отменить + + + + 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! + Невозможно открыть файл %1 для записи. Пожалуйста, убедитесь, что у вас есть разрешение на запись в файл и содержащую его директорию, и попробуйте снова. + + + + Export project to %1 + Экспорт проекта в %1 + + + + Error + Ошибка + + + + Error while determining file-encoder device. Please try to choose a different output format. + Ошибка при определении кодека файла. Попробуйте выбрать другой формат вывода. + + + + Rendering: %1% + Обработка: %1% + + + Compression level: + + + + (fastest) + + + + (default) + + + + (smallest) + + + + + Expressive + + Selected graph + + + + A1 + + + + A2 + + + + A3 + + + + W1 smoothing + + + + W2 smoothing + + + + W3 smoothing + + + + PAN1 + + + + PAN2 + + + + REL TRANS + + + + + Fader + + + + Please enter a new value between %1 and %2: + Введите новое значение от %1 до %2: + + + + FileBrowser + + + Browser + Обозреватель файлов + + + Search + + + + Refresh list + + + + + FileBrowserTreeWidget + + + Send to active instrument-track + Послать на активную инструментальную-дорожку + + + + Open in new instrument-track/Song Editor + Отркрыть в новой инструментальной дорожке/редакторе песни + + + + Open in new instrument-track/B+B Editor + Открыть в новой инструментальной дорожке/Б+Б редакторе + + + + Loading sample + Загрузка записи + + + + Please wait, loading sample for preview... + Пж. ждите, запись загружается для просмотра... + + + + Error + Ошибка + + + + does not appear to be a valid + Не похоже на правильное + + + + file + файл + + + + --- Factory files --- + --- Заводские файлы --- FlangerControls + + Delay Samples + Задержка сэмплов + + + + Lfo Frequency + Частота LFO + + + Seconds Секунды + Regen - + + Noise Шум + Invert - - - - Delay samples - - - - LFO frequency - + Инвертировать FlangerControlsDialog + DELAY Задержка + + Delay Time: + Время задержки: + + + RATE ЧАСТ + + Period: + Период: + + + AMNT ГЛУБ + Amount: - + Величина: + FDBK - + + + Feedback Amount: + Объём возврата: + + + NOISE Шум + + White Noise Amount: + Объём белого шума: + + + Invert - - - - Period: - - - - Delay time: - - - - Feedback amount: - - - - White noise amount: - + Инвертировать - FreeBoyInstrument + FxLine - Sweep time - Время распространения + + Channel send amount + Величина отправки канала - Sweep direction - Направление распространения + + 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. + + Канал эффектов (ЭФ) получает сигнал на вход от одной или нескольких инструментальных дорожек. +В свою очередь его можно подключить к нескольким другим каналам эффектов. ЛММС автоматически предотвращает бесконечные циклы и не позволяет создавать соединения, которые приведут к бесконечному циклу. +Чтобы соединить один канал с другим, выберите канал ЭФфектов и кликните кнопку послать (Send) на канале, куда нужно послать. Регулятор под кнопкой "послать" контролирует уровень сигнала, посылаемого на канал. +Можно убирать и двигать каналы эффектов через контекстное меню, если кликнуть правой кнопкой мыши по каналу эффектов. + - Channel 1 volume - Громкость первого канала + + Move &left + Двигать влево &L - Volume sweep direction - Объём направления распространения + + Move &right + Двигать вправо &r - Length of each step in sweep - Длина каждого такта в распространении + + Rename &channel + Переименовать канал &c - Channel 2 volume - Громкость второго канала + + R&emove channel + Удалить канал &e - Channel 3 volume - Громкость третьего канала - - - Channel 4 volume - Громкость четвёртого канала - - - Channel 1 to SO2 (Left) - От первого канала к SO2 (левый канал) - - - Channel 2 to SO2 (Left) - От второго канала к SO2 (левый канал) - - - Channel 3 to SO2 (Left) - От третьего канала к SO2 (левый канал) - - - Channel 4 to SO2 (Left) - От четвёртого канала к SO2 (левый канал) - - - Channel 1 to SO1 (Right) - От первого канала к SO1 (правый канал) - - - Channel 2 to SO1 (Right) - От второго канала к SO1 (правый канал) - - - Channel 3 to SO1 (Right) - От третьего канала к SO1 (правый канал) - - - Channel 4 to SO1 (Right) - От четвёртого канала к SO1 (правый канал) - - - Treble - Верхние - - - Bass - Нижние - - - Shift Register width - Сдвиг ширины регистра - - - Sweep rate shift amount - - - - Wave pattern duty cycle - - - - Right output level - - - - Left output level - + + Remove &unused channels + Удалить неиспользуемые каналы &u - FreeBoyInstrumentView + FxMixer - Length of each step in sweep: - Длина каждого такта в развёртке: + + Master + Главный - Length of each step in sweep - Длина каждого такта в распространении + + + + FX %1 + Эффект %1 - Treble: - Верхние: + + Volume + Громкость - Treble - Верхние + + Mute + Тихо - Bass: - Нижние: + + Solo + Соло + + + + FxMixerView + + + FX-Mixer + Микшер Эффектов - Bass - Нижние + + FX Fader %1 + - Sweep time: - + + Mute + Тихо - Sweep time - Время распространения + + Mute this FX channel + Заглушить этот канал ЭФ - Sweep rate shift amount: - + + Solo + Соло - Sweep rate shift amount - + + Solo FX channel + Соло канал ЭФ + + + FxRoute - Wave pattern duty cycle: - - - - Wave pattern duty cycle - - - - Square channel 1 volume: - - - - Square channel 1 volume - - - - Square channel 2 volume: - - - - Square channel 2 volume - - - - Wave pattern channel volume: - - - - Wave pattern channel volume - - - - Noise channel volume: - - - - Noise channel volume - - - - SO1 volume (Right): - - - - SO1 volume (Right) - - - - SO2 volume (Left): - - - - SO2 volume (Left) - - - - Sweep direction - Направление распространения - - - Volume sweep direction - Объём направления распространения - - - Shift register width - - - - Channel 1 to SO1 (Right) - От первого канала к SO1 (правый канал) - - - Channel 2 to SO1 (Right) - От второго канала к SO1 (правый канал) - - - Channel 3 to SO1 (Right) - От третьего канала к SO1 (правый канал) - - - Channel 4 to SO1 (Right) - От четвёртого канала к SO1 (правый канал) - - - Channel 1 to SO2 (Left) - От первого канала к SO2 (левый канал) - - - Channel 2 to SO2 (Left) - От второго канала к SO2 (левый канал) - - - Channel 3 to SO2 (Left) - От третьего канала к SO2 (левый канал) - - - Channel 4 to SO2 (Left) - От четвёртого канала к SO2 (левый канал) - - - Wave pattern graph - + + + Amount to send from channel %1 to channel %2 + Величина отправки с канала %1 на канал %2 GigInstrument + Bank Банк + Patch Патч + Gain Мощность @@ -1194,1125 +2977,3787 @@ GigInstrumentView + + Open other GIG file + Открыть другой GIG файл + + + + Click here to open another GIG file + Кликните сюда, чтобы открыть другой GIG файл + + + + Choose the patch + Выбрать патч + + + + Click here to change which patch of the GIG file to use + Нажмите здесь для смены используемого патча GIG файла + + + + + Change which instrument of the GIG file is being played + Изменить инструмент, который воспроизводит GIG файл + + + + Which GIG file is currently being used + Какой GIG файл сейчас используется + + + + Which patch of the GIG file is currently being used + Какой патч GIG файла сейчас используется + + + + Gain + УСИЛ + + + + Factor to multiply samples by + Фактор умножения сэмплов + + + Open GIG file Открыть GIG файл + GIG Files (*.gig) GIG Файлы (*.gig) + + + GuiApplication - Choose patch - + + Working directory + Рабочий каталог - Gain: - + + The LMMS working directory %1 does not exist. Create it now? You can change the directory later via Edit -> Settings. + Рабочий каталог LMMS (%1) не существует. Создать его? Позже вы сможете сменить его через Правка -> Параметры. + + + + Preparing UI + Подготовка UI + + + + Preparing song editor + Подготовка редактора песни + + + + Preparing mixer + Подготовка микшера + + + + Preparing controller rack + Подготовка стойки управления + + + + Preparing project notes + Подготовка заметок проекта + + + + Preparing beat/bassline editor + Подготовка Ритм+Бас редактора + + + + Preparing piano roll + Подготовка редактора нот + + + + Preparing automation editor + Подготовка редактора автоматизации + + + + InstrumentFunctionArpeggio + + + Arpeggio + Арпеджио + + + + Arpeggio type + Тип арпеджио + + + + Arpeggio range + Диапазон арпеджио + + + + Cycle steps + + + + + Skip rate + Частота пропуска + + + + Miss rate + + + + + Arpeggio time + Период арпеджио + + + + Arpeggio gate + Шлюз арпеджио + + + + Arpeggio direction + Направление арпеджио + + + + Arpeggio mode + Режим арпеджио + + + + Up + Вверх + + + + Down + Вниз + + + + Up and down + Вверх и вниз + + + + Down and up + Вниз и вверх + + + + Random + Случайно + + + + Free + Свободно + + + + Sort + Упорядочить + + + + Sync + Синхронизировать + + + + 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 + RANGE + + + + Arpeggio range: + Диапазон арпеджио: + + + + octave(s) + Октав[а/ы] + + + + Use this knob for setting the arpeggio range in octaves. The selected arpeggio will be played within specified number of octaves. + Используйте эту ручку, чтобы установить диапазон арпеджио (в октавах). Выбранный тип арпеджио будет охватывать указанное количество октав. + + + + CYCLE + ЦИКЛ + + + + Cycle notes: + + + + + note(s) + нота(ы) + + + + 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 + ПРОПУСК + + + + Skip rate: + Частота пропуска: + + + + + + % + % + + + + 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 + TIME + + + + Arpeggio time: + Период арпеджио: + + + + ms + мс + + + + Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. + Регулировка периода арпеджио - время (в миллисекундах), которое должен звучать каждый тон арпеджио. + + + + GATE + GATE + + + + 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: + Аккорд: + + + + Direction: + Направление: + + + + Mode: + Режим: + + + + InstrumentFunctionNoteStacking + + + octave + Октава + + + + + Major + Мажорный + + + + Majb5 + Majb5 + + + + 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 + Maj7 + + + + Maj7b5 + Maj7b5 + + + + Maj7#5 + Maj7#5 + + + + Maj7#11 + Maj7#11 + + + + Maj7add13 + Maj7add13 + + + + m7 + m7 + + + + m7b5 + m7b5 + + + + m7b9 + m7b9 + + + + m7add11 + m7add11 + + + + m7add13 + m7add13 + + + + m-Maj7 + m-Maj7 + + + + m-Maj7add11 + m-Maj7add11 + + + + m-Maj7add13 + m-Maj7add13 + + + + 9 + 9 + + + + 9sus4 + 9sus4 + + + + add9 + add9 + + + + 9#5 + 9#5 + + + + 9b5 + 9b5 + + + + 9#11 + 9#11 + + + + 9b13 + 9b13 + + + + Maj9 + Maj9 + + + + Maj9sus4 + Maj9sus4 + + + + Maj9#5 + Maj9#5 + + + + Maj9#11 + Maj9#11 + + + + m9 + m9 + + + + madd9 + madd9 + + + + m9b5 + m9b5 + + + + m9-Maj7 + m9-Maj7 + + + + 11 + 11 + + + + 11b9 + 11b9 + + + + Maj11 + Maj11 + + + + m11 + m11 + + + + m-Maj11 + m-Maj11 + + + + 13 + 13 + + + + 13#9 + 13#9 + + + + 13b9 + 13b9 + + + + 13b5b9 + 13b5b9 + + + + Maj13 + Maj13 + + + + m13 + m13 + + + + m-Maj13 + m-Maj13 + + + + Harmonic minor + Гармонический минор + + + + Melodic minor + Мелодический минор + + + + Whole tone + Целый тон + + + + Diminished + Пониженный + + + + Major pentatonic + Мажорная пентатоника + + + + Minor pentatonic + Минорная пентатоника + + + + Jap in sen + + + + + Major bebop + + + + + Dominant bebop + + + + + Blues + Blues + + + + Arabic + Арабский + + + + Enigmatic + + + + + Neopolitan + Неополитанский + + + + Neopolitan minor + Неополитанский минор + + + + Hungarian minor + + + + + Dorian + Дорийский + + + + Phrygian + Фригийский + + + + Lydian + Лидийский + + + + Mixolydian + Миксолидийский + + + + Aeolian + Эолийский + + + + Locrian + + + + + Minor + + + + + Chromatic + Хроматический + + + + Half-Whole Diminished + + + + + 5 + 5 + + + + Phrygian dominant + + + + + Persian + + + + + Chords + Аккорды + + + + Chord type + Тип аккорда + + + + Chord range + Диапазон аккорда + + + + InstrumentFunctionNoteStackingView + + + STACKING + СТЫКОВКА + + + + Chord: + Аккорд: + + + + RANGE + ДИАП + + + + Chord range: + Диапазон аккорда: + + + + octave(s) + Октав[а/ы] + + + + 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 + ВКЛ MIDI ВВОД + + + + + CHANNEL + CHANNEL + + + + + VELOCITY + VELOCITY + + + + ENABLE MIDI OUTPUT + ВКЛ MIDI ВЫВОД + + + + PROGRAM + PROGRAM + + + + NOTE + NOTE + + + + MIDI devices to receive MIDI events from + MiDi устройства-источники событий + + + + MIDI devices to send MIDI events to + MiDi устройства для отправки событий на них + + + + CUSTOM BASE VELOCITY + ПРОИЗВОЛЬНАЯ БАЗОВАЯ СКОРОСТЬ + + + + Specify the velocity normalization base for MIDI-based instruments at 100% note velocity + Определяет базовую скорость нормализации для MiDi инструментов при громкости ноты 100% + + + + BASE VELOCITY + БАЗОВАЯ СКОРОСТЬ + + + + InstrumentMiscView + + + MASTER PITCH + Мастер-высота + + + + Enables the use of Master Pitch + Включает использование основной тональности + + + + InstrumentSoundShaping + + + VOLUME + VOLUME + + + + Volume + Громкость + + + + CUTOFF + CUTOFF + + + + + Cutoff frequency + Срез частоты + + + + RESO + RESO + + + + Resonance + Резонанс + + + + Envelopes/LFOs + Огибание/LFO + + + + Filter type + Тип фильтра + + + + Q/Resonance + + + + + LowPass + Низ.ЧФ + + + + HiPass + Выс.ЧФ + + + + BandPass csg + Сред.ЧФ csg + + + + BandPass czpg + Сред.ЧФ czpg + + + + Notch + Полосно-заграждающий + + + + Allpass + Все проходят + + + + Moog + Муг + + + + 2x LowPass + 2х Низ.ЧФ + + + + RC LowPass 12dB + RC Низ.ЧФ 12дБ + + + + RC BandPass 12dB + RC Сред.ЧФ 12 дБ + + + + RC HighPass 12dB + RC Выс.ЧФ 12дБ + + + + RC LowPass 24dB + RC Низ.ЧФ 24дБ + + + + RC BandPass 24dB + RC Сред.ЧФ 24дБ + + + + RC HighPass 24dB + RC Выс.ЧФ 24дБ + + + + Vocal Formant Filter + Фильтр Вокальной форманты + + + + 2x Moog + 2x Муг + + + + SV LowPass + SV Низ.ЧФ + + + + SV BandPass + SV Сред.ЧФ + + + + SV HighPass + SV Выс.ЧФ + + + + SV Notch + + + + + Fast Formant + + + + + Tripole + Триполи + + + + InstrumentSoundShapingView + + + TARGET + ЦЕЛЬ + + + + 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...! + Эта вкладка позволяет вам настроить огибающие. Они очень важны для настройки звучания. +Например, с помощью огибающей громкости вы можете задать зависимость громкости звучания от времени. Если вам понадобится эмулировать мягкие струнные, просто задайте больше времени нарастания и исчезновения звука. С помощью обгибающих и низкочастотного осцилятора (LFO) вы в несколько щелчков мыши сможете создать просто невероятные звуки! + + + + 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 + ЧАСТ + + + + cutoff frequency: + Срез частот: + + + + 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: + Усиление: + + + + 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. + Огибающие, LFO и фильтры не поддерживаются этим инструментом. InstrumentTrack + + With this knob you can set the volume of the opened channel. + Регулировка громкости текущего канала. + + + + + unnamed_track + безымянная_дорожка + + + + Base note + Опорная нота + + + + Volume + Громкость + + + + Panning + Стерео + + + + Pitch + Тональность + + + + Pitch range + Диапазон тональности + + + + FX channel + Канал ЭФ + + + + Master Pitch + Основная тональность + + + + Default preset Основная предустановка + + InstrumentTrackView + + + Volume + Громкость + + + + Volume: + Громкость: + + + + VOL + ГРОМ + + + + Panning + Баланс + + + + Panning: + Баланс: + + + + PAN + БАЛ + + + + MIDI + MIDI + + + + Input + Вход + + + + Output + Выход + + + + FX %1: %2 + ЭФ %1: %2 + + + + 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 + Параметры MIDI + + + + Miscellaneous + Разное + + + + Save preset + Сохранить предустановку + + + + XML preset file (*.xpf) + XML файл настроек (*.xpf) + + + + Plugin + Модуль + + + + Knob + + + Set linear + Установить линейно + + + + Set logarithmic + Установить логарифмически + + + + Please enter a new value between -96.0 dBFS and 6.0 dBFS: + Введите новое значение от –96,0 дБВ до 6,0 дБВ: + + + + Please enter a new value between %1 and %2: + Введите новое значение от %1 до %2: + + + + LadspaControl + + + Link channels + Связать каналы + + LadspaControlDialog + Link Channels Связать каналы + Channel Канал + + LadspaControlView + + + Link channels + Связать каналы + + + + Value: + Значение: + + + + Sorry, no help available. + Извините, справки нет. + + LadspaEffect + Unknown LADSPA plugin %1 requested. Запрошен неизвестный модуль LADSPA «%1». + + LcdSpinBox + + + Please enter a new value between %1 and %2: + Введите новое значение от %1 до %2: + + + + LeftRightNav + + + + + Previous + Предыдущий + + + + + + Next + Следующий + + + + Previous (%1) + Предыдущий (%1) + + + + Next (%1) + Следующий (%1) + + + + LfoController + + + LFO Controller + Контроллер LFO + + + + Base value + Основное значение + + + + Oscillator speed + Скорость волны + + + + Oscillator amount + Размер волны + + + + Oscillator phase + Фаза волны + + + + Oscillator waveform + Форма волны + + + + Frequency Multiplier + Множитель частоты + + + + LfoControllerDialog + + + LFO + LFO + + + + LFO Controller + Контроллер LFO + + + + BASE + БАЗА + + + + Base amount: + Базовое значение: + + + + todo + доделать + + + + SPD + СКОР + + + + LFO-speed: + Скорость LFO: + + + + Use this knob for setting speed of the LFO. The bigger this value the faster the LFO oscillates and the faster the effect. + Эта ручка устанавлявает скорость LFO. Чем больше значение, тем больше частота осциллятора. + + + + AMNT + ГЛУБ + + + + Modulation amount: + Количество модуляции: + + + + 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. + Эта ручка устанавливает глубину модуляции для LFO. Чем больше значение, тем в большей степени выбранная характеристика (н-р, громкость или частота среза) будет зависеть от ГНЧ(LFO). + + + + PHS + ФАЗА + + + + Phase offset: + Сдвиг фазы: + + + + degrees + градусы + + + + 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. + Эта ручка устанавливает начальную фазу НизкоЧастотного Осциллятора (LFO), т. е. точку, с которой осциллятор начинает вырабатывать сигнал. Например, если вы задали синусоидальную форму сигнала и начальную фазу 180º, волна сначала пойдёт вниз, а не вверх, так же как и для квадратной волны. + + + + Click here for a sine-wave. + Синусоида. + + + + Click here for a triangle-wave. + Сгенерировать треугольный сигнал. + + + + Click here for a saw-wave. + Сгенерировать зигзаг. + + + + Click here for a square-wave. + Сгенерировать квадрат. + + + + Click here for a moog saw-wave. + Нажать здесь для зигзагообразной муг волны. + + + + Click here for an exponential wave. + Генерировать экспоненциальный сигнал. + + + + Click here for white-noise. + Сгенерировать белый шум. + + + + Click here for a user-defined shape. +Double click to pick a file. + Нажмите здесь для определения своей формы. +Двойное нажатие для выбора файла. + + + + LmmsCore + + + Generating wavetables + Генерация волн + + + + Initializing data structures + Инициализация структуры данных + + + + Opening audio and midi devices + Открываем аудио и миди устройства + + + + Launching mixer threads + Запускаем потоки микшера + + + + MainWindow + + Settings + Параметры + + Configuration file + Файл настроек + + + + Error while parsing configuration file at line %1:%2: %3 + Ошибка во время обработки файла настроек в строке %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! + Невозможно открыть файл %1 для записи. Пожалуйста, убедитесь, что у вас есть разрешение на запись в файл и содержащую его директорию, и попробуйте снова. + + + + 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? + Остался файл для восстановления. Похоже последняя сессия не была нормально завершена или запущен ещё один процесс LMMS. +Хотите восстановить проект из этой сессии? + + + + + + 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 + Версия %1 + + + + Preparing plugin browser + Подготовка обзора плагинов + + + + Preparing file browsers + Подготовка обзора файлов + + + + My Projects + Мои проекты + + + + My Samples + Мои сэмплы + + + + My Presets + Мои предустановки + + + + My Home + Моя домашняя папка + + + + Root directory + Корневая директория + + + + Volumes + Громкость 1 оциллятора + + + + My Computer + Мой компьютер + + + + Loading background artwork + Загружаем фоновый рисунок + + + + &File + &F Файл + + + + &New + &N Новый + + + + New from template + Новый на основе шаблона + + + + &Open... + &Открыть... + + + + &Recently Opened Projects + &R Недавние проекты + + + + &Save + &S Сохранить + + + + Save &As... + &A Сохранить как... + + + + Save as New &Version + &V Сохранить как новую версию + + + + Save as default template + Сохранить как обычный шаблон + + + + Import... + Импорт... + + + + E&xport... + &X Экспорт... + + + + E&xport Tracks... + &x Экспорт дорожек... + + + + Export &MIDI... + Экспорт &MIDI... + + + + &Quit + &Q Выйти + + + + &Edit + &E Правка + + + + Undo + Откатить действие + + + + Redo + Возврат действия + + + + Settings + Параметры + + + + &View + &Просмотр + + + + &Tools + &T Сервис + + + + &Help + &H Справка + + + + Online Help + Помощь онлайн + + + + Help + Справка + + + + What's This? + Что это? + + + + About + О программе + + + + Create new project + Создать новый проект + + + + Create new project from template + Создать новый проект по шаблону + + + + Open existing project + Открыть существующий проект + + + + Recently opened projects + Недавние проекты + + + + Save current project + Сохранить текущий проект + + + + Export current project + Экспорт проекта + + + + What's this? + Что это? + + + + Toggle metronome + Включить метроном + + + + Show/hide Song-Editor + Показать/скрыть музыкальный редактор + + + + 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 + Показать/скрыть Ритм+Бас редактор + + + + 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 + Показать/Скрыть Редактор Нот + + + + Click here to show or hide the Piano-Roll. With the help of the Piano-Roll you can edit melodies in an easy way. + Запуск редатора нот. С его помощью вы можете легко редактировать мелодии. + + + + Show/hide Automation Editor + Показать/скрыть редактор автоматизации + + + + 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 + Показать/скрыть микшер ЭФ + + + + 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. + Скрыть/показать микшер ЭФфектов. Он является мощным инструментом для управления эффектами. Вы можете вставлять эффекты в различные каналы. + + + + Show/hide project notes + Показать/скрыть заметки проекта + + + + Click here to show or hide the project notes window. In this window you can put down your project notes. + Эта кнопка показывает/прячет окно с заметками. В этом окне вы можете помещать любые комментарии к своей композиции. + + + + Show/hide controller rack + Показать/скрыть управление контроллерами + + + + Untitled + Неназванный + + + + Recover session. Please save your work! + Восстановление сессии. Пожалуйста, сохраните свою работу! + + + + LMMS %1 + 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) + 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. + Пока что справка для LMMS не написана. +Вероятно, Вы сможете найти нужные материалы на http://lmms.sf.net/wiki . + + + + 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 + Включить обозначение нот в музыкальном редакторе + + + + MeterDialog + + + + Meter Numerator + Шкала чисел + + + + + Meter Denominator + Шкала делений + + + + TIME SIG + ПЕРИОД + + + + MeterModel + + + Numerator + Числитель + + + + Denominator + Знаменатель + + + + MidiController + + + MIDI Controller + Контроллер MIDI + + + + unnamed_midi_controller + нераспознанный миди контроллер + + 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. + Вы не установили SoundFont по умолчанию в параметрах (Правка->Настройки), поэтому после импорта миди файла звук воспроизводиться не будет. +Вам следует загрузить основной MiDi SoundFont, указать его в параметрах и попробовать снова. + + + 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. Вы не включили поддержку проигрывателя SoundFont2 при компиляции ЛММС, он используется для добавления основного звука в импортируемые Миди файлы, поэтому звука не будет после импорта этого миди файла. + Track - + Дорожка + + + + MidiJack + + + JACK server down + When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (title) + JACK-сервер не доступен - You have not 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. - + + The JACK server seems to be shuted down. + When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (dialog message) + JACK-сервер, похоже, не запущен. + + + + MidiPort + + + Input channel + Вход + + + + Output channel + Выход + + + + Input controller + Контроллер входа + + + + Output controller + Контроллер выхода + + + + Fixed input velocity + Постоянная скорость ввода + + + + Fixed output velocity + Постоянная скорость вывода + + + + Fixed output note + Постоянный вывод нот + + + + Output MIDI program + Программа для вывода MiDi + + + + Base velocity + Базовая скорость + + + + Receive MIDI-events + Принимать события MIDI + + + + Send MIDI-events + Отправлять события MIDI + + + + MidiSetupWidget + + + DEVICE + УСТРОЙСТВО MonstroInstrument + + Osc 1 Volume + Осциллятор 1 громкость + + + + Osc 1 Panning + Осциллятор 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 + Осциллятор 2 громкость + + + + Osc 2 Panning + Осциллятор 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 + Осциллятор 3 громкость + + + + Osc 3 Panning + Осциллятор 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 + + + + + LFO 1 Attack + + + + + LFO 1 Rate + + + + + LFO 1 Phase + + + + + LFO 2 Waveform + + + + + LFO 2 Attack + + + + + LFO 2 Rate + + + + + LFO 2 Phase + + + + + Env 1 Pre-delay + + + + + Env 1 Attack + + + + + 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 + Кривая 2 Наклон + + + + Osc2-3 modulation + + + + Selected view - + Выбранный вид + + Vol1-Env1 + + + + + Vol1-Env2 + + + + + Vol1-LFO1 + + + + + Vol1-LFO2 + + + + + Vol2-Env1 + + + + + Vol2-Env2 + + + + + Vol2-LFO1 + + + + + Vol2-LFO2 + + + + + Vol3-Env1 + + + + + Vol3-Env2 + + + + + Vol3-LFO1 + + + + + Vol3-LFO2 + + + + + Phs1-Env1 + + + + + Phs1-Env2 + + + + + Phs1-LFO1 + + + + + Phs1-LFO2 + + + + + Phs2-Env1 + + + + + Phs2-Env2 + + + + + Phs2-LFO1 + + + + + Phs2-LFO2 + + + + + Phs3-Env1 + + + + + Phs3-Env2 + + + + + Phs3-LFO1 + + + + + Phs3-LFO2 + + + + + Pit1-Env1 + + + + + Pit1-Env2 + + + + + Pit1-LFO1 + + + + + Pit1-LFO2 + + + + + Pit2-Env1 + + + + + Pit2-Env2 + + + + + Pit2-LFO1 + + + + + Pit2-LFO2 + + + + + Pit3-Env1 + + + + + Pit3-Env2 + + + + + Pit3-LFO1 + + + + + Pit3-LFO2 + + + + + PW1-Env1 + + + + + PW1-Env2 + + + + + PW1-LFO1 + + + + + PW1-LFO2 + + + + + Sub3-Env1 + + + + + Sub3-Env2 + + + + + Sub3-LFO1 + + + + + Sub3-LFO2 + + + + + Sine wave Синусоида + Bandlimited Triangle wave Ограниченная по частоте треугольная волна + Bandlimited Saw wave Ограниченная по частоте острая волна + Bandlimited Ramp wave - + Ограничение по частоте ниспадающая волна + Bandlimited Square wave Ограниченная по частоте квадратная волна + Bandlimited Moog saw wave - Ограниченная по частоте Муг острая волна + Ограниченная по частоте Муг-зигзаг волна + + Soft square wave Сглаженная квадратная волна + Absolute sine wave - + + + Exponential wave Экспоненциальная волна + White noise Белый шум + Digital Triangle wave Цифровая треугольная волна + Digital Saw wave Цифровая острая волна + Digital Ramp wave - + + Digital Square wave Цифровая квадратная волна + Digital Moog saw wave Цифровая Муг острая волна + Triangle wave Треугольная волна + Saw wave Зигзаг + Ramp wave - + + Square wave Квадрат + Moog saw wave - + + Abs. sine wave - + + Random Случайно + Random smooth Случайное сглаживание - - Osc 1 volume - - - - Osc 1 panning - - - - 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 - - - - Osc 2 panning - - - - 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 - - - - Osc 3 panning - - - - Osc 3 coarse detune - - - - Osc 3 sub-oscillator mix - - - - Osc 3 waveform 1 - - - - Osc 3 waveform 2 - - - - Osc 3 sync hard - - - - Osc 3 Sync reverse - - - - LFO 1 waveform - - - - LFO 1 attack - - - - LFO 1 rate - - - - LFO 1 phase - - - - LFO 2 waveform - - - - LFO 2 attack - - - - LFO 2 rate - - - - LFO 2 phase - - - - Env 1 pre-delay - - - - Env 1 attack - - - - 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 - - - - Osc 2+3 modulation - - - - Osc 1 - Vol env 1 - - - - Osc 1 - Vol env 2 - - - - Osc 1 - Vol LFO 1 - - - - Osc 1 - Vol LFO 2 - - - - Osc 2 - Vol env 1 - - - - Osc 2 - Vol env 2 - - - - Osc 2 - Vol LFO 1 - - - - Osc 2 - Vol LFO 2 - - - - Osc 3 - Vol env 1 - - - - Osc 3 - Vol env 2 - - - - Osc 3 - Vol LFO 1 - - - - Osc 3 - Vol LFO 2 - - - - Osc 1 - Phs env 1 - - - - Osc 1 - Phs env 2 - - - - Osc 1 - Phs LFO 1 - - - - Osc 1 - Phs LFO 2 - - - - Osc 2 - Phs env 1 - - - - Osc 2 - Phs env 2 - - - - Osc 2 - Phs LFO 1 - - - - Osc 2 - Phs LFO 2 - - - - Osc 3 - Phs env 1 - - - - Osc 3 - Phs env 2 - - - - Osc 3 - Phs LFO 1 - - - - Osc 3 - Phs LFO 2 - - - - Osc 1 - Pit env 1 - - - - Osc 1 - Pit env 2 - - - - Osc 1 - Pit LFO 1 - - - - Osc 1 - Pit LFO 2 - - - - Osc 2 - Pit env 1 - - - - Osc 2 - Pit env 2 - - - - Osc 2 - Pit LFO 1 - - - - Osc 2 - Pit LFO 2 - - - - Osc 3 - Pit env 1 - - - - Osc 3 - Pit env 2 - - - - Osc 3 - Pit LFO 1 - - - - Osc 3 - Pit LFO 2 - - - - Osc 1 - PW env 1 - - - - Osc 1 - PW env 2 - - - - Osc 1 - PW LFO 1 - - - - Osc 1 - PW LFO 2 - - - - Osc 3 - Sub env 1 - - - - Osc 3 - Sub env 2 - - - - Osc 3 - Sub LFO 1 - - - - Osc 3 - Sub LFO 2 - - MonstroView + Operators view Операторский вид + + 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 Матричный вид + + 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. + Матричный вид содержит матрицу модуляции. Здесь можно определить модуляционное отношение между разными операторами. Каждый слышимый оператор (осцилляторы 1-3) имеют 3-4 свойства, которые можно модулировать любыми модуляторами. Используя больше модуляций увеличивается нагрузка на процессор. + +Вид делится на цели модуляции, сгруппированные на целевой осциллятор. Доступные цели : громкость, тон, фаза, ширина пульсации и отношение с подчиненным (под-) осциллятором. Отметим что некоторые цели определены только для одного осциллятора. + +Каждая цель модуляции имеет 4 регулятора, один на каждый модулятор. По умолчанию регуляторы установлены на 0, то есть без модуляции. Включая регулятор на 1 ведёт к тому, что модулятор влияет на цель модуляции на столько на сколько возможно. Включая его на -1 делает то же, но с обратной модуляцией. + + + + + Volume Громкость + + + Panning Баланс + + + Coarse detune - + Грубая расстройка + + + semitones полутона - cents - + + + Finetune left + + + + + + cents + + + + + + 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 Вступление + + Rate Частота выборки + + Phase - + + + Pre-delay - + Пре-дилэй + + Hold Удерживание + + Decay Затихание + + Sustain Выдержка + + Release Убывание + + Slope - + Фронт + + Mix Osc2 with Osc3 + Смешать Осц2 с Осц3 + + + + Modulate amplitude of Osc3 with Osc2 + Модулировать амплитуду осциллятора 3 сигналом с осц2 + + + + Modulate frequency of Osc3 with Osc2 + Модулировать частоту осциллятора 3 сигналом с осц2 + + + + Modulate phase of Osc3 with Osc2 + Модулировать фазу Осц3 осциллятором2 + + + + The CRS knob changes the tuning of oscillator 1 in semitone steps. + Регулятор CRS меняет настройку осциллятора 1 в размере полутона. + + + + The CRS knob changes the tuning of oscillator 2 in semitone steps. + Регулятор CRS меняет настройку осциллятора 2 в размере полутона. + + + + The CRS knob changes the tuning of oscillator 3 in semitone steps. + Регулятор CRS меняет настройку осциллятора 3 в размере полутона. + + + + + + + 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. + FTL и FTR меняют подстройку осциллятора для левого и правого канала соответственно. Они могут добавить стерео расстраивания осциллятора, которое расширяет стерео картину и создаёт иллюзию космоса. + + + + + + The SPO knob modifies the difference in phase between left and right channels. Higher difference creates a wider stereo image. + Регулятор SPO меняет фазовую разницу между левым и правым каналами. Высокая разница создаёт более широкую стерео картину. + + + + 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. + PW регулятор контролирует ширину пульсаций, также известную как рабочий цикл осциллятора 1. Осциллятор 1 это цифровой импульсный волновой генератор, он не воспроизводит сигнал с ограниченной полосой, это значит, что его можно использовать как слышимый осциллятор, но приведёт к наложению сигналов (или сглаживанию). Его можно использовать и как не слышимый источник синхронизирующего сигнала, для использования в синхронизации осцилляторов 2 и 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. + Посылать синхронизацию при повышении: при включении, сигнал синхронизации посылается каждый раз когда состояние осциллятора 1 меняется с низкого на высокое, т.е. когда амплитуда меняется от -1 до 1. +Тон осциллятора 1, фаза и ширина пульсаций может влиять на время синхронизации, но громкость не имеет эффекта. Сигнал синхронизации посылается независимо для левого и правого каналов. + + + + 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. + Посылать синхронизацию при падении: при включении, сигнал синхронизации посылается каждый раз когда состояние осциллятора 1 меняется с выского на низкое, т.е. когда амплитуда меняется от 1 до -1. +Тон осциллятора 1, фаза и ширина пульсаций может влиять на время синхронизации, но громкость не имеет эффекта. Сигнал синхронизации посылается независимо для левого и правого каналов. + + + + + Hard sync: Every time the oscillator receives a sync signal from oscillator 1, its phase is reset to 0 + whatever its phase offset is. + Жесткая синхр. : Каждый раз при получении осциллятором сигнала синхронизации от осциллятора 1, его фаза сбрасывается до 0 + его граница фазы, какой бы она ни была. + + + + + Reverse sync: Every time the oscillator receives a sync signal from oscillator 1, the amplitude of the oscillator gets inverted. + Обратная синхронизация: Каждый раз при получении сигнала синхронизации от осциллятора 1, амплитуда осцилятора переворачивается. + + + + Choose waveform for oscillator 2. + Выбрать форму волны для осциллятора 2. + + + + Choose waveform for oscillator 3's first sub-osc. Oscillator 3 can smoothly interpolate between two different waveforms. + Выберите форму волны для первого доп. осциллятора осциллятора 3. Осциллятор 3 может мягко переходить между двумя разными волнами. + + + + Choose waveform for oscillator 3's second sub-osc. Oscillator 3 can smoothly interpolate between two different waveforms. + Выберите форму волны для второго доп. осциллятора осциллятора 3. Осциллятор 3 может мягко переходить между двумя разными волнами. + + + + 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. + SUB меняет смешивание двух доп. осяцилляторов осциллятора 3. Каждый доп. осц. может быть установлен для создания разных волн и осциллятор 3 может мягко переходить между ними. Все входящие модуляции для осциллятора 3 применяются на оба доп.осц./волны одним и тем же образом. + + + + 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. + В дополнение к выделенным модуляторам Монстро позволяет выходу осциллятора 2 модулировать осцллятор 3. + +Смешанный (Mix) режим значит без модуляции: выходы осцилляторов просто смешиваются друг с другом. + + + + 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. + В дополнение к выделенным модуляторам Монстро позволяет выходу осциллятора 2 модулировать осцллятор 3. + +AM режим значит Амплитуда Модуляции: Осциллятор 2 модулирует амплитуду (громкость) осциллятора 3. + + + + 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. + В дополнение к выделенным модуляторам Монстро позволяет выходу осциллятора 2 модулировать осцллятор 3. + +FM (ЧМ) режим значит Частотная Модуляция: Осциллятор 2 модулирует частоту (pitch, тональность) осциллятора 3. Частота модуляции происходит в фазе модуляции, которая даёт более стабильный общий тон, чем "чистая" частотная модуляция. + + + + 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. + В дополнение к выделенным модуляторам Монстро позволяет выходу осциллятора 2 модулировать осцллятор 3. + +PM (ФМ) режим значит фазовая модуляция: Осциллятор 2 модулирует фазу осциллятора 3. Это отличается от частотной модуляции тем, что изменения фаз не суммируются. + + + + 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... + Выберите форму волны для LFO 1 (НизкоЧастотныйГенератор). +"Random" (Случайно) и "Random-smooth" (случайное сглаживание) - это специальные волны: они создают случаный сигнал, где частота LFO контролирует как часто изменяется состояние генератора (LFO). +Сглаженная версия переходит между этими состояниями с косинусоидальной интерплояцией. Эти случайные режимы могут быть использованы, чтобы дать "жизни" вашим настройкам - добавить немного аналоговой непредсказуемости... + + + + 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... + Выберите форму волны для LFO 2 (НизкоЧастотныйГенератор). +"Random" (Случайно) и "Random-smooth" (случайное сглаживание) - это специальные волны: они создают случаный сигнал, где частота LFO контролирует как часто изменяется состояние генератора (LFO). +Сглаженная версия переходит между этими состояниями с косинусоидальной интерплояцией. Эти случайные режимы могут быть использованы, чтобы дать "жизни" вашим настройкам - добавить немного аналоговой непредсказуемости... + + + + + Attack causes the LFO to come on gradually from the start of the note. + Атака отвечает за плавность поведения LFO от начала ноты. + + + + + Rate sets the speed of the LFO, measured in milliseconds per cycle. Can be synced to tempo. + Rate (Частота) устанавливает скорость LFO, измеряемую в миллисекундах за цикл. Может синхронизироваться с темпом. + + + + + PHS controls the phase offset of the LFO. + PHS контролирует сдвиг фазы LFO (НЧГ). + + + + + PRE, or pre-delay, delays the start of the envelope from the start of the note. 0 means no delay. + PRE предзадержка, задерживает старт огибающей от начала ноты. 0 значит без задержки. + + + + + ATT, or attack, controls how fast the envelope ramps up at start, measured in milliseconds. A value of 0 means instant. + ATT атака контролирует как быстро огибающая наращивается на старте, измеряясь в милисекундах. Значение 0 значит мгновенно. + + + + + HOLD controls how long the envelope stays at peak after the attack phase. + HOLD (УДЕРЖ) контролирует как долго огибающая остаётся на пике после фазы атаки. + + + + + 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. + DEC (decay) затухание контролирует как быстро огибающая спадает с пикового значения, измеряется в милисекундах, как долго будет идти с пика до нуля. Реальное затухание может быть короче, если используется выдержка. + + + + + 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. + SUS (sustain) выдержка, контролирует уровень огибающей. Затухание фазы не пойдёт ниже этого уровня пока нота удерживается. + + + + + 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. + REL (release) отпуск контролирует как долго нота отпускается, измеряясь в долготе падения от пика до нуля. Реальный отпуск может быть короче, в зависимости от фазы, в которой нота отпущена. + + + + + 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. + Регулятор наклона контролирует кривую или образ огибающей. Значение 0 создаёт прямые подъёмы и спады. Отрицательные величины создают кривые с замедленным началом, быстрым пиком и снова замедленным спадом. Позитивные значения создают кривые которые начинаются и кончаются быстро, но долбше остаются на пиках. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Modulation amount Глубина модуляции - - Fine tune left - - - - Fine tune right - - - - Mix osc 2 with osc 3 - - - - Modulate amplitude of osc 3 by osc 2 - - - - Modulate frequency of osc 3 by osc 2 - - - - Modulate phase of osc 3 by osc 2 - - MultitapEchoControlDialog + Length Длина + Step length: - + Длина шага: + Dry - + Высушить + + Dry Gain: + + + + Stages - + + + Lowpass stages: + + + + Swap inputs - + Переставить входы местами - Dry gain: - - - - Low-pass stages: - - - - Swap left and right input channels for reflections - + + Swap left and right input channel for reflections + Поменять вход левого и правого канала для отзвуков NesInstrument - Channel 2 Coarse detune - + + Channel 1 Coarse detune + Канал 1 - грубая расстройка + + Channel 1 Volume + Громкость 1 канала + + + + Channel 1 Envelope length + Канал 1 - Длина огибающей + + + + Channel 1 Duty cycle + + + + + Channel 1 Sweep amount + + + + + Channel 1 Sweep rate + + + + + Channel 2 Coarse detune + + + + Channel 2 Volume Громкость 2 канала + + Channel 2 Envelope length + + + + + Channel 2 Duty cycle + + + + + Channel 2 Sweep amount + + + + + Channel 2 Sweep rate + + + + + Channel 3 Coarse detune + + + + + Channel 3 Volume + Громкость 3 канала + + + + Channel 4 Volume + Громкость 4 канала + + + + Channel 4 Envelope length + + + + + Channel 4 Noise frequency + + + + + Channel 4 Noise frequency sweep + + + + Master volume Основная громкость + Vibrato Вибрато - - Channel 1 coarse detune - - - - Channel 1 volume - Громкость первого канала - - - Channel 1 envelope length - - - - Channel 1 duty cycle - - - - Channel 1 sweep amount - - - - Channel 1 sweep rate - - - - Channel 2 envelope length - - - - Channel 2 duty cycle - - - - Channel 2 sweep amount - - - - Channel 2 sweep rate - - - - Channel 3 coarse detune - - - - Channel 3 volume - Громкость третьего канала - - - Channel 4 volume - Громкость четвёртого канала - - - Channel 4 envelope length - - - - Channel 4 noise frequency - - - - Channel 4 noise frequency sweep - - NesInstrumentView + + + + Volume Громкость + + + Coarse detune - + Грубая расстройка + + + Envelope length - + Длина огибающей + Enable channel 1 - + Включить канал 1 + Enable envelope 1 - + Включить кривую 1 + Enable envelope 1 loop - + + Enable sweep 1 - + + + Sweep amount - + Амплитуда биений + + Sweep rate - + Частота биений + + 12.5% Duty cycle - + 12.5% Рабочий цикл + + 25% Duty cycle - + 25% Рабочий цикл + + 50% Duty cycle - + 50% Рабочий цикл + + 75% Duty cycle - + 75% Рабочий цикл + Enable channel 2 - + Включить канал 2 + Enable envelope 2 - + Включить кривую 2 + Enable envelope 2 loop - + Включить повтор кривой 2 + Enable sweep 2 - + + Enable channel 3 - + + Noise Frequency - + Частота шума + Frequency sweep - + + Enable channel 4 - + + Enable envelope 4 - + + Enable envelope 4 loop - + + Quantize noise frequency when using note frequency - + + Use note frequency for noise - + Использовние частоты ноты для шума + Noise mode - + Режим шума + + Master Volume + Мастер-громкость + + + Vibrato Вибрато - - Master volume - Основная громкость - - - - OpulenzInstrument - - Patch - Патч - - - Op 1 attack - - - - Op 1 decay - - - - Op 1 sustain - - - - Op 1 release - - - - Op 1 level - - - - Op 1 level scaling - - - - Op 1 frequency multiplier - - - - Op 1 feedback - - - - 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 multiplier - - - - Op 2 key scaling rate - - - - Op 2 percussive envelope - - - - Op 2 tremolo - - - - Op 2 vibrato - - - - Op 2 waveform - - - - FM - FM - - - Vibrato depth - - - - Tremolo depth - - - - - OpulenzInstrumentView - - Attack - Вступление - - - Decay - Затихание - - - Release - Убывание - - - Frequency multiplier - - OscillatorObject - Osc %1 volume - Громкость осциллятора %1 - - - Osc %1 panning - Стереобаланс для осциллятора %1 - - - Osc %1 coarse detuning - Подстройка осциллятора %1 грубая - - - Osc %1 fine detuning left - Подстройка левого канала осциллятора %1 тонкая - - - Osc %1 fine detuning right - Подстройка правого канала осциллятора %1 тонкая - - - Osc %1 phase-offset - Сдвиг фазы для осциллятора %1 - - - Osc %1 stereo phase-detuning - Подстройка стерео-фазы осциллятора %1 - - - Osc %1 wave shape - Гладкость сигнала осциллятора %1 - - - Modulation type %1 - Тип модуляции %1 - - + Osc %1 waveform Форма сигнала осциллятора %1 + Osc %1 harmonic Осц %1 гармонический + + + + Osc %1 volume + Громкость осциллятора %1 + + + + + Osc %1 panning + Стереобаланс для осциллятора %1 + + + + + Osc %1 fine detuning left + Подстройка левого канала осциллятора %1 тонкая + + + + Osc %1 coarse detuning + Подстройка осциллятора %1 грубая + + + + Osc %1 fine detuning right + Подстройка правого канала осциллятора %1 тонкая + + + + Osc %1 phase-offset + Сдвиг фазы для осциллятора %1 + + + + Osc %1 stereo phase-detuning + Подстройка стерео-фазы осциллятора %1 + + + + Osc %1 wave shape + Гладкость сигнала осциллятора %1 + + + + Modulation type %1 + Тип модуляции %1 + PatchesDialog + Qsynth: Channel Preset - + + Bank selector - + Выбор банка + Bank Банк + Program selector Выбор программ + Patch Патч + Name Имя + OK ОК + Cancel Отмена @@ -2320,244 +6765,1727 @@ PatmanView + + Open other patch + Открыть другой патч + + + + Click here to open another patch-file. Loop and Tune settings are not reset. + Нажмите чтобы открыть другой патч-файл. Цикличность и настройки при этом сохранятся. + + + Loop Повтор + Loop mode Режим повтора + + Here you can toggle the Loop mode. If enabled, PatMan will use the loop information available in the file. + Здесь включается/выключается режим повтора, при включёнии PatMan будет использовать информацию о повторе из файла. + + + Tune Подстроить + Tune mode Тип подстройки + + Here you can toggle the Tune mode. If enabled, PatMan will tune the sample to match the note's frequency. + Здесь включается/выключается режим подстройки. Если он включён, то PatMan изменит запись так, чтобы она совпадала по частоте с нотой. + + + No file selected Не выбран файл + Open patch file Открыть патч-файл + Patch-Files (*.pat) Патч-файлы (*.pat) + + + PatternView - Open patch - + + use mouse wheel to set velocity of a step + + + + + double-click to open in Piano Roll + Двойной щелчок открывает в Редакторе Нот + + + + Open in piano-roll + Открыть в редакторе нот + + + + Clear all notes + Очистить все ноты + + + + Reset name + Сбросить название + + + + Change name + Переименовать + + + + Add steps + Добавить такты + + + + Remove steps + Удалить такты + + + + Clone Steps + Клонировать такты + + + + 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. + Из-за ошибки в старой версии LMMS контроллеры вершин не могут правильно подключаться. Пж. убедитесь, что контроллеры вершин правильно подсоединены и пересохраните этот файл, извините, за причинённые неудобства. + + + + PeakControllerDialog + + + PEAK + ПИК + + + + LFO Controller + Контроллер LFO PeakControllerEffectControlDialog + BASE БАЗА - Modulation amount: - Глубина модуляции: - - - Attack: - Вступление: - - - Release: - Убывание: + + Base amount: + Базовое значение: + AMNT ГЛУБ + + Modulation amount: + Глубина модуляции: + + + MULT МНОЖ + + Amount Multiplicator: + Величина множителя: + + + ATCK ВСТУП + + Attack: + Вступление: + + + DCAY СПАД - Treshold: - + + Release: + Убывание: + TRSH - + ПОР - Base: - - - - Amount multiplicator: - - - - Mute output - Заглушить вывод - - - Absolute value - + + Treshold: + Порог: PeakControllerEffectControls + Base value Опорное значение + Modulation amount Глубина модуляции - Mute output - Заглушить вывод - - + Attack Вступление + Release Убывание + Treshold - + Порог - Absolute value - + + Mute output + Заглушить вывод - Amount multiplicator - + + Abs Value + Абс значение + + + + Amount Multiplicator + Величина множителя + + + + 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% + Громкость %1% + + + + Panning: %1% left + Баланс: %1% лево + + + + Panning: %1% right + Баланс: %1% право + + + + Panning: center + Баланс: центр + + + + Please open a pattern by double-clicking on it! + Откройте мелодию с помощью двойного щелчка мышью! + + + + + Please enter a new value between %1 and %2: + Введите новое значение от %1 до %2: + + + + PianoRollWindow + + + Play/pause current pattern (Space) + Игра/Пауза текущей мелодии (Пробел) + + + + Record notes from MIDI-device/channel-piano + Записать ноты с музыкального инструмента (MIDI)/канала + + + + Record notes from MIDI-device/channel-piano while playing song or BB track + Записать ноты с цифрового музыкального инструмента (MIDI) во время воспроизведения композиции или дорожки Ритм-Баса + + + + 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. + Нажмите эту кнопку, если вы хотите записать ноты с устройства MIDI или виртуального синтезатора соответствующего канала. Позже вы сможете отредактировать записанную мелодию. + + + + 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. + Нажмите эту кнопку, если вы хотите записать ноты с устройства MIDI или виртуального синтезатора соответствующего канала. Во время записи все ноты записываются в эту мелодию, и вы будете слышать композицию или РБ дорожку на заднем плане. + + + + Click here to stop playback of current pattern. + Нажмите здесь, если вы хотите остановить воспроизведение текущей мелодии. + + + + Edit actions + Правка: + + + + Draw mode (Shift+D) + Режим рисования (Shift+D) + + + + Erase mode (Shift+E) + Режим стирания (Shift+E) + + + + Select mode (Shift+S) + Режим выбора нот (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. + Режим рисования нот, в нём вы можете добавлять/перемещать и изменять длительность одиночных нот. Это режим по умолчанию и используется большую часть времени. +Для включения этого режима можно использовать комбинацию клавиш Shift+D, удерживайте %1 для временного переключения в режим выбора. + + + + 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. + Режим стирания. В этом режиме вы можете стирать ноты. Для включения этого режима можно использовать комбинацию клавиш Shift+E. + + + + 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. + Режим выделения. В этом режиме можно выделять ноты, можно также удерживать %1 в режиме рисования, чтобы можно было на время войти в режим выделения. + + + + 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. + Нажмите здесь для активации Pitch Blend режима. Вы сможете кликнуть на ноту, чтобы начать автоматическией детюн. Можно использовать это для "скольжения" от одной ноты к другой. Можно включить этот режим при помощи Shift + T. + + + + Quantize + + + + + Copy paste controls + Копировать-вставить управление + + + + Cut selected notes (%1+X) + Переместить выделенные ноты в буфер (%1+X) + + + + Copy selected notes (%1+C) + Копировать выделенные ноты в буфер (%1+X) + + + + Paste notes from clipboard (%1+V) + Вставить ноты из буфера (%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. + "Q" обозначает квантизацию и контролирует размер нотной сетки и контрольные точки притяжения. С меньшей величиной квантизации, можно рисовать короткие ноты в редаторе нот и более точно контролировать точки в Редакторе Автоматизации. + + + + 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 + Позволяет выбрть длину новой ноты. "Последняя Нота" значит, что LMMS будет использовать длину ноты, изменённой в последний раз + + + + 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! + Функция напрямую связана с контекстным меню на виртуальной клавиатуре слева в нотном редакторе. После того, как выбран масштаб в выпадающем меню, можно кликнуть правой кнопкой в виртуальной клавиатуре и выбрать "Mark Current Scale" (Отметить текущий масштаб). LMMS подсветит все ноты лежащие в выбранном масштабе для выбранной клавиши! + + + + 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. + Позволяет выбрать аккорд, который LMMS затем сможет нарисовать или подсветить. В этом меню можно найти ниболее популярные аккорды. После того, как вы выбрали аккорд, кликните в любом месте, чтобы поставить его и правым кликом по виртуальной клавиатуре открывается контекстное меню и подсветка аккорда. Для возврата в режим одной ноты нужно выбрать "Без аккорда" в этом выпадающем меню. + + + + + Piano-Roll - %1 + Нотный редактор - %1 + + + + + Piano-Roll - no pattern + Пианоролл — нет шаблона + + + + PianoView + + + Base note + Опорная нота + + + + Plugin + + + Plugin not found + Модуль не найден + + + + The plugin "%1" wasn't found or could not be loaded! +Reason: "%2" + Модуль «%1» отсутствует либо не может быть загружен! +Причина: «%2» + + + + Error while loading plugin + Ошибка загрузки модуля + + + + Failed to load plugin "%1"! + Не получилось загрузить модуль «%1»! + + + + PluginBrowser + + + Instrument Plugins + Плагины инструментов + + + + Instrument browser + Обзор инструментов + + + + Drag an instrument into either the Song-Editor, the Beat+Bassline Editor or into an existing instrument track. + Вы можете переносить нужные вам инструменты из этой панели в музыкальный, ритм-бас редактор или в существующую дорожку инструмента. + + + + PluginFactory + + + Plugin not found. + Плагин не найден + + + + LMMS plugin %1 does not have a plugin descriptor named %2! + ЛММС плагин %1 не имеет описания плагина с именем %2! + + + + ProjectNotes + + + Project Notes + Показать/скрыть заметки к проекту + + + + Enter project notes here + Напишите заметки, касающиеся проекта здесь + + + + Edit Actions + Правка + + + + &Undo + &U Отменить + + + + %1+Z + %1+Z + + + + &Redo + &R Повторить + + + + %1+Y + %1+Y + + + + &Copy + &C Копировать + + + + %1+C + %1+C + + + + Cu&t + &t Вырезать + + + + %1+X + %1+X + + + + &Paste + &P Вставить + + + + %1+V + %1+V + + + + Format Actions + Форматирование + + + + &Bold + &b Полужирный + + + + %1+B + %1+B + + + + &Italic + &i Курсив + + + + %1+I + %1+I + + + + &Underline + &U Подчеркнутый + + + + %1+U + %1+U + + + + &Left + &L По левому краю + + + + %1+L + %1+L + + + + C&enter + По &центру + + + + %1+E + + + + + &Right + + + + + %1+R + + + + + &Justify + &Выравнивать + + + + %1+J + + + + + &Color... + &Цвет... + + + + ProjectRenderer + + + WAV-File (*.wav) + Файл WAV (*.wav) + + + + Compressed OGG-File (*.ogg) + Сжатый файл OGG (*.ogg) + + + FLAC-File (*.flac) + + + + + Compressed MP3-File (*.mp3) + QWidget + + + Name: Название: + + Maker: Создатель: + + Copyright: Правообладатель: + + Requires Real Time: Требуется обработка в реальном времени: + + + + + + Yes Да + + + + + + No Нет + + Real Time Capable: Работа в реальном времени: + + In Place Broken: Вместо сломанного: + + Channels In: Каналы в: + + Channels Out: Каналы из: + + File: %1 + Файл: %1 + + + File: Файл: + + + RenameDialog - File: %1 - Файл: %1 + + Rename... + Переименовать... ReverbSCControlDialog + Input Ввод + + Input Gain: + Входная мощность: + + + Size Размер + Size: Размер: + Color Цвет + Color: Цвет: + Output Вывод - Input gain: - Входная мощность: - - - Output gain: - Выходная мощность: + + Output Gain: + Выходная мощность: ReverbSCControls + + Input Gain + Входная мощность + + + Size Размер + Color Цвет - Input gain - Входная мощность + + Output Gain + Выходная мощность + + + + SampleBuffer + + + Fail to open file + Не удается открыть файл - Output gain - Выходная мощность + + 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) + Все аудио файлы (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + + + + Wave-Files (*.wav) + Файлы Wave (*.wav) + + + + OGG-Files (*.ogg) + Файлы OGG (*.ogg) + + + + DrumSynth-Files (*.ds) + Файлы DrumSynth (*.ds) + + + + FLAC-Files (*.flac) + Файлы FLAC (*.flac) + + + + SPEEX-Files (*.spx) + Файлы SPEEX (*.spx) + + + + VOC-Files (*.voc) + Файлы VOC (*.voc) + + + + AIFF-Files (*.aif *.aiff) + Файлы AIFF (*.aif *.aiff) + + + + AU-Files (*.au) + Файлы AU (*.au) + + + + RAW-Files (*.raw) + Файлы RAW (*.raw) + + + + SampleTCOView + + + double-click to select sample + Выберите запись двойным нажатием мыши + + + + Delete (middle mousebutton) + Удалить (средняя кнопка мыши) + + + + Cut + Вырезать + + + + Copy + Копировать + + + + Paste + Вставить + + + + Mute/unmute (<%1> + middle click) + Заглушить/включить (<%1> + средняя кнопка мыши) + + + + SampleTrack + + + Volume + Громкость + + + + Panning + Баланс + + + + + Sample track + Дорожка записи + + + + SampleTrackView + + + Track volume + Громкость дорожки + + + + Channel volume: + Громкость канала: + + + + VOL + ГРОМ + + + + Panning + Баланс + + + + Panning: + Баланс: + + + + PAN + БАЛ + + + + SetupDialog + + + Setup LMMS + Настройка 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 + Синхронизировать VST плагины с хостом воспроизведения + + + + 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 + Встроить с использованием QT API + + + + Embed using native Win32 API + Встроить с использованием Win32 API + + + + Embed using XEmbed protocol + Встроить с использованием протокола XEmbed + + + + LANGUAGE + ЯЗЫК + + + + + Paths + Пути + + + + Directories + Папки + + + + LMMS working directory + Рабочий каталог LMMS + + + + Themes directory + Папка тем + + + + Background artwork + Фоновое изображение + + + + VST-plugin directory + Каталог модулей VST + + + + GIG directory + Папка GIG + + + + SF2 directory + Папка SF2 + + + + LADSPA plugin directories + Папка плагинов LADSPA + + + + STK rawwave directory + Каталог STK rawwave + + + + Default Soundfont File + Основной Soundfont файл + + + + + 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 + Показывать указатель воспроизведения в процессоре аудио файлов (AFP) + + + + + Audio settings + Параметры звука + + + + AUDIO INTERFACE + ЗВУКОВАЯ СИСТЕМА + + + + + MIDI settings + Параметры MIDI + + + + MIDI INTERFACE + MIDI СИСТЕМА + + + + OK + ОК + + + + Cancel + Отменить + + + + Restart LMMS + Перезапустить LMMS + + + + Please note that most changes won't take effect until you restart LMMS! + Учтите, что большинство настроек не вступят в силу до перезапуска ЛММС! + + + + Frames: %1 +Latency: %2 ms + Фрагментов: %1 +Отклик: %2 + + + + 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. + Здесь вы можете настроить размер внутреннего звукового буфера LMMS. Меньшие значения дают меньшее время отклика программы, но повышают потребление ресурсов - это особенно заметно на старых машинах и системах, ядро которых не поддерживает приоритета реального времени. Если наблюдается прерывистый звук, попробуйте увеличить размер буфера. + + + + Choose LMMS working directory + Выбор рабочего каталога LMMS + + + + Choose your GIG directory + Выберите вашу папку GIG + + + + Choose your SF2 directory + Выберите вашу папку SF2 + + + + Choose your VST-plugin directory + Выбор своего каталога для модулей VST + + + + Choose artwork-theme directory + Выбор каталога с темой оформления для LMMS + + + + Choose LADSPA plugin directory + Выбор каталога с модулями LADSPA + + + + Choose STK rawwave directory + Выбор каталога STK rawwave + + + + Choose default SoundFont + Выбрать главный SoundFont + + + + Choose background artwork + Выбрать фоновое изображение + + + + minutes + Минуты + + + + minute + Минута + + + + Disabled + Отключено + + + + Auto-save interval: %1 + Интервал автосорхранения: %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. + Установить время между автоматическим бэкапом на %1. Не забывайте сохранять проект вручную. + + + + 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. + Пожалуйста, выберите желаемую звуковую систему. В зависимости от конфигурации во время компилирования программы вы можете использовать ALSA, JACK, OSS и другие. В нижней части окна настройки можно задать специфические параметры выбранной системы. + + + + 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. + Пожалуйста, выберите интерфейс MIDI. В зависимости от конфигурации во время компилирования программы вы можете использовать ALSA, OSS и другие. В нижней части окна настройки можно задать специфические параметры выбранного интерфейса. + + + + Song + + + Tempo + Темп + + + + Master volume + Основная громкость + + + + Master pitch + Основная тональность + + + + LMMS Error report + Отчет об ошибке LMMS + + + + Project saved + Проект сохранён + + + + The project %1 is now saved. + Проект %1 сохранён. + + + + Project NOT saved. + Проект НЕ СОХРАНЁН. + + + + The project %1 was not saved! + Проект %1 не сохранён! + + + + Import file + Импорт файла + + + + MIDI sequences + MiDi последовательности + + + + Hydrogen projects + Hydrogen проекты + + + + 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) + MIDI-файл (*.mid) + + + + The following errors occured while loading: + Следующие ошибки возникли при загрузке: + + + + 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. + Невозможно открыть файл %1, вероятно, нет разрешений на его чтение. +Пж. убедитесь, что есть по крайней мере права на чтение этого файла и попробуйте ещё раз. + + + + 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. + Невозможно открыть %1 для записи, возможно, нет разрешений на запись в этот файл, пж. удостоверьтесь, что есть доступ к этому файлу и попробуйте снова. + + + + Error in file + Ошибка в файле + + + + The file %1 seems to contain errors and therefore can't be loaded. + Файл %1 возможно содержит ошибки из-за которых не может загрузиться. + + + + Version difference + Версия отличается + + + + This %1 was created with LMMS %2. + %1 был создан в LMMS %2. + + + + template + шаблон + + + + project + проект + + + + Tempo + Темп + + + + TEMPO/BPM + ТЕМП/BPM + + + + tempo of song + Темп музыки + + + + 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). + Это значение задаёт темп музыки в ударах в минуту (англ. аббр. BPM). На каждый такт приходится четыре удара, так что темп в ударах в минуту фактически указывает, сколько четвертей такта проигрывается за минуту (или, что то же, количество тактов, проигрываемых за четыре минуты). + + + + High quality mode + Высокое качество + + + + + Master volume + Основная громкость + + + + master volume + основная громкость + + + + + Master pitch + Основная тональность + + + + master pitch + основная тональность + + + + Value: %1% + Значение: %1% + + + + Value: %1 semitones + Значение: %1 полутон(а/ов) + + + + SongEditorWindow + + + Song-Editor + Музыкальный редактор + + + + Play song (Space) + Начать воспроизведение (Пробел) + + + + Record samples from Audio-device + Записать сэмпл со звукового устройства + + + + Record samples from Audio-device while playing song or BB track + Записать сэмпл с аудио-устройства во время воспроизведения в музыкальном или ритм/бас редакторе + + + + Stop song (Space) + Остановить воспроизведение (Пробел) + + + + 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. + Нажмите, чтобы прослушать созданную мелодию. Воспроизведение начнётся с позиции курсора (зелёный треугольник); вы можете двигать его во время проигрывания. + + + + 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 + Действия трека + + + + Add beat/bassline + Добавить ритм/бас + + + + Add sample-track + Добавить дорожку записи + + + + Add automation-track + Добавить дорожку автоматизации + + + + Edit actions + Правка: + + + + Draw mode + Режим рисования + + + + Edit mode (select and move) + Правка (выделение/перемещение) + + + + Timeline controls + Управление временем + + + + Zoom controls + Приблизить управление SpectrumAnalyzerControlDialog + Linear spectrum Линейный спектр + Linear Y axis Линейная ось ординат (Y) @@ -2565,862 +8493,1485 @@ SpectrumAnalyzerControls + Linear spectrum Линейный спектр + Linear Y axis Линейная ось ординат (Y) + Channel mode Режим канала + + SubWindow + + + Close + Закрыть + + + + Maximize + Развернуть + + + + Restore + Восстановить + + + + TabWidget + + + + Settings for %1 + Настройки для %1 + + + + TempoSyncKnob + + + + Tempo Sync + Синхронизация темпа + + + + No Sync + Синхронизации нет + + + + Eight beats + Восемь ударов (две ноты) + + + + Whole note + Целая нота + + + + Half note + Полунота + + + + Quarter note + Четверть ноты + + + + 8th note + Восьмая ноты + + + + 16th note + 1/16 ноты + + + + 32nd note + 1/32 ноты + + + + Custom... + Своя... + + + + Custom + Своя + + + + Synced to Eight Beats + Синхро по 8 ударам + + + + Synced to Whole Note + Синхро по целой ноте + + + + Synced to Half Note + Синхро по половине ноты + + + + Synced to Quarter Note + Синхро по четверти ноты + + + + Synced to 8th Note + Синхро по 1/8 ноты + + + + Synced to 16th Note + Синхро по 1/16 ноты + + + + Synced to 32nd Note + Синхро по 1/32 ноты + + + + TimeDisplayWidget + + + click to change time units + нажми для изменения единиц времени + + + + MIN + МИН + + + + SEC + СЕК + + + + MSEC + мСЕК + + + + BAR + ДЕЛЕНИЕ + + + + BEAT + БИТ + + + + TICK + ТИК + + + + TimeLineWidget + + + Enable/disable auto-scrolling + Вкл/выкл автопрокрутку + + + + Enable/disable loop-points + Вкл/выкл точки петли + + + + After stopping go back to begin + После остановки переходить к началу + + + + After stopping go back to position at which playing was started + После остановки переходить к месту, с которого началось воспроизведение + + + + After stopping keep position + Оставаться на месте остановки + + + + + Hint + Подсказка + + + + Press <%1> to disable magnetic loop points. + Нажмите <%1>, чтобы убрать прилипание точек петли. + + + + Hold <Shift> to move the begin loop point; Press <%1> to disable magnetic loop points. + Зажмите <Shift> чтобы сдвинуть начало точек петли; Нажмите <%1>, чтобы убрать прилипание точек петли. + + + + Track + + + Mute + Тихо + + + + Solo + Соло + + TrackContainer + + Couldn't import file + Не могу импортировать файл + + + + Couldn't find a filter for importing file %1. +You should convert this file into a format supported by LMMS using another software. + Не могу найти фильтр для импорта файла %1. +Для подключения этого файла преобразуйте его в формат, поддерживаемый LMMS. + + + + Couldn't open file + Не могу открыть файл + + + + 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! + Не могу открыть файл %1 для записи. +Проверьте, обладаете ли вы правами на запись в выбранный файл и содержащий его каталог и попробуйте снова! + + + + Loading project... + Чтение проекта... + + + + Cancel Отменить + + Please wait... Подождите, пожалуйста... + + Loading cancelled + Загрузка отменена. + + + + Project loading was cancelled. + Загрузка проекта была отменена. + + + + Loading Track %1 (%2/Total %3) + + + + Importing MIDI-file... Импортирую файл MIDI... + + TrackContentObject + + + Mute + Тихо + + + + TrackContentObjectView + + + Current position + Текущая позиция + + + + + Hint + Подсказка + + + + Press <%1> and drag to make a copy. + Нажмите <%1> и тащите мышью, чтобы создать копию. + + + + Current length + Текущая длительность + + + + Press <%1> for free resizing. + Для свободного изменения размера нажмите <%1>. + + + + + %1:%2 (%3:%4 to %5:%6) + %1:%2 (от %3:%4 до %5:%6) + + + + Delete (middle mousebutton) + Удалить (средняя кнопка мыши) + + + + Cut + Вырезать + + + + Copy + Копировать + + + + Paste + Вставить + + + + Mute/unmute (<%1> + middle click) + Тихо/громко (<%1> + middle click) + + + + TrackOperationsWidget + + + Press <%1> while clicking on move-grip to begin a new drag'n'drop-action. + Зажмите <Сtrl> и нажимайте мышь во время движения, чтобы начать новую переброску. + + + + Actions for this track + Действия для этой дорожки + + + + Mute + Тихо + + + + + Solo + Соло + + + + Mute this track + Заглушить эту дорожку + + + + Clone this track + Клонировать дорожку + + + + Remove this track + Удалить дорожку + + + + Clear this track + Очистить эту дорожку + + + + FX %1: %2 + ЭФ %1: %2 + + + + Assign to new FX Channel + Назначить на другой канал ЭФфектов + + + + Turn all recording on + Включить всё на запись + + + + Turn all recording off + Выключить всю запись + + TripleOscillatorView + + Use phase modulation for modulating oscillator 1 with oscillator 2 + Модулировать фазу осциллятора 2 сигналом с 1 + + + + Use amplitude modulation for modulating oscillator 1 with oscillator 2 + Модулировать амплитуду осциллятора 2 сигналом с первого + + + + Mix output of oscillator 1 & 2 + Смешать выводы 1 и 2 осцилляторов + + + Synchronize oscillator 1 with oscillator 2 Синхронизировать первый осциллятор по второму + + Use frequency modulation for modulating oscillator 1 with oscillator 2 + Модулировать частоту осциллятора 2 сигналом с 1 + + + + Use phase modulation for modulating oscillator 2 with oscillator 3 + Модулировать фазу осциллятора 3 сигналом с 2 + + + + Use amplitude modulation for modulating oscillator 2 with oscillator 3 + Модулировать амплитуду осциллятора 3 сигналом с 2 + + + + Mix output of oscillator 2 & 3 + Совместить вывод осцилляторов 2 и 3 + + + Synchronize oscillator 2 with oscillator 3 Синхронизировать осциллятор 2 и 3 + + Use frequency modulation for modulating oscillator 2 with oscillator 3 + Модулировать частоту осциллятора 3 сигналом со 2 + + + Osc %1 volume: Громкость осциллятора %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. + Эта ручка устанавливает громкость осциллятора %1. Если 0, то осциллятор выключается, иначе будет слышно настолько громко , как тут установлено. + + + Osc %1 panning: Баланс для осциллятора %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. + Регулятор стереобаланса осциллятора %1. Величина -100 обозначает, что 100% сигнала идёт в левый канал, а 100 - в правый. + + + Osc %1 coarse detuning: Грубая подстройка осциллятора %1: + semitones полутон[а,ов] + + 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. + Грубая регулировка подстройки осциллятора %1. Возможна подстройка до 24 полутонов (до 2 октавы) вверх и вниз. Полезно для создания аккордов. + + + Osc %1 fine detuning left: Точная подстройка левого канала осциллятора %1: + + cents Проценты + + 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. + Эта ручка устанавливает точную подстройку для левого канала осциллятора %1. Подстройка задаётся в диапазоне от -100 сотых до +100 сотых. Это полезно для создания "сочных" звуков. + + + Osc %1 fine detuning right: Точная подстройка правого канала осциллятора %1: + + 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. + Эта ручка устанавливает точную подстройку для правого канала осциллятора %1. Подстройка задаётся в диапазоне от -100 сотых до +100 сотых. Это полезно для создания "сочных" звуков. + + + Osc %1 phase-offset: Сдвиг фазы осциллятора %1: + + degrees градусы + + 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. + Эта ручка устанавливает начальную фазу осциллятора %1, т. е. точку, с которой осциллятор начинает вырабатывать сигнал. Например, если вы задали синусоидальную форму сигнала и начальную фазу 180º, волна сначала пойдёт вниз, а не вверх. То же для меандра (сигнала прямоугольной формы). + + + Osc %1 stereo phase-detuning: Подстройка стерео фазы осциллятора %1: - Modulate phase of oscillator 1 by oscillator 2 - + + 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. + Эта ручка устанавливает фазовую подстройку осциллятора %1 между каналами, то есть разность фаз между левым и правым каналами. Это удобно для создания расширения стереоэффектов. - Modulate amplitude of oscillator 1 by oscillator 2 - + + Use a sine-wave for current oscillator. + Генерировать гармонический (синусоидальный) сигнал. - Mix output of oscillators 1 & 2 - + + Use a triangle-wave for current oscillator. + Генерировать треугольный сигнал. - Modulate frequency of oscillator 1 by oscillator 2 - + + Use a saw-wave for current oscillator. + Генерировать зигзагообразный сигнал. - Modulate phase of oscillator 2 by oscillator 3 - + + Use a square-wave for current oscillator. + Генерировать квадрат (меандр). - Modulate amplitude of oscillator 2 by oscillator 3 - + + Use a moog-like saw-wave for current oscillator. + Использовать муг-зигзаг для этого осциллятора. - Mix output of oscillators 2 & 3 - + + Use an exponential wave for current oscillator. + Использовать экспоненциальный сигнал для этого осциллятора. - Modulate frequency of oscillator 2 by oscillator 3 - + + Use white-noise for current oscillator. + Генерировать белый шум. - Sine wave - Синусоида + + Use a user-defined waveform for current oscillator. + Задать форму сигнала. + + + + VersionedSaveDialog + + + Increment version number + Увеличивающийся номер версии - Triangle wave - + + Decrement version number + Понижающийся номер версии - Saw wave - Зигзаг - - - Square wave - - - - Moog-like saw wave - - - - Exponential wave - Экспоненциальная волна - - - White noise - Белый шум - - - User-defined wave - + + already exists. Do you want to replace it? + уже существует. Хотите перезаписать? VestigeInstrumentView - Show/hide GUI - Показать/скрыть интерфейс + + Open other VST-plugin + Открыть другой VST плагин - Turn off all notes - Выключить все ноты + + 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. + Открыть другой модуль VST. После нажатия на кнопку появится стандартный диалог выбора файла, где вы сможете выбрать нужный модуль. - DLL-files (*.dll) - Бибилиотеки DLL (*.dll) + + Control VST-plugin from LMMS host + Управление VST плагином через LMMS хост - EXE-files (*.exe) - Программы EXE (*.exe) + + Click here, if you want to control VST-plugin from host. + Нажмите здесь, для контроля VST плагином через хост. + + Open VST-plugin preset + Открыть предустановку VST плагина + + + + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. + Открыть другую .fxp . fxb предустановку VST. + + + Previous (-) Предыдущий <-> + + + Click here, if you want to switch to another VST-plugin preset program. + Переключение на другую предустановку программы VST плагина. + + + Save preset Сохранить предустановку + + Click here, if you want to save current VST-plugin preset program. + Сохранить текущую предустановку программы VST плагина. + + + Next (+) Следующий <+> + + Click here to select presets that are currently loaded in VST. + Выбор из уже загруженных в VST предустановок. + + + + Show/hide GUI + Показать/скрыть интерфейс + + + + Click here to show or hide the graphical user interface (GUI) of your VST-plugin. + Скрывает/показывает графический пользовательский интерфейс (GUI) выбранного модуля VST. + + + + Turn off all notes + Выключить все ноты + + + + Open VST-plugin + Открыть модуль VST + + + + DLL-files (*.dll) + Бибилиотеки DLL (*.dll) + + + + EXE-files (*.exe) + Программы EXE (*.exe) + + + + No VST-plugin loaded + Модуль VST не загружен + + + Preset Предустановка + by от + - VST plugin control - управление VST плагином + + + VisualizationWidget - Open VST plugin - + + click to enable/disable visualization of master-output + Нажмите, чтобы включить/выключить визуализацию главного вывода - Control VST plugin from LMMS host - - - - Open VST plugin preset - - - - No VST plugin loaded - + + Click to enable + Нажать для включения VstEffectControlDialog + Show/hide Показать/Скрыть + + Control VST-plugin from LMMS host + Управление VST плагином через LMMS хост + + + + Click here, if you want to control VST-plugin from host. + Нажмите здесь, для контроля VST плагином через хост. + + + + Open VST-plugin preset + Открыть предустановку VST плагина + + + + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. + Открыть другую .fxp . fxb предустановку VST. + + + Previous (-) Предыдущий <-> + + + Click here, if you want to switch to another VST-plugin preset program. + Переключение на другую предустановку программы VST плагина. + + + Next (+) Следующий <+> + + Click here to select presets that are currently loaded in VST. + Выбор из уже загруженных в VST предустановок. + + + Save preset Сохранить настройку + + Click here, if you want to save current VST-plugin preset program. + Сохранить текущую предустановку программы VST плагина. + + + + Effect by: Эффекты по: + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> - - Control VST plugin from LMMS host - - - - Open VST plugin preset - - VstPlugin - Loading plugin - Загрузка модуля + + + The VST plugin %1 could not be loaded. + VST плагин %1 не может быть загружен. + Open Preset Открыть предустановку + + Vst Plugin Preset (*.fxp *.fxb) Предустановка VST плагина (*.fxp *.fxb) + : default : основные + " " + ' ' + Save Preset Сохранить предустановку + .fxp .fxp + .FXP .FXP + .FXB .FXB + .fxb .fxb - Please wait while loading VST plugin... - Пожалуйста, подождите пока грузится VST плагин... + + Loading plugin + Загрузка модуля - The VST plugin %1 could not be loaded. - VST плагин %1 не может быть загружен. + + Please wait while loading VST plugin... + Пожалуйста, подождите пока грузится VST плагин... WatsynInstrument + Volume A1 - + Громкость А1 + Volume A2 - + Громкость А2 + Volume B1 - + Громкость B1 + Volume B2 - + Громкость B2 + Panning A1 - + + Panning A2 - + + Panning B1 - + + Panning B2 - + + Freq. multiplier A1 - + Множитель частоты А1 + Freq. multiplier A2 - + Множитель частоты А2 + Freq. multiplier B1 - + Множитель частоты B1 + Freq. multiplier B2 - + Множитель частоты B2 + Left detune A1 - + + Left detune A2 - + + Left detune B1 - + + Left detune B2 - + + Right detune A1 - + + Right detune A2 - + + Right detune B1 - + + Right detune B2 - + + 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 - + + B2-B1 modulation - + + Selected graph - + Выбранный график WatsynView - Select oscillator A1 - - - - Select oscillator A2 - - - - Select oscillator B1 - - - - Select oscillator B2 - - - - Mix output of A2 to A1 - - - - Mix output of B2 to B1 - - - - Draw your own waveform here by dragging your mouse on this graph. - Здесь вы можете рисовать собственный сигнал передвигая зажатой мышью по этому графу. - - - Load waveform - - - - Phase left - Фаза слева - - - Phase right - Фаза справа - - - Normalize - Нормализовать - - - Invert - - - - Smooth - Сгладить - - - Sine wave - Синусоида - - - Triangle wave - Треугольная волна - - - Square wave - Квадрат - - + + + + Volume Громкость + + + + Panning Баланс + + + + Freq. multiplier - + Множитель частоты + + + + Left detune - + + + + + + + + + cents - + + + + + Right detune - + + A-B Mix - + + Mix envelope amount - + + Mix envelope attack - + + Mix envelope hold - + + Mix envelope decay - + + Crosstalk - + - Modulate amplitude of A1 by output of A2 - + + Select oscillator A1 + - Ring modulate A1 and A2 - + + Select oscillator A2 + - Modulate phase of A1 by output of A2 - + + Select oscillator B1 + - Modulate amplitude of B1 by output of B2 - + + Select oscillator B2 + - Ring modulate B1 and B2 - + + Mix output of A2 to A1 + - Modulate phase of B1 by output of B2 - + + Modulate amplitude of A1 with output of A2 + Модулировать амплитуду A1 сигналом с A2 - Load a waveform from a sample file - + + Ring-modulate A1 and A2 + Кольцевая модуляция А1 и А2 - Shift phase by -15 degrees - + + Modulate phase of A1 with output of A2 + Модулировать фазу A1 сигналом с A2 - Shift phase by +15 degrees - + + Mix output of B2 to B1 + - Saw wave - Зигзаг - - - - Xpressive - - Selected graph - + + Modulate amplitude of B1 with output of B2 + Модулировать амплитуду B1 сигналом с B2 - A1 - + + Ring-modulate B1 and B2 + Кольцевая модуляция B1 и B2 - A2 - + + Modulate phase of B1 with output of B2 + Модулировать фазу B1 сигналом с B2 - A3 - - - - W1 smoothing - - - - W2 smoothing - - - - W3 smoothing - - - - Panning 1 - - - - Panning 2 - - - - Rel trans - - - - - XpressiveView - + + + + Draw your own waveform here by dragging your mouse on this graph. - + Здесь вы можете рисовать собственный сигнал передвигая зажатой мышью по этому графу. - Select oscillator W1 - + + Load waveform + - Select oscillator W2 - + + Click to load a waveform from a sample file + Кликнуть для загрузки формы звука из файла с образцом - Select oscillator W3 - + + Phase left + Фаза слева - Select output O1 - + + Click to shift phase by -15 degrees + - Select output O2 - + + Phase right + Фаза справа - Open help window - + + Click to shift phase by +15 degrees + + + Normalize + Нормализовать + + + + Click to normalize + + + + + Invert + Инвертировать + + + + Click to invert + + + + + Smooth + Сгладить + + + + Click to smooth + + + + Sine wave - Синусоида + Синусоида - Moog-saw wave - - - - Exponential wave - Экспоненциальная волна - - - Saw wave - Зигзаг - - - User-defined wave - + + Click for sine wave + + + Triangle wave - + Треугольная волна + + Click for triangle wave + + + + + Click for saw wave + + + + Square wave - + Квадрат - White noise - Белый шум - - - WaveInterpolate - - - - ExpressionValid - - - - General purpose 1: - - - - General purpose 2: - - - - General purpose 3: - - - - O1 panning: - - - - O2 panning: - - - - Release transition: - - - - Smoothness - + + Click for square wave + ZynAddSubFxInstrument + Portamento Портаменто + + Filter Frequency + Фильтр Частот + + + + Filter Resonance + Фильтр резонанса + + + Bandwidth Ширина полосы - Filter frequency - + + FM Gain + Усил FM - Filter resonance - + + Resonance Center Frequency + Частоты центра резонанса - FM gain - + + Resonance Bandwidth + Ширина полосы резонанса - Resonance center frequency - - - - Resonance bandwidth - - - - Forward MIDI control change events - + + Forward MIDI Control Change Events + Переслать изменение событий MiDi управления ZynAddSubFxView - Show GUI - Показать интерфейс - - + Portamento: Портаменто: + PORT PORT + + Filter Frequency: + Фильтр частот: + + + FREQ FREQ + + Filter Resonance: + Фильтр резонанса: + + + RES RES + Bandwidth: Полоса пропускания: + BW BW + + FM Gain: + Усиление частоты модуляции (FM): + + + FM GAIN FM GAIN + Resonance center frequency: Частоты центра резонанса: + RES CF RES CF + Resonance bandwidth: Ширина полосы резонанса: + RES BW RES BW - Filter frequency: - + + Forward MIDI Control Changes + Переслать изменение событий MiDi управления - Filter resonance: - + + Show GUI + Показать интерфейс - FM gain: - - - - Forward MIDI control changes - + + Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. + Скрыть или показать графический интерфейс ZynAddSubFX. audioFileProcessor + Amplify Усиление + Start of sample Начало записи + End of sample Конец записи - Reverse sample - Перевернуть запись - - - Stutter - Запинание - - + Loopback point Точка петли + + Reverse sample + Перевернуть запись + + + Loop mode Режим повтора + + Stutter + Запинание + + + Interpolation mode Режим интерполяции + None Нет + Linear - + Линеарный + Sinc - + + Sample not found: %1 Сэмпл не найден: %1 @@ -3428,430 +9979,294 @@ bitInvader - Sample length - + + Samplelength + Длительность bitInvaderView - Sine wave - Синусоида - - - Triangle wave - Треугольник - - - Saw wave - Зигзаг - - - Square wave - Квадрат (Меандр) - - - Interpolation - Интерполяция - - - Normalize - Нормализовать + + Sample Length + Длительность записи + Draw your own waveform here by dragging your mouse on this graph. Здесь вы можете рисовать собственный сигнал. - Sample length - + + Sine wave + Синусоида - White noise - Белый шум + + Click for a sine-wave. + Сгенерировать гармонический (синусоидальный) сигнал. - User-defined wave - + + Triangle wave + Треугольник - Smooth waveform - Сгладить волну + + Click here for a triangle-wave. + Сгенерировать треугольный сигнал. + + + + Saw wave + Зигзаг + + + + Click here for a saw-wave. + Сгенерировать зигзаг. + + + + Square wave + Квадрат (Меандр) + + + + Click here for a square-wave. + Сгенерировать квадрат. + + + + White noise wave + Белый шум + + + + Click here for white-noise. + Сгенерировать белый шум. + + + + User defined wave + Пользовательская + + + + Click here for a user-defined shape. + Задать форму сигнала вручную. + + + + Smooth + Сгладить + + + + Click here to smooth waveform. + Щёлкните чтобы сгладить форму сигнала. + + + + Interpolation + Интерполяция + + + + Normalize + Нормализовать dynProcControlDialog + INPUT ВХОД + Input gain: Входная мощность: + OUTPUT Выход + Output gain: Выходная мощность: + ATTACK АТАКА + Peak attack time: Время пиковой атаки: + RELEASE ОТПУСК + Peak release time: Время отпуска пика: + + Reset waveform + Сбросить волну + + + + Click here to reset the wavegraph back to default + Сбросить граф волны обратно по умолчанию + + + + Smooth waveform + Сгладить волну + + + + Click here to apply smoothing to wavegraph + Применить сглаживание к графу волны + + + + Increase wavegraph amplitude by 1dB + Повысить амплитуду графа волны на 1 дБ + + + + Click here to increase wavegraph amplitude by 1dB + Нажмите здесь, чтобы повысить амплитуду графа волны на 1 дБ + + + + Decrease wavegraph amplitude by 1dB + Снизить амплитуду графа волны на 1 дБ + + + + Click here to decrease wavegraph amplitude by 1dB + Снизить амплитуду графа волны на 1 дБ + + + + 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 Обрабатывает каждый стерео канал независимо - - Reset wavegraph - - - - Smooth wavegraph - - - - Increase wavegraph amplitude by 1 dB - - - - Decrease wavegraph amplitude by 1 dB - - - - Stereo mode: maximum - - - - Stereo mode: average - - - - Stereo mode: unlinked - - dynProcControls + Input gain Входная мощность + Output gain Выходная мощность + Attack time Время атаки + Release time Время отпуска + Stereo mode Режим стерео - kickerInstrument + expressiveView - Start frequency - Начальная частота + Select oscillator W1 + - End frequency - Конечная частота + Select oscillator W2 + - Gain - Усиление + Select oscillator W3 + - Length - Длина + Select OUTPUT 1 + - Noise - Шум + Select OUTPUT 2 + - Click - + Open help window + - Start from note - + Sine wave + Синусоида - End to note - + Click for a sine-wave. + Сгенерировать гармонический (синусоидальный) сигнал. - Start distortion - + Moog-Saw wave + - End distortion - + Click for a Moog-Saw-wave. + - Envelope slope - + Exponential wave + Экспоненциальная волна - Frequency slope - - - - - kickerInstrumentView - - Start frequency: - Начальная частота: - - - End frequency: - Конечная частота: - - - Gain: - Усиление: - - - Click: - - - - Noise: - Шум: - - - Frequency slope: - - - - Envelope length: - - - - Envelope slope: - - - - Start distortion: - - - - End distortion: - - - - - ladspaBrowserView - - Available Effects - Доступные эффекты - - - Unavailable Effects - Недоступные эффекты - - - Instruments - Инструменты - - - Analysis Tools - Анализаторы - - - Don't know - Неизвестные - - - Type: - Тип: - - - - ladspaDescription - - Plugins - Модули - - - Description - Описание - - - - ladspaPortDialog - - Ports - Порты - - - Name - Название - - - Rate - Частота выборки - - - Direction - Направление - - - Type - Тип - - - Min < Default < Max - Меньше < Стандарт < Больше - - - Logarithmic - Логарифмический - - - SR Dependent - Зависимость от SR - - - Audio - Аудио - - - Control - Управление - - - Input - Ввод - - - Output - Вывод - - - Toggled - Включено - - - Integer - Целое - - - Float - Дробное - - - Yes - Да - - - - lb302Synth - - VCF Cutoff Frequency - Частота среза VCF - - - VCF Resonance - Усиление VCF - - - VCF Envelope Mod - Модуляция огибающей VCF - - - VCF Envelope Decay - Спад огибающей VCF - - - Distortion - Искажение - - - Waveform - Форма сигнала - - - Slide Decay - Сдвиг затухания - - - Slide - Сдвиг - - - Accent - Акцент - - - Dead - Глухо - - - 24dB/oct Filter - 24дБ/окт фильтр - - - - lb302SynthView - - Cutoff Freq: - Частота среза: - - - Resonance: - Отзвук: - - - Env Mod: - Мод Огиб: - - - Decay: - Спад: - - - 303-es-que, 24dB/octave, 3 pole filter - 303-ий, 24дБ/октаву, 3-польный фильтр - - - Slide Decay: - Сдвиг спада: - - - DIST: - ИСК: + Click for an exponential wave. + Saw wave @@ -3861,6 +10276,14 @@ Click here for a saw-wave. Сгенерировать зигзаг. + + User defined wave + Пользовательская + + + Click here for a user-defined shape. + Задать форму сигнала вручную. + Triangle wave Треугольная волна @@ -3877,71 +10300,560 @@ Click here for a square-wave. Сгенерировать квадрат. - - Rounded square wave - Волна скругленного квадрата - - - Click here for a square-wave with a rounded end. - Создать квадратную волну закруглённую в конце. - - - Moog wave - Муг волна - - - Click here for a moog-like wave. - Сгенерировать волну похожую на муг. - - - Sine wave - Синусоида - - - Click for a sine-wave. - Сгенерировать гармонический (синусоидальный) сигнал. - White noise wave Белый шум - - Click here for an exponential wave. - Генерировать экспоненциальный сигнал. - Click here for white-noise. Сгенерировать белый шум. - Bandlimited saw wave - + WaveInterpolate + + ExpressionValid + + + + General purpose 1: + + + + General purpose 2: + + + + General purpose 3: + + + + O1 panning: + + + + O2 panning: + + + + Release transition: + + + + Smoothness + + + + + fxLineLcdSpinBox + + + Assign to: + Назначить на: + + + + New FX Channel + Новый канал ЭФ + + + + graphModel + + + Graph + Граф + + + + kickerInstrument + + + Start frequency + Начальная частота + + + + End frequency + Конечная частота + + + + Length + Длина + + + + Distortion Start + Начало искажения + + + + Distortion End + Конец искажения + + + + Gain + Усиление + + + + Envelope Slope + Сглаживание кривой + + + + Noise + Шум + + + + Click + Клик + + + + Frequency Slope + Сглаживание частоты + + + + Start from note + + + + + End to note + Конец для ноты + + + + kickerInstrumentView + + + Start frequency: + Начальная частота: + + + + End frequency: + Конечная частота: + + + + Frequency Slope: + + + + + Gain: + Усиление: + + + + Envelope Length: + + + + + Envelope Slope: + + + + + Click: + Клик: + + + + Noise: + Шум: + + + + Distortion Start: + + + + + Distortion End: + + + + + ladspaBrowserView + + + + Available Effects + Доступные эффекты + + + + + Unavailable Effects + Недоступные эффекты + + + + + Instruments + Инструменты + + + + + Analysis Tools + Анализаторы + + + + + Don't know + Неизвестные + + + + 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. + В этом окне показана информация обо всех модулях LADSPA, которые обнаружила LMMS. Они разделены на пять категорий, в зависимости от названий и типов портов. + +Доступные эффекты — это те, которые могут быть использоаны в LMMS. Чтобы эффект LADSPA мог быть использован, он должен, во-первых, быть собственно эффектом, т. е. иметь как входные так и выходные каналы. LMMS в качестве входного канала воспринимает аудиопорт, содержащий в названии „in“, а выходные узнаёт по подстроке „out“. Для использования в LMMS число входных каналов должно совпадать с числом выходных, и эффект должен иметь возможность использования в реальном времени. + +Недоступные эффекты — это модули LADSPA, опознанные в качестве эффектов, однако либо с несовпадающими количестами входных/выходных каналов, либо не предназначенные для использования в реальном времени. + +Инструменты — это модули, у которых есть только выходные каналы. + +Анализаторы — это модули, обладающие лишь входными каналами. + +Неизвестные — модули, у которых не было обнаружено ни входных, ни выходных каналов. + +Двойной щелчок левой кнопкой мыши по модулю даст информацию о его портах. + + + + Type: + Тип: + + + + ladspaDescription + + + Plugins + Модули + + + + Description + Описание + + + + ladspaPortDialog + + + Ports + Порты + + + + Name + Название + + + + Rate + Частота выборки + + + + Direction + Направление + + + + Type + Тип + + + + Min < Default < Max + Меньше < Стандарт < Больше + + + + Logarithmic + Логарифмический + + + + SR Dependent + Зависимость от SR + + + + Audio + Аудио + + + + Control + Управление + + + + Input + Ввод + + + + Output + Вывод + + + + Toggled + Включено + + + + Integer + Целое + + + + Float + Дробное + + + + + Yes + Да + + + + lb302Synth + + + VCF Cutoff Frequency + Частота среза VCF + + + + VCF Resonance + Усиление VCF + + + + VCF Envelope Mod + Модуляция огибающей VCF + + + + VCF Envelope Decay + Спад огибающей VCF + + + + Distortion + Искажение + + + + Waveform + Форма сигнала + + + + Slide Decay + Сдвиг затухания + + + + Slide + Сдвиг + + + + Accent + Акцент + + + + Dead + Глухо + + + + 24dB/oct Filter + 24дБ/окт фильтр + + + + lb302SynthView + + + Cutoff Freq: + Частота среза: + + + + Resonance: + Отзвук: + + + + Env Mod: + Мод Огиб: + + + + Decay: + Затухание: + + + + 303-es-que, 24dB/octave, 3 pole filter + 303-ий, 24дБ/октаву, 3-польный фильтр + + + + Slide Decay: + Сдвиг затухания: + + + + DIST: + ИСК: + + + + Saw wave + Зигзаг + + + + Click here for a saw-wave. + Сгенерировать зигзаг. + + + + Triangle wave + Треугольная волна + + + + Click here for a triangle-wave. + Сгенерировать треугольный сигнал. + + + + Square wave + Квадрат + + + + Click here for a square-wave. + Сгенерировать квадрат. + + + + Rounded square wave + Волна скругленного квадрата + + + + Click here for a square-wave with a rounded end. + Создать квадратную волну закруглённую в конце. + + + + Moog wave + Муг волна + + + + Click here for a moog-like wave. + Сгенерировать волну похожую на муг. + + + + Sine wave + Синусоида + + + + Click for a sine-wave. + Сгенерировать гармонический (синусоидальный) сигнал. + + + + + White noise wave + Белый шум + + + + Click here for an exponential wave. + Генерировать экспоненциальный сигнал. + + + + Click here for white-noise. + Сгенерировать белый шум. + + + + 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. Нажать здесь для пилообразной муг (moog) волны с ограниченной полосой. @@ -3949,286 +10861,562 @@ malletsInstrument + Hardness Жёсткость + Position Положение + + Vibrato Gain + Усиление вибрато + + + + Vibrato Freq + Частота вибрато + + + + Stick Mix + Сведение ручек + + + Modulator Модулятор + Crossfade Переход + + LFO Speed + Скорость LFO + + + + LFO Depth + Глубина LFO + + + ADSR ADSR + Pressure Давление + Motion Движение + Speed Скорость + Bowed Наклон + Spread Разброс + Marimba Маримба + Vibraphone Вибрафон + Agogo Дискотека + + Wood1 + Дерево1 + + + Reso Резо + + Wood2 + Дерево2 + + + Beats Удары + + Two Fixed + Два фиксированных + + + Clump Тяжёлая поступь + + Tubular Bells + Трубные колокола + + + + Uniform Bar + Равномерные полосы + + + + Tuned Bar + Подстроенные полосы + + + Glass Стекло - Vibrato gain - - - - Vibrato frequency - - - - Stick mix - - - - LFO speed - Скорость LFO - - - LFO depth - - - - Wood 1 - - - - Wood 2 - - - - Two fixed - - - - Tubular bells - - - - Uniform bar - - - - Tuned bar - - - - Tibetan bowl - + + Tibetan Bowl + Тибетские шары malletsInstrumentView + Instrument Инструмент + Spread Разброс + Spread: Разброс: - Hardness - Жёсткость - - - Hardness: - Жёсткость: - - - Position - Положение - - - Position: - Положение: - - - Modulator - Модулятор - - - Modulator: - Модулятор: - - - Crossfade - Переход - - - Crossfade: - Переход: - - - ADSR - ADSR - - - ADSR: - ADSR: - - - Pressure - Давление - - - Pressure: - Давление: - - - Speed - Скорость - - - Speed: - Скорость: - - + Missing files Файлы отсутствуют + Your Stk-installation seems to be incomplete. Please make sure the full Stk-package is installed! Похоже устновка Stk прошла не полностью. Пожалуйста, убедитесь, что пакет Stk полностью установлен! - Vibrato gain - + + Hardness + Жёсткость - Vibrato gain: - + + Hardness: + Жёсткость: - Vibrato frequency - + + Position + Положение - Vibrato frequency: - + + Position: + Положение: - Stick mix - + + Vib Gain + Усил. вибрато - Stick mix: - + + Vib Gain: + Усил. вибрато: - LFO speed - Скорость LFO + + Vib Freq + Част. виб - LFO speed: - Скорость LFO: + + Vib Freq: + Вибрато: - LFO depth - + + Stick Mix + Сведение ручек - LFO depth: - + + Stick Mix: + Сведение ручек: + + + + Modulator + Модулятор + + + + Modulator: + Модулятор: + + + + Crossfade + Переход + + + + Crossfade: + Переход: + + + + LFO Speed + Скорость LFO + + + + LFO Speed: + Скорость LFO: + + + + LFO Depth + Глубина LFO + + + + LFO Depth: + Глубина LFO: + + + + ADSR + ADSR + + + + ADSR: + ADSR: + + + + Pressure + Давление + + + + Pressure: + Давление: + + + + Speed + Скорость + + + + Speed: + Скорость: manageVSTEffectView + - VST parameter control Управление VST параметрами + + VST Sync + VST синхронизация + + + + Click here if you want to synchronize all parameters with VST plugin. + Нажмите здесь для синхронизации всех параметров VST плагина. + + + + Automated Автоматизировано + + Click here if you want to display automated parameters only. + Нажмите здесь, если хотите видеть только автоматизированные параметры. + + + Close Закрыть - VST sync - + + Close VST effect knob-controller window. + Закрыть окно управления регуляторами VST эффектов. manageVestigeInstrumentView + + - VST plugin control Управление VST плагином + VST Sync VST синхронизация + + Click here if you want to synchronize all parameters with VST plugin. + Нажмите здесь для синхронизации всех параметров VST плагина. + + + + Automated Автоматизировано + + Click here if you want to display automated parameters only. + Нажмите здесь, если хотите видеть только автоматизированные параметры. + + + Close Закрыть + + + Close VST plugin knob-controller window. + Закрыть окно управления регуляторами VST плагина. + + + + opl2instrument + + + Patch + Патч + + + + Op 1 Attack + ОП 1 Вступление + + + + Op 1 Decay + ОП 1 Спад + + + + Op 1 Sustain + ОП 1 Выдержка + + + + Op 1 Release + ОП 1 Убывание + + + + Op 1 Level + ОП 1 Уровень + + + + Op 1 Level Scaling + ОП 1 Уровень увеличения + + + + Op 1 Frequency Multiple + ОП 1 Множитель частот + + + + Op 1 Feedback + ОП 1 Возврат + + + + Op 1 Key Scaling Rate + ОП 1 Ключевая ставка увеличения + + + + Op 1 Percussive Envelope + ОП 1 Ударная огибающая + + + + Op 1 Tremolo + ОП 1 Тремоло + + + + Op 1 Vibrato + Оп 1 Вибрато + + + + Op 1 Waveform + ОП 1 Волна + + + + Op 2 Attack + ОП 2 Вступление + + + + Op 2 Decay + ОП 2 Спад + + + + Op 2 Sustain + ОП 2 Выдержка + + + + Op 2 Release + ОП 2 Убывание + + + + Op 2 Level + ОП 2 Уровень + + + + Op 2 Level Scaling + ОП 2 Уровень увеличения + + + + Op 2 Frequency Multiple + ОП 2 Множитель частот + + + + Op 2 Key Scaling Rate + ОП 2 Ключевая ставка множителя + + + + Op 2 Percussive Envelope + ОП 2 Ударная огибающая + + + + Op 2 Tremolo + ОП 2 Тремоло + + + + Op 2 Vibrato + Оп 2 Вибрато + + + + Op 2 Waveform + ОП 2 Волна + + + + FM + FM + + + + Vibrato Depth + Глубина вибрато + + + + Tremolo Depth + Глубина тремоло + + + + opl2instrumentView + + + + Attack + Вступление + + + + + Decay + Затихание + + + + + Release + Убывание + + + + + Frequency multiplier + Множитель частоты + organicInstrument + Distortion Искажение + Volume Громкость @@ -4236,73 +11424,458 @@ organicInstrumentView + Distortion: Искажение: + + The distortion knob adds distortion to the output of the instrument. + Дисторшн добавляет искажения к выводу инструмента. + + + 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: Форма сигнала для осциллятора %1: + Osc %1 volume: Громкость осциллятора %1: + Osc %1 panning: Баланс для осциллятора %1: - cents - сотые - - + Osc %1 stereo detuning Осц %1 стерео расстройка + + cents + сотые + + + Osc %1 harmonic: Осц %1 гармоника: + + FreeBoyInstrument + + + Sweep time + Время распространения + + + + Sweep direction + Направление распространения + + + + Sweep RtShift amount + Кол-во развёртки сдвиг вправо + + + + + Wave Pattern Duty + Рабочая форма волны + + + + Channel 1 volume + Громкость первого канала + + + + + + Volume sweep direction + Объём направления распространения + + + + + + Length of each step in sweep + Длина каждого такта в распространении + + + + Channel 2 volume + Громкость второго канала + + + + Channel 3 volume + Громкость третьего канала + + + + Channel 4 volume + Громкость четвёртого канала + + + + Shift Register width + Сдвиг ширины регистра + + + + Right Output level + Выходной уровень справа + + + + Left Output level + Выходной уровень слева + + + + Channel 1 to SO2 (Left) + От первого канала к SO2 (левый канал) + + + + Channel 2 to SO2 (Left) + От второго канала к SO2 (левый канал) + + + + Channel 3 to SO2 (Left) + От третьего канала к SO2 (левый канал) + + + + Channel 4 to SO2 (Left) + От четвёртого канала к SO2 (левый канал) + + + + Channel 1 to SO1 (Right) + От первого канала к SO1 (правый канал) + + + + Channel 2 to SO1 (Right) + От второго канала к SO1 (правый канал) + + + + Channel 3 to SO1 (Right) + От третьего канала к SO1 (правый канал) + + + + Channel 4 to SO1 (Right) + От четвёртого канала к SO1 (правый канал) + + + + Treble + Верхние + + + + Bass + Нижние + + + + FreeBoyInstrumentView + + + 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: + Громкость квадратного канала 1: + + + + Square Channel 1 Volume + Громкость квадратного канала 1 + + + + + + Length of each step in sweep: + Длина каждого такта в развёртке: + + + + + + Length of each step in sweep + Длина каждого такта в распространении + + + + + + The delay between step change + Задержка между изменениями такта + + + + Wave pattern duty + Рабочая форма волны + + + + Square Channel 2 Volume: + Громкость квадратного канала 2: + + + + + Square Channel 2 Volume + Громкость квадратного канала 2 + + + + Wave Channel Volume: + Громкость волнового канала: + + + + + Wave Channel Volume + Громкость волнового канала + + + + Noise Channel Volume: + Громкость канала шума: + + + + + Noise Channel Volume + Громкость канала шума + + + + SO1 Volume (Right): + Громкость SO1 (Правый): + + + + SO1 Volume (Right) + Громкость SO1 (Правый) + + + + SO2 Volume (Left): + Громкость SO2 (Левый): + + + + SO2 Volume (Left) + Громкость SO2 (Левый) + + + + Treble: + Верхние: + + + + Treble + Верхние + + + + Bass: + Нижние: + + + + Bass + Нижние + + + + Sweep Direction + Направление развёртки + + + + + + + + Volume Sweep Direction + Громкость направления развёртки + + + + Shift Register Width + Сдвиг ширины регистра + + + + Channel1 to SO1 (Right) + Канал1 в SO1 (Правый) + + + + Channel2 to SO1 (Right) + Канал2 в SO1 (Правый) + + + + Channel3 to SO1 (Right) + Канал3 в SO1 (Правый) + + + + Channel4 to SO1 (Right) + Канал4 в SO1 (Правый) + + + + Channel1 to SO2 (Left) + Канал1 в SO2 (Левый) + + + + Channel2 to SO2 (Left) + Канал2 в SO2 (Левый) + + + + Channel3 to SO2 (Left) + Канал2 в SO2 (Левый) + + + + Channel4 to SO2 (Left) + Канал4 в SO2 (Левый) + + + + Wave Pattern + Рисунок волны + + + + Draw the wave here + Рисовать волну здесь + + patchesDialog + Qsynth: Channel Preset - + + Bank selector - + Выбор банка + Bank Банк + Program selector Выбор программ + Patch Патч + Name Имя + OK ОК + Cancel Отмена @@ -4310,449 +11883,634 @@ pluginBrowser - Incomplete monophonic imitation tb303 - Незавершённая монофоническая имитация tb303 + + no description + описание отсутствует - Plugin for freely manipulating stereo output - Модуль для произвольного управления стереовыходом + + A native amplifier plugin + Родной плагин усилителя - Plugin for controlling knobs with sound peaks - Модуль для установки значений регуляторов по пикам громкости + + Simple sampler with various settings for using samples (e.g. drums) in an instrument-track + Простой сэмплер с разными установками по использованию сэмплов (как барабаны) в инструментальной дорожке - Plugin for enhancing stereo separation of a stereo input file - Модуль, усиливающий разницу между каналами стереозаписи + + Boost your bass the fast and simple way + Накачай свой бас быстро и просто + + Customizable wavetable synthesizer + Настраиваемый синтезатор звукозаписей (wavetable) + + + + An oversampling bitcrusher + + + + + Carla Patchbay Instrument + + + + + Carla Rack Instrument + Карла инструментальная стойка + + + + A 4-band Crossover Equalizer + + + + + A native delay plugin + Встроенный delay плагин + + + + A Dual filter plugin + Двух фильтровый плагин + + + + plugin for processing dynamics in a flexible way + + + + + A native eq plugin + Родной плагин эквалайзера + + + + A native flanger plugin + + + + + Player for GIG files + Проигрыватель GIG-файлов + + + + Filter for importing Hydrogen files into LMMS + Фильтр для импорта Hydrogen файлов в LMMS + + + + Versatile drum synthesizer + Универсальный барабанный синтезатор + + + List installed LADSPA plugins Показать установленные модули LADSPA - GUS-compatible patch instrument - Патч-инструмент, совместимый с GUS - - - Additive Synthesizer for organ-like sounds - Синтезатор звуков вроде органа - - - Tuneful things to bang on - Мелодичные ударные - - - VST-host for using VST(i)-plugins within LMMS - VST - хост для поддержки модулей VST(i) в LMMS - - - Vibrating string modeler - Эмуляция вибрирующих струн - - + plugin for using arbitrary LADSPA-effects inside LMMS. Модуль, позволяющий использовать в LMMS любые эффекты LADSPA. + + Incomplete monophonic imitation tb303 + Незавершённая монофоническая имитация tb303 + + + + Filter for exporting MIDI-files from LMMS + Фильтр для экспорта MIDI файлов из LMMS + + + Filter for importing MIDI-files into LMMS Фильтр для включения файла MIDI в проект ЛММС + + Monstrous 3-oscillator synth with modulation matrix + Монстро 3-осциляторный синт с матрицей модуляции + + + + A multitap echo delay plugin + + + + + A NES-like synthesizer + Синтезатор типа NES + + + + 2-operator FM Synth + 2-режимный синт модуляции частот (FM synth) + + + + Additive Synthesizer for organ-like sounds + Синтезатор звуков вроде органа + + + + Emulation of GameBoy (TM) APU + Эмуляция GameBoy (TM) + + + + GUS-compatible patch instrument + Патч-инструмент, совместимый с GUS + + + + Plugin for controlling knobs with sound peaks + Модуль для установки значений регуляторов по пикам громкости + + + + Reverb algorithm by Sean Costello + + + + + Player for SoundFont files + Проигрыватель файлов SoundFont + + + + LMMS port of sfxr + LMMS порт SFXR + + + Emulation of the MOS6581 and MOS8580 SID. This chip was used in the Commodore 64 computer. Эмуляция MOS6581 и MOS8580. Использовалось на компьютере Commodore 64. - Player for SoundFont files - Проигрыватель файлов SoundFont - - - Emulation of GameBoy (TM) APU - Эмуляция GameBoy (TM) - - - Customizable wavetable synthesizer - Настраиваемый синтезатор звукозаписей (wavetable) - - - Embedded ZynAddSubFX - Встроенный ZynAddSubFX - - - 2-operator FM Synth - 2-режимный синт модуляции частот (FM synth) - - - Filter for importing Hydrogen files into LMMS - Фильтр для импорта Hydrogen файлов в LMMS - - - LMMS port of sfxr - LMMS порт SFXR - - - Monstrous 3-oscillator synth with modulation matrix - Монстро 3-осциляторный синт с матрицей модуляции - - - Three powerful oscillators you can modulate in several ways - Три мощных осциллятора, которые можно модулировать несколькими способами - - - A native amplifier plugin - Родной плагин усилителя - - - Carla Rack Instrument - Карла инструментальная стойка - - - 4-oscillator modulatable wavetable synth - - - - plugin for waveshaping - Плагин для сглаживания волн - - - Boost your bass the fast and simple way - Накачай свой бас быстро и просто - - - Versatile drum synthesizer - - - - Simple sampler with various settings for using samples (e.g. drums) in an instrument-track - Простой сэмплер с разными установками по использованию сэмплов (как барабаны) в инструментальной дорожке - - - plugin for processing dynamics in a flexible way - - - - Carla Patchbay Instrument - - - - plugin for using arbitrary VST effects inside LMMS. - Плагин для использования любых VST эффектов в ЛММС - - + Graphical spectrum analyzer plugin Плагин графического анализа спектра - A NES-like synthesizer - Синтезатор типа NES + + Plugin for enhancing stereo separation of a stereo input file + Модуль, усиливающий разницу между каналами стереозаписи - A native delay plugin - + + Plugin for freely manipulating stereo output + Модуль для произвольного управления стереовыходом - Player for GIG files - + + Tuneful things to bang on + Мелодичные ударные - A multitap echo delay plugin - + + Three powerful oscillators you can modulate in several ways + Три мощных осциллятора, которые можно модулировать несколькими способами - A native flanger plugin - + + VST-host for using VST(i)-plugins within LMMS + VST - хост для поддержки модулей VST(i) в LMMS - An oversampling bitcrusher - + + Vibrating string modeler + Эмуляция вибрирующих струн - A native eq plugin - Родной плагин эквалайзера + + plugin for using arbitrary VST effects inside LMMS. + Плагин для использования любых VST эффектов в ЛММС - A 4-band Crossover Equalizer - + + 4-oscillator modulatable wavetable synth + 4-осцилляторный модулируемый волновой синтезатор - A Dual filter plugin - + + plugin for waveshaping + Плагин для сглаживания волн - Filter for exporting MIDI-files from LMMS - - - - Reverb algorithm by Sean Costello - + + Embedded ZynAddSubFX + Встроенный ZynAddSubFX Mathematical expression parser - + sf2Instrument + Bank Банк + Patch Патч + 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 не удаётся загрузить. - - Reverb room size - - - - Reverb damping - - - - Reverb width - - - - Reverb level - - - - Chorus voices - - - - Chorus level - - - - Chorus speed - - - - Chorus depth - - sf2InstrumentView + + Open other SoundFont file + Открыть другой файл SoundFront + + + + Click here to open another SF2 file + Нажмите здесь чтобы открыть другой файл SF2 + + + + 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 Открыть файл SoundFront - Choose patch - - - - Gain: - - - - Room size: - - - - Damping: - - - - Width: - Ширина: - - - Level: - - - - Voices: - - - - Speed: - Скорость: - - - Depth: - Емкость: - - - SoundFont Files (*.sf2 *.sf3) - + + SoundFont2 Files (*.sf2) + Файлы SoundFont2 (*.sf2) sfxrInstrument - Wave - + + Wave Form + Форма волны sidInstrument + + Cutoff + Срез + + + Resonance Усиление + Filter type Тип фильтра + Voice 3 off Голос 3 откл + Volume Громкость + Chip model Модель чипа - - Cutoff frequency - - sidInstrumentView + Volume: Громкость: + Resonance: Усиление: + + Cutoff frequency: Частота среза: + + High-Pass filter + Выс.ЧФ + + + + Band-Pass filter + Сред.ЧФ + + + + Low-Pass filter + Низ.ЧФ + + + + Voice3 Off + Голос 3 откл + + + MOS6581 SID - + MOS6581 SID + MOS8580 SID - + MOS8580 SID + + Attack: Вступление: - Decay: - Спад: + + Attack rate determines how rapidly the output of Voice %1 rises from zero to peak amplitude. + Длительность вступления определяет, насколько быстро громкость %1-го голоса возрастает от нуля до наибольшего значения. + + + Decay: + Затухание: + + + + Decay rate determines how rapidly the output falls from the peak amplitude to the selected Sustain level. + Длительность спада определяет, насколько быстро громкость падает от максимума до остаточного уровня. + + + Sustain: Выдержка: + + Output of Voice %1 will remain at the selected Sustain amplitude as long as the note is held. + Громкость %1-го голоса будет оставаться на уровне амплитуды выдержки, пока длится нота. + + + + Release: Убывание: + + The output of of Voice %1 will fall from Sustain amplitude to zero amplitude at the selected Release rate. + Громкость %1-го голоса будет падать от остаточного уровня до нуля с указанной здесь скоростью. + + + + 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. + Длительность импульса позволяет мягко регулировать прохождение импульса без заметных сбоев. Импульсная волна должна быть выбрана на осцилляторе %1, чтобы получить звучание. + + + Coarse: Грубость: + + The Coarse detuning allows to detune Voice %1 one octave up or down. + Грубая настройка позволяет подстроить Голос %1 на одну октаву вверх или вниз. + + + + Pulse Wave + Пульсирующая волна + + + + Triangle Wave + Треугольник + + + + SawTooth + Зигзаг + + + Noise Шум + Sync Синхро + + Sync synchronizes the fundamental frequency of Oscillator %1 with the fundamental frequency of Oscillator %2 producing "Hard Sync" effects. + Синхро синхронизирует фундаментальную частоту осцилляторов %1 фундаментальной частотой осциллятора %2, создавая эффект "Железной синхронизации". + + + + Ring-Mod + Круговой режим + + + + Ring-mod replaces the Triangle Waveform output of Oscillator %1 with a "Ring Modulated" combination of Oscillators %1 and %2. + Круговой режим заменяет треугольные волны на выходе осциллятора %1 "Круговой модуляцией" комбинацией осцилляторов %1 и %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. + Если этот флажок установлен, то %1-й голос будет проходить через фильтр. Иначе голос №%1 будет подаваться прямо на выход. + + + Test Тест - High-pass filter - - - - Band-pass filter - - - - Low-pass filter - - - - Voice 3 off - - - - Pulse wave - - - - Triangle wave - - - - Saw wave - Зигзаг - - - Ring modulation - - - - Pulse width: - + + Test, when set, resets and locks Oscillator %1 at zero until Test is turned off. + Если «флажок» установлен, то %1-й осциллятор выдаёт нулевой сигнал (пока флажок не снимется). stereoEnhancerControlDialog - Width: - Ширина: + + WIDE + ШИРЕ - WIDTH - + + Width: + Ширина: stereoEnhancerControls + Width Ширина @@ -4760,18 +12518,22 @@ This chip was used in the Commodore 64 computer. stereoMatrixControlDialog + Left to Left Vol: От левого на левый: + Left to Right Vol: От левого на правый: + Right to Left Vol: От правого на левый: + Right to Right Vol: От правого на правый: @@ -4779,18 +12541,22 @@ This chip was used in the Commodore 64 computer. stereoMatrixControls + Left to Left От левого на левый + Left to Right От левого на правый + Right to Left От правого на левый + Right to Right От правого на правый @@ -4798,191 +12564,380 @@ This chip was used in the Commodore 64 computer. vestigeInstrument + Loading plugin Загрузка модуля - Please wait while loading the VST plugin... - + + Please wait while loading VST-plugin... + Подождите, пока загрузится модуль VST... vibed + String %1 volume Громкость %1-й струны + String %1 stiffness Жёсткость %1-й струны + Pick %1 position Лад %1 + Pickup %1 position Положение %1-го звукоснимателя + + Pan %1 + Бал %1 + + + + Detune %1 + Подстройка %1 + + + + Fuzziness %1 + Нечёткость %1 + + + + Length %1 + Длина %1 + + + Impulse %1 Импульс %1 - String %1 panning - - - - String %1 detune - - - - String %1 fuzziness - - - - String %1 length - - - - String %1 - + + Octave %1 + Октава %1 vibedView + + Volume: + Громкость: + + + + The 'V' knob sets the volume of the selected string. + Регулятор 'V' устанавливает громкость текущей струны. + + + 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. + Регулятор 'S' устанавливает жёсткость текущей струны. Этот параметр отвечает за длительность звучания струны (чем больше значение жёсткости, тем дольше звенит струна). + + + Pick position: Лад: + + 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. + Регулятор 'P' устанавливает место струны, где она будет „прижата“. Чем ниже значение, тем ближе это место будет к кобылке. + + + Pickup position: Положение звукоснимателя: + + 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. + Регулятор 'PU' устанавливает место струны, откуда будет сниматься звук. Чем ниже значение, тем ближе это место будет к кобылке. + + + + Pan: + Бал: + + + + The Pan knob determines the location of the selected string in the stereo field. + Эта ручка устанавливает стереобаланс для текущей струны. + + + + 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: + Нечёткость: + + + + 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: + Длина: + + + + 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. + Переключатель „Imp“ устанавливает режим работы струны: если он включён, то указанная форма сигнала интерпретируется как начальный импульс, иначе — как начальная форма струны. + + + Octave Октава + + 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. + Переключатель октав позволяет указать гармонику основной частоты, на которой будет звучать струна. Например, „-2“ означает, что струна будет звучать двумя октавами ниже основной частоты, „F“ заставит струну звенеть на основной частоте инструмента, а „6“ — на частоте, на шесть октав более высокой, чем основная. + + + Impulse Editor Редактор сигнала + + 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. + Редактор формы позволяет явно указать профиль струны в начальный момент времени, либо её начальный импульс (в заисимости от состояния переключателя „Imp“). +Кнопки справа от рисунка позволяют задавать некоторые стандартные формы, причём кнопка '?' служит для задания формы из произвольного звукового файла (загружаются первые 128 элементов выборки). + +Также форма сигнала может быть просто нарисована с помощью мыши. + +Кнопка 'S' сгладит текущую форму. + +Кнопка 'N' нормализует уровень. + + + + 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. + Инструмент „Vibed“ моделирует до девяти независимых одновременно звучащих струн. + +Переключатель „Strings“ позволяет выбрать струну, чьи свойства редактируются. + +Переключатель „Imp“ устанавливает режим работы струны: если он включён, то указанная форма сигнала интерпретируется как начальный импульс, иначе — как начальная форма струны. + +Переключатель „Octave“ позволяет указать гармонику основной частоты, на которой будет звучать струна. + +Редактор формы позволяет явно указать профиль струны в начальный момент времени, либо её начальный импульс. + +Ручка 'V' устанавливает громкость текущей струны, 'S' — жёсткость, 'P' — место, где прижата струна, а 'PU'' — положение звукоснимателя + +Ручка подстройки и стереобаланса, есть надежда, не нуждаются в объяснениях. + +Ручка „Длина“ регулирует длину струны + +Индикатор-переключатель слева внизу определяет, включена ли текущая струна. + + + Enable waveform Включить + + Click here to enable/disable waveform. + Нажмите, чтобы включить/выключить сигнал. + + + String Струна + + 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. + Переключатель струн позволяет выбрать струну, чьи свойства редактируются. Инструмент Vibed содержит до девяти независимо звучащих струн, индикатор в левом нижнем углу показывает, активна ли текущая струна (т. е. будет ли она слышна). + + + Sine wave Синусоида + + Use a sine-wave for current oscillator. + Генерировать гармонический (синусоидальный) сигнал. + + + Triangle wave Треугольник + + Use a triangle-wave for current oscillator. + Генерировать треугольный сигнал. + + + Saw wave Зигзаг + + Use a saw-wave for current oscillator. + Генерировать зигзагообразный сигнал. + + + Square wave Квадратная волна - String volume: - + + Use a square-wave for current oscillator. + Генерировать квадрат (меандр). - String panning: - + + White noise wave + Белый шум - String detune: - + + Use white-noise for current oscillator. + Генерировать белый шум. - String fuzziness: - + + User defined wave + Пользовательская - String length: - + + Use a user-defined waveform for current oscillator. + Задать форму сигнала. - Impulse - + + Smooth + Сгладить - Enable/disable string - + + Click here to smooth waveform. + Щёлкните чтобы сгладить форму сигнала. - White noise - Белый шум + + Normalize + Нормализовать - User-defined wave - - - - Smooth waveform - Сгладить волну - - - Normalize waveform - + + Click here to normalize waveform. + Нажмите, чтобы нормализовать сигнал. voiceObject + Voice %1 pulse width Голос %1 длина сигнала + Voice %1 attack Вступление %1-го голоса + Voice %1 decay - Спад %1-го голоса + Затухание %1-го голоса + Voice %1 sustain Выдержка для %1-го голоса + Voice %1 release Убывание %1-го голоса + Voice %1 coarse detuning Подстройка %1-го голоса (грубо) + Voice %1 wave shape Форма сигнала для %1-го голоса + Voice %1 sync Синхронизация %1-го голоса + Voice %1 ring modulate Голос %1 кольцевой модулятор + Voice %1 filtered Фильтрованный %1-й голос + Voice %1 test Голос %1 тест @@ -4990,53 +12945,85 @@ This chip was used in the Commodore 64 computer. waveShaperControlDialog + INPUT ВХОД + Input gain: Входная мощность: + OUTPUT Выход + Output gain: Выходная мощность: + + Reset waveform + Сбросить волну + + + + Click here to reset the wavegraph back to default + Сбросить граф волны обратно по умолчанию + + + + Smooth waveform + Сгладить волну + + + + Click here to apply smoothing to wavegraph + Применить сглаживание к графу волны + + + + Increase graph amplitude by 1dB + Повысить амплитуду графа на 1 дБ + + + + Click here to increase wavegraph amplitude by 1dB + Нажмите здесь, чтобы повысить амплитуду графа волны на 1 дБ + + + + Decrease graph amplitude by 1dB + Снизить амплитуду графа на 1 дБ + + + + Click here to decrease wavegraph amplitude by 1dB + Снизить амплитуду графа волны на 1 дБ + + + Clip input Срезать выходной сигнал - Reset wavegraph - - - - Smooth wavegraph - - - - Increase wavegraph amplitude by 1 dB - - - - Decrease wavegraph amplitude by 1 dB - - - - Clip input signal to 0 dB - + + Clip input signal to 0dB + Срезать входной сигнал до 0дБ waveShaperControls + Input gain Входная мощность + Output gain Выходная мощность diff --git a/data/locale/uk.ts b/data/locale/uk.ts index e9aefd4c1..7271c4946 100644 --- a/data/locale/uk.ts +++ b/data/locale/uk.ts @@ -1,37 +1,116 @@ - - - + + + AboutDialog + + + About LMMS + Про програму LMMS + + + + LMMS + LMMS + + + + Version %1 (%2/%3, Qt %4, %5) + Версія %1 (%2/%3, Qt %4, %5) + + + + About + Про програму + + + + LMMS - easy music production for everyone + LMMS - легке створення музики для всіх + + + + Copyright © %1 + Авторське право © %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 + Автори + + + + Involved + Учасники + + + + Contributors ordered by number of commits: + Розробники відсортовані за кількістю коммітов: + + + + Translation + Переклад + + + + 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! + Переклад виконали: +Михайло Рожко <mihail.rozshko@gmail.com> + +Якщо Ви зацікавлені в перекладі LMMS на іншу мову або хочете поліпшити існуючий переклад, ми будемо раді будь-якій допомогі! Просто зв'яжіться з розробниками! + + + + License + Ліцензія + + AmplifierControlDialog + VOL ГУЧН + Volume: Гучність: + PAN БАЛ + Panning: Баланс: + LEFT ЛІВЕ + Left gain: Ліве підсилення: + RIGHT ПРАВЕ + Right gain: Праве підсилення: @@ -39,95 +118,727 @@ AmplifierControls + Volume Гучність + Panning Баланс + Left gain Ліве підсилення + Right gain Праве підсилення + + AudioAlsaSetupWidget + + + DEVICE + ПРИСТРІЙ + + + + CHANNELS + КАНАЛИ + + AudioFileProcessorView + + Open other sample + Відкрити інший запис + + + + 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. + Натисніть тут, щоб відкрити інший звуковий файл. У новому вікні діалогу ви зможете вибрати потрібний файл. Такі налаштування, як режим повтору, точки початку/кінця, підсилення та інші не скинуться, тому звучання може відрізнятися від оригіналу. + + + Reverse sample Реверс запису - Amplify: - Підсилення: - - - Continue sample playback across notes - Продовжити відтворення запису по нотах + + If you enable this button, the whole sample is reversed. This is useful for cool effects, e.g. a reversed crash. + Якщо включити цю кнопку, весь запис піде у зворотний бік, це зручно для крутих ефектів, наприклад зворотного гуркоту. + Disable loop Відключити повторення + + This button disables looping. The sample plays only once from start to end. + Ця кнопка відключає повтор. Запис програється тільки один раз від початку до кінця. + + + + Enable loop Включити повторення + + This button enables forwards-looping. The sample loops between the end point and the loop point. + Ця кнопка включає передній повтор. Запис повторюється між кінцевою точкою і точкою повтору. + + + + This button enables ping-pong-looping. The sample loops backwards and forwards between the end point and the loop point. + Ця кнопка включає пінг-понг петлю. Запис повторюється назад і вперед між кінцевою точкою і точкою повтору. + + + + Continue sample playback across notes + Продовжити відтворення запису по нотах + + + + 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) + Включення цієї опції продовжить відтворення запису за різними нотами - якщо змінити прискорення або тривалість ноти зупиниться до кінця запису, то з наступної ноти запис продовжиться там, де зупинився, щоб скинути відтворення на початок запису, вставте ноту внизу у клавіш (<20 Гц) + + + + Amplify: + Підсилення: + + + + 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!) + Ця ручка задає коефіцієнт підсилення. При значенні 100% вихідний звук не змінюється, в іншому випадку - він буде ослаблений або підсилений. (Зверніть увагу, що вихідний запис при цьому залишиться недоторканим.) + + + + Startpoint: + Початок: + + + + With this knob you can set the point where AudioFileProcessor should begin playing your sample. + Цим регулятором можна встановити мітку з якої АудіоФайлПроцессор повинен почати відтворення запису. + + + + Endpoint: + Кінець: + + + + With this knob you can set the point where AudioFileProcessor should stop playing your sample. + Цей регулятор встановлює мітку в якій АудіоФайлПроцессор повинен перестати програвати запис. + + + Loopback point: Точка повернення з повтору: - Open sample - - - - Enable ping-pong loop - - - - Start point: - - - - End point: - + + With this knob you can set the point where the loop starts. + Цей регулятор ставить мітку початку повторення. AudioFileProcessorWaveView + Sample length: Довжина запису: + + AudioJack + + + JACK client restarted + JACK-клієнт перезапущений + + + + 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 не був підключений до JACK з якоїсь причини, тому LMMS підключення до JACK було перезапущено. Вам доведеться заново вручну створити з'єднання. + + + + JACK server down + JACK-сервер не доступний + + + + 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. + Можливо JACK-сервер був вимкнений і запуск нового процесу не вдався, тому LMMS не може продовжити роботу. Вам слід зберегти проект і перезапустити JACK і LMMS. + + + + CLIENT-NAME + ІМ'Я КЛІЄНТА + + + + CHANNELS + КАНАЛИ + + + + AudioOss::setupWidget + + + DEVICE + ПРИСТРІЙ + + + + CHANNELS + КАНАЛИ + + + + AudioPortAudio::setupWidget + + + BACKEND + УПРАВЛІННЯ + + + + DEVICE + ПРИСТРІЙ + + + + AudioPulseAudio::setupWidget + + + DEVICE + ПРИСТРІЙ + + + + CHANNELS + КАНАЛИ + + + + AudioSdl::setupWidget + + + DEVICE + ПРИСТРІЙ + + + + AudioSndio::setupWidget + + + DEVICE + ПРИСТРІЙ + + + + CHANNELS + КАНАЛИ + + + + AudioSoundIo::setupWidget + + + BACKEND + УПРАВЛІННЯ + + + + DEVICE + ПРИСТРІЙ + + + + AutomatableModel + + + &Reset (%1%2) + &R Скинути (%1%2) + + + + &Copy value (%1%2) + &C Копіювати значення (%1%2) + + + + &Paste value (%1%2) + &P Вставити значення (%1%2) + + + + Edit song-global automation + Змінити глоабльную автоматизацію композиції + + + + Remove song-global automation + Прибрати глобальну автоматизацію композиції + + + + Remove all linked controls + Прибрати все приєднане управління + + + + Connected to %1 + Приєднано до %1 + + + + Connected to controller + Приєднано до контролера + + + + Edit connection... + Налаштувати з'єднання... + + + + Remove connection + Видалити з'єднання + + + + Connect to controller... + З'єднати з контролером ... + + + + AutomationEditor + + + Please open an automation pattern with the context menu of a control! + Відкрийте редатор автоматизації через контекстне меню регулятора! + + + + Values copied + Значення скопійовані + + + + All selected values were copied to the clipboard. + Всі вибрані значення скопійовані до буферу обміну. + + + + 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) + Режим малювання (Shift + D) + + + + Erase mode (Shift+E) + Режим стирання (Shift+E) + + + + Flip vertically + Перевернути вертикально + + + + Flip horizontally + Перевернути горизонтально + + + + Click here and the pattern will be inverted.The points are flipped in the y direction. + Натисніть тут і мелодія перевернеться. Точки перевертаються в Y напрямку. + + + + Click here and the pattern will be reversed. The points are flipped in the x direction. + Натисніть тут і мелодія перевернеться в напрямку 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. + При натиснені цієї кнопки активується режим малювання нот, в ньому ви можете додавати/переміщати і змінювати тривалість одиночних нот. Це основний режим і використовується більшу частину часу. +Для увімкнення цього режиму можна скористатися комбінацію клавіш Shift+D. + + + + 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. + При натиснені цієї кнопки активується режим стирання. У цьому режимі ви можете видаляти ноти по одній. +Для увімкнення цього режиму можна скористатися комбінацію клавіш Shift+E. + + + + 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) + Вирізати вибрані ноти (%1+X) + + + + Copy selected values (%1+C) + Копіювати вибрані ноти до буферу (%1+C) + + + + Paste values from clipboard (%1+V) + Вставити значення з буферу (%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. + Квантування. Встановлює найменший розмір кроку для точки автоматизації. За замовчуванням це також задає довжину, очищаючи інші точки діапазону. Натисніть <Ctrl>, щоб змінити цю поведінку. + + + + + Automation Editor - no pattern + Редактор автоматизації - немає шаблону + + + + + Automation Editor - %1 + Редактор автоматизації - %1 + + + + Model is already connected to this pattern. + Модель вже підключена до цього шаблону. + + + + AutomationPattern + + + Drag a control while pressing <%1> + Тягніть контроль утримуючи <%1> + + + + AutomationPatternView + + + double-click to open this pattern in automation editor + Двічі клацніть мишею щоб налаштувати автоматизацію для цього шаблону + + + + Open in Automation editor + Відкрити в редакторі автоматизації + + + + Clear + Очистити + + + + Reset name + Скинути назву + + + + Change name + Перейменувати + + + + Set/clear record + Встановити/очистити запис + + + + Flip Vertically (Visible) + Перевернути вертикально (Видиме) + + + + Flip Horizontally (Visible) + Перевернути горизонтально (Видиме) + + + + %1 Connections + З'єднання %1 + + + + Disconnect "%1" + Від'єднати «%1» + + + + Model is already connected to this pattern. + Модель вже підключена до цього шаблону. + + + + AutomationTrack + + + Automation track + Доріжка автоматизації + + + + BBEditor + + + Beat+Bassline Editor + Ритм Бас Редактор + + + + Play/pause current beat/bassline (Space) + Грати/пауза поточної лінії ритму/басу (Пробіл) + + + + Stop playback of current beat/bassline (Space) + Зупинити відтворення поточної лінії ритм-басу (Пробіл) + + + + Click here to play the current beat/bassline. The beat/bassline is automatically looped when its end is reached. + Натисніть щоб програти поточну лінію ритм-басу. Вона буде повторена при досягненні кінця. + + + + Click here to stop playing of current beat/bassline. + Зупинити відтворення (Пробіл). + + + + Beat selector + Вибір ударних + + + + Track and step actions + Дії для доріжки чи її частини + + + + Add beat/bassline + Додати ритм/бас + + + + Add sample-track + Додати доріжку запису + + + + Add automation-track + Додати доріжку автоматизації + + + + Remove steps + Видалити такти + + + + Add steps + Додати такти + + + + Clone Steps + Клонувати такти + + + + BBTCOView + + + Open in Beat+Bassline-Editor + Відкрити в редакторі ритму і басу + + + + Reset name + Скинути назву + + + + Change name + Перейменувати + + + + Change color + Змінити колір + + + + Reset color to default + Відновити колір за замовчуванням + + + + BBTrack + + + Beat/Bassline %1 + Ритм/Бас лінія %1 + + + + Clone of %1 + Копія %1 + + BassBoosterControlDialog + FREQ ЧАСТ + Frequency: Частота: + GAIN ПІДС + Gain: Підсилення: + RATIO ВІДН + Ratio: Відношення: @@ -135,14 +846,17 @@ BassBoosterControls + Frequency Частота + Gain Підсилення + Ratio Відношення @@ -150,1043 +864,2111 @@ BitcrushControlDialog + IN ВХД + OUT ВИХ + + GAIN ПІДС + + Input Gain: + Вхідне підсилення: + + + + NOISE + ШУМ + + + + Input Noise: + Вхідний шум: + + + + Output Gain: + Вихідне підсилення: + + + CLIP ЗРІЗ - Sample rate: - Частота дискретизації: + + Output Clip: + Вихідне відсічення: - Stereo difference: - Стерео різниця: + + Rate Enabled + Частоту вибірки увімкнено - Levels: - Рівні: + + Enable samplerate-crushing + Включити дроблення частоти дискретизації - NOISE - + + Depth Enabled + Глибина включена + + Enable bitdepth-crushing + Включити ​​дроблення глибини кольору + + + FREQ ЧАСТ + + Sample rate: + Частота дискретизації: + + + STEREO - + СТЕРЕО + + Stereo difference: + Стерео різниця: + + + QUANT - + КВАНТ - Input gain: - Вхідне підсилення: - - - Input noise: - - - - Output gain: - Вихідне підсилення: - - - Output clip: - - - - Rate enabled - - - - Enable sample-rate crushing - - - - Depth enabled - - - - Enable bit-depth crushing - + + Levels: + Рівні: - BitcrushControls + CaptionMenu - Input gain - Вхідне підсилення + + &Help + &H Довідка - Input noise - - - - Output gain - Вихідне підсилення - - - Output clip - - - - Sample rate - - - - Stereo difference - - - - Levels - - - - Rate enabled - - - - Depth enabled - + + Help (not available) + Допомога (не доступно) CarlaInstrumentView + Show GUI Показати інтерфейс + + + Click here to show or hide the graphical user interface (GUI) of Carla. + Натисніть сюди щоб сховати чи показати графічний інтерфейс Carla. + + + + Controller + + + Controller %1 + Контролер %1 + + + + ControllerConnectionDialog + + + Connection Settings + Параметры соединения + + + + MIDI CONTROLLER + MIDI-КОНТРОЛЕР + + + + Input channel + Канал введення + + + + CHANNEL + КАНАЛ + + + + Input controller + Контролер введення + + + + CONTROLLER + КОНТРОЛЕР + + + + + Auto Detect + Автовизначення + + + + MIDI-devices to receive MIDI-events from + Пристрої MiDi для прийому подій + + + + USER CONTROLLER + КОРИСТ. КОНТРОЛЕР + + + + MAPPING FUNCTION + ПЕРЕВИЗНАЧЕННЯ + + + + OK + ОК + + + + Cancel + Відміна + + + + LMMS + ЛММС + + + + Cycle Detected. + Виявлено цикл. + + + + ControllerRackView + + + Controller Rack + Стійка контролерів + + + + Add + Додати + + + + Confirm Delete + Підтвердити видалення + + + + Confirm delete? There are existing connection(s) associated with this controller. There is no way to undo. + Чи підтверджуєте видалення? Є можливі зв'язки з цим контролером, потім їх не можна буде повернути.. + + + + ControllerView + + + Controls + Управління + + + + Controllers are able to automate the value of a knob, slider, and other controls. + Контролери можуть автоматизувати зміни значень регуляторів, повзунків та іншого управління. + + + + Rename controller + Перейменувати контролер + + + + Enter the new name for this controller + Введіть нову назву контролера + + + + LFO + LFO + + + + &Remove this controller + &R Видалити цей контролер + + + + Re&name this controller + &N Перейменувати цей контролер + CrossoverEQControlDialog - Band 1/2 crossover: - + + Band 1/2 Crossover: + Смуга 1/2 кросовер: - Band 2/3 crossover: - + + Band 2/3 Crossover: + Смуга 2/3 кросовер: - Band 3/4 crossover: - + + Band 3/4 Crossover: + Смуга 3/4 кросовер: - Band 1 gain - + + Band 1 Gain: + Смуга 1 підсилення: - Band 1 gain: - + + Band 2 Gain: + Смуга 2 підсилення: - Band 2 gain - + + Band 3 Gain: + Смуга 3 підсилення: - Band 2 gain: - + + Band 4 Gain: + Смуга 4 підсилення: - Band 3 gain - + + Band 1 Mute + Смуга 1 відключена - Band 3 gain: - + + Mute Band 1 + Відключити смугу 1 - Band 4 gain - + + Band 2 Mute + Смуга 2 відключена - Band 4 gain: - + + Mute Band 2 + Відключити смугу 2 - Band 1 mute - + + Band 3 Mute + Смуга 3 відключена - Mute band 1 - + + Mute Band 3 + Відключити смугу 3 - Band 2 mute - + + Band 4 Mute + Смуга 4 відключена - Mute band 2 - - - - Band 3 mute - - - - Mute band 3 - - - - Band 4 mute - - - - Mute band 4 - + + Mute Band 4 + Відключити смугу 4 DelayControls + + Delay Samples + Затримка семплів + + + Feedback Повернення + + Lfo Frequency + Частота LFO + + + + Lfo Amount + Величина LFO + + + Output gain Вихідне підсилення - - Delay samples - - - - LFO frequency - - - - LFO amount - - DelayControlsDialog - Gain - Підсилення - - + DELAY - + ЗАТРИМ + + Delay Time + Час затримки + + + FDBK - + FDBK + + Feedback Amount + Величина повернення + + + RATE - + ЧАСТ + + Lfo + LFO + + + AMNT ГЛИБ - Delay time - + + Lfo Amt + Вел LFO - Feedback amount - + + Out Gain + Вих підсилення - LFO frequency - - - - LFO amount - - - - Out gain - + + Gain + Підсилення DualFilterControlDialog - Filter 1 enabled - Фільтр 1 включено - - - Filter 2 enabled - Фільтр 2 включено - - + + FREQ ЧАСТ + + Cutoff frequency Зріз частоти + + RESO РЕЗО + + Resonance Резонанс + + GAIN ПІДС + + Gain Підсилення + MIX МІКС + Mix Мікс - Enable/disable filter 1 - + + Filter 1 enabled + Фільтр 1 включено - Enable/disable filter 2 - + + Filter 2 enabled + Фільтр 2 включено + + + + Click to enable/disable Filter 1 + Натиснути для включення/виключення Фільтру 1 + + + + Click to enable/disable Filter 2 + Натиснути для включення/виключення Фільтру 2 DualFilterControls + Filter 1 enabled Фільтр 1 включено + Filter 1 type Тип фільтру + + Cutoff 1 frequency + Зріз 1 частоти + + + Q/Resonance 1 Кіл./Резонансу 1 + Gain 1 Підсилення 1 + Mix Мікс + Filter 2 enabled Фільтр 2 включено + Filter 2 type Тип фільтру 2 + + Cutoff 2 frequency + Зріз 2 частоти + + + Q/Resonance 2 Кіл./Резонансу 2 + Gain 2 Підсилення 2 + + + LowPass + Низ.ЧФ + + + + + HiPass + Вис.ЧФ + + + + + BandPass csg + Серед.ЧФ csg + + + + + BandPass czpg + Серед.ЧФ czpg + + + + Notch Смуго-загороджуючий + + + Allpass + Всі проходять + + + + Moog Муг + + + 2x LowPass + 2х Низ.ЧФ + + + + + RC LowPass 12dB + RC Низ.ЧФ 12дБ + + + + + RC BandPass 12dB + RC Серед.ЧФ 12 дБ + + + + + RC HighPass 12dB + RC Вис.ЧФ 12дБ + + + + + RC LowPass 24dB + RC Низ.ЧФ 24дБ + + + + + RC BandPass 24dB + RC Серед.ЧФ 24дБ + + + + + RC HighPass 24dB + RC Вис.ЧФ 24дБ + + + + + Vocal Formant Filter + Фільтр Вокальної форманти + + + + 2x Moog 2x Муг + + + SV LowPass + SV Низ.ЧФ + + + + + SV BandPass + SV Серед.ЧФ + + + + + SV HighPass + SV Вис.ЧФ + + + + SV Notch SV Смуго-заг + + Fast Formant Швидка форманта + + Tripole Тріполі + + + Editor - Cutoff frequency 1 - + + Transport controls + Управління засобами сполучення - Cutoff frequency 2 - + + Play (Space) + Грати (Пробіл) - Low-pass - + + Stop (Space) + Зупинити (Пробіл) - Hi-pass - + + Record + Запис - Band-pass csg - + + Record while playing + Запис під час програвання + + + + Effect + + + Effect enabled + Ефект включений - Band-pass czpg - + + Wet/Dry mix + Насиченість - All-pass - + + Gate + Шлюз - 2x Low-pass - + + Decay + Згасання + + + + EffectChain + + + Effects enabled + Ефекти включені + + + + EffectRackView + + + EFFECTS CHAIN + МЕРЕЖА ЕФЕКТІВ - RC Low-pass 12 dB/oct - + + Add effect + Додати ефект + + + + EffectSelectDialog + + + Add effect + Додати ефект - RC Band-pass 12 dB/oct - + + + Name + І'мя - RC High-pass 12 dB/oct - + + Type + Тип - RC Low-pass 24 dB/oct - + + Description + Опис - RC Band-pass 24 dB/oct - + + Author + Автор + + + + EffectView + + + Toggles the effect on or off. + Увімк/Вимк ефект. - RC High-pass 24 dB/oct - + + On/Off + Увімк/Вимк - Vocal Formant - + + W/D + НАСИЧ - SV Low-pass - + + Wet Level: + Рівень насиченості: - SV Band-pass - + + The Wet/Dry knob sets the ratio between the input signal and the effect signal that forms the output. + Регулятор насиченості визначає частку обробленого сигналу, яка буде на виході. - SV High-pass - + + 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. + Decay (затихання) управляє кількістю буферів тиші, які повинні пройти до кінця роботи плагіна. Менші величини знижують перевантаження процесора, але виникає ризик появи потріскування або підрізання в хвості на перетримці (delay) або відлуння (reverb) ефектах. + + + + GATE + ШЛЮЗ + + + + Gate: + Шлюз: + + + + The Gate knob controls the signal level that is considered to be 'silence' while deciding when to stop processing signals. + GATE (Шлюз) визначає рівень сигналу, який буде вважатися "тишею" при визначенні зупинки оброблення сигналів. + + + + 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. + +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. + Сигнал проходить послідовно через всі встановлені фільтри (зверху вниз). + +Перемикач Увімк/Вимк дозволяє в будь-який момент вмикати / вимикати фільтр. + +Регулятор (wet / dry) насиченості визначає баланс між вхідним сигналом і сигналом після ефекту, який стає вихідним сигналом ефекту. Вхідний сигнал кожного фільтра є виходом попереднього, так що частка чистого сигналу при проходженні по ланцюжку постійно падає. + +Регулятор (decay) затихання визначає час, який буде діяти фільтр після того як ноти були відпущені. +Ефект перестане обробляти сигнали, коли гучність впаде нижче порогу для заданої довжини часу. Ця ручка (Knob) встановлює "задану довжину часу" Чим менше значення, тим менші вимоги до ЦП, тому краще ставити це число низьким для більшості ефектів. однак це може викликати обрізку звуку при використанні ефектів з тривалими періодами тиші, типу затримки. + +Регулятор шлюзу служить для вказівки порогу сигналу для авто-відключення ефекту, відлік для "заданої довжини часу" почнеться як тільки опрацьований сигнал впаде нижче зазначеного цим регулятором рівня. + +Кнопка "Управління" відкриває вікно зміни параметрів ефекту. + +Контекстне меню, яке викликається клацанням правою кнопкою миші, дозволяє змінювати порядок проходження фільтрів або видаляти їх разом з іншими. + + + + Move &up + &u Перемістити вище + + + + Move &down + &d Перемістити нижче + + + + &Remove this plugin + &R Видалити цей плагін + + + + EnvelopeAndLfoParameters + + + Predelay + Затримка + + + + Attack + Вступ + + + + Hold + Утримання + + + + Decay + Згасання + + + + Sustain + Витримка + + + + Release + Зменшення + + + + Modulation + Модуляція + + + + LFO Predelay + Затримка LFO + + + + LFO Attack + Вступ LFO + + + + LFO speed + Швидкість LFO + + + + LFO Modulation + Модуляція LFO + + + + LFO Wave Shape + Форма сигналу LFO + + + + Freq x 100 + ЧАСТ x 100 + + + + Modulate Env-Amount + Модулювати обвідну + + + + EnvelopeAndLfoView + + + + DEL + DEL + + + + Predelay: + Предзатримка: + + + + 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: + Вступ: + + + + 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: + Утримання: + + + + 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: + Згасання: + + + + 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: + Витримка: + + + + 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: + Зменшення: + + + + 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 + AMT + + + + + Modulation amount: + Глибина модуляції: + + + + 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: + Предзатримка 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 (LFO - низькочастотний осциллятор (генератор)). Чим більша величина, тим більше часу до того як LFO почне працювати. + + + + LFO- 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. + Використовуйте цю ручку для встановлення часу вступу цього LFO. Чим більше значення, тим довше LFO потребує збільшення своєї амплітуди до максимуму. + + + + SPD + SPD + + + + LFO speed: + Швидкість 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. + Ця ручка встановлює швидкість поточного LFO. Чим більше значення, тим швидше LFO коливається і швидше виробляється ефект. + + + + 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. + Ця ручка встановлює глибину модуляції для поточного LFO. Чим більше значення, тим більшою мірою обрана характеристика (н-д, гучність або частота зрізу) залежатиме від цього LFO. + + + + Click here for a sine-wave. + Синусоїда. + + + + Click here for a triangle-wave. + Згенерувати трикутний сигнал. + + + + Click here for a saw-wave for current. + Згенерувати зигзагоподібний сигнал. + + + + Click here for a square-wave. + Згенерувати квадратний сигнал. + + + + Click here for a user-defined wave. Afterwards, drag an according sample-file onto the LFO graph. + Задати свою форму сигналу. Згодом, перетягнути відповідний файл із записом в граф LFO. + + + + Click here for random wave. + Натисніть сюди для випадкової хвилі. + + + + FREQ x 100 + ЧАСТОТА x 100 + + + + Click here if the frequency of this LFO should be multiplied by 100. + Натисніть, щоб помножити частоту цього LFO на 100. + + + + multiply LFO-frequency by 100 + Помножити частоту LFO на 100 + + + + MODULATE ENV-AMOUNT + МОДЕЛЮВ ОБВІДНУ + + + + Click here to make the envelope-amount controlled by this LFO. + Натисніть сюди, щоб глибина модуляції обвідної задавалася цим LFO. + + + + control envelope-amount by this LFO + Дозволити цьому LFO задавати значення обвідної + + + + ms/LFO: + мс/LFO: + + + + Hint + Підказка + + + + Drag a sample from somewhere and drop it in this window. + Перетягніть в це вікно який-небудь запис. EqControls + Input gain Вхідне підсилення + Output gain Вихідне підсилення + + Low shelf gain + Мала ступінь підсилення + + + Peak 1 gain Пік 1 підсилення + Peak 2 gain Пік 2 підсилення + Peak 3 gain Пік 3 підсилення + Peak 4 gain Пік 4 підсилення + + High Shelf gain + Висока ступінь підсилення + + + HP res ВЧ резон + + Low Shelf res + Мала ступінь резон + + + Peak 1 BW Пік 1 BW + Peak 2 BW Пік 2 BW + Peak 3 BW Пік 3 BW + Peak 4 BW Пік 4 BW + + High Shelf res + Висока ступінь резон + + + LP res НЧ резон + HP freq НЧ част + + Low Shelf freq + Низька ступінь част + + + Peak 1 freq Пік 1 част + Peak 2 freq Пік 2 част + Peak 3 freq Пік 3 част + Peak 4 freq Пік 4 част + + High shelf freq + Висока ступінь част + + + LP freq НЧ част + HP active ВЧ активна + + Low shelf active + Мала ступінь активна + + + Peak 1 active Пік 1 активний + Peak 2 active Пік 2 активний + Peak 3 active Пік 3 активний + Peak 4 active Пік 4 активний + + High shelf active + Висока ступінь активна + + + LP active НЧ активна + LP 12 НЧ 12 + LP 24 НЧ 24 + LP 48 НЧ 48 + HP 12 ВЧ 12 + HP 24 ВЧ 24 + HP 48 ВЧ 48 + + low pass type + Тип низької частоти + + + + high pass type + Тип високої частоти + + + Analyse IN Аналізувати ВХІД + Analyse OUT Аналізувати ВИХІД - - Low-shelf gain - - - - High-shelf gain - - - - Low-shelf res - - - - High-shelf res - - - - Low-shelf freq - - - - High-shelf freq - - - - Low-shelf active - - - - High-shelf active - - - - Low-pass type - - - - High-pass type - - EqControlsDialog + HP ВЧ + + Low Shelf + Мала ступінь + + + Peak 1 Пік 1 + Peak 2 Пік 2 + Peak 3 Пік 3 + Peak 4 Пік 4 + + High Shelf + Висока ступінь + + + LP НЧ + + In Gain + Вхід підсилення + + + + + Gain Підсилення + + Out Gain + Вих підсилення + + + Bandwidth: Ширина смуги: - Resonance : - Резонанс: - - - Frequency: - Частота: - - + Octave Октава - Low-shelf - + + Resonance : + Резонанс: - High-shelf - + + Frequency: + Частота: - Input gain - Вхідне підсилення + + lp grp + нч grp - Output gain - Вихідне підсилення - - - LP group - - - - HP group - + + hp grp + вч grp EqHandle + Reso: Резон: + BW: ШС: + + Freq: Част: + + ExportProjectDialog + + + Export project + Експорт проекту + + + + Output + Вивід + + + + File format: + Формат файла: + + + + Samplerate: + Частота дискретизації: + + + + 44100 Hz + 44.1 КГц + + + + 48000 Hz + 48 КГц + + + + 88200 Hz + 88.2 КГц + + + + 96000 Hz + 96 КГц + + + + 192000 Hz + 192 КГц + + + + Depth: + Глибина: + + + + 16 Bit Integer + 16 Біт ціле + + + + 24 Bit Integer + 24 Біт ціле + + + + 32 Bit Float + 32 Біт плаваюча + + + + Stereo mode: + Стерео режим: + + + + Stereo + Стерео + + + + Joint Stereo + Об'єднане стерео + + + + Mono + Моно + + + + Bitrate: + Бітрейт: + + + + 64 KBit/s + 64 КБіт/с + + + + 128 KBit/s + 128 КБіт/с + + + + 160 KBit/s + 160 КБіт/с + + + + 192 KBit/s + 192 КБіт/с + + + + 256 KBit/s + 256 КБіт/с + + + + 320 KBit/s + 320 КБіт/с + + + + Use variable bitrate + Використовувати змінний бітрейт + + + + Quality settings + Налаштування якості + + + + Interpolation: + Інтерполяція: + + + + Zero Order Hold + Нульова затримка + + + + Sinc Fastest + Синхр. Швидка + + + + Sinc Medium (recommended) + Синхр. Середня (рекомендовано) + + + + Sinc Best (very slow!) + Синхр. краща (дуже повільно!) + + + + Oversampling (use with care!): + Передискретизація (використовувати обережно!): + + + + 1x (None) + 1х (Ні) + + + + 2x + + + + + 4x + + + + + 8x + + + + + Export as loop (remove end silence) + Експортувати як петлю (прибрати тишу в кінці) + + + + Export between loop markers + Експорт між маркерами циклу + + + + Start + Почати + + + + Cancel + Відміна + + + + 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! + Не вдалось відкрити файл %1 для запису. +Перевірте, чи маєте ви права на запис файлу і каталог що його містить і спробуйте знову! + + + + Export project to %1 + Експорт проекту в %1 + + + + Error + Помилка + + + + Error while determining file-encoder device. Please try to choose a different output format. + Помилка при визначенні кодека файлу. Спробуйте вибрати інший формат виводу. + + + + Rendering: %1% + Обробка: %1% + + + Compression level: + + + + (fastest) + + + + (default) + + + + (smallest) + + + + + Expressive + + Selected graph + Обраний графік + + + A1 + + + + A2 + + + + A3 + + + + W1 smoothing + + + + W2 smoothing + + + + W3 smoothing + + + + PAN1 + + + + PAN2 + + + + REL TRANS + + + + + Fader + + + + Please enter a new value between %1 and %2: + Введіть нове значення від %1 до %2: + + + + FileBrowser + + + Browser + Оглядач файлів + + + Search + + + + Refresh list + + + + + FileBrowserTreeWidget + + + Send to active instrument-track + З'єднати з активним інструментом-доріжкою + + + + Open in new instrument-track/Song Editor + Відкрити в новій інструментальній доріжці/Музичному редакторі + + + + Open in new instrument-track/B+B Editor + Відкрити в новій інструментальній доріжці/Біт + Бас редакторі + + + + Loading sample + Завантаження запису + + + + Please wait, loading sample for preview... + Будь-ласка почекайте, запис завантажується для перегляду ... + + + + Error + Помилка + + + + does not appear to be a valid + не являється дійсним + + + + file + файл + + + + --- Factory files --- + --- Заводські файли --- + + FlangerControls + + Delay Samples + Затримка семплів + + + + Lfo Frequency + Частота LFO + + + Seconds Секунд + Regen Перегенерувати + Noise Шум + Invert Інвертувати - - Delay samples - - - - LFO frequency - - FlangerControlsDialog + DELAY - + ЗАТРИМ + + Delay Time: + Час затримки: + + + RATE - + ЧАСТ + + Period: + Період: + + + AMNT ГЛИБ + Amount: - + Величина: + FDBK - + FDBK + + Feedback Amount: + Величина повернення: + + + NOISE - + ШУМ + + White Noise Amount: + Об'єм білого шуму: + + + Invert Інвертувати + + + FxLine - Period: - + + Channel send amount + Величина відправки каналу - Delay time: - + + 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. + + Канал ефектів (ЕФ) отримує сигнал на вхід від однієї або декількох інструментальних доріжок. +У свою чергу його можна підключити до декількох інших каналам ефектів. ЛММС автоматично запобігає нескінченному повтореню і не дозволяє створювати з'єднання, які приведуть до нескінченного повторення. +Щоб з'єднати один канал з іншим, виберіть канал ефектів і натисніть кнопку надіслати на каналі, в який потрібно надіслати. Регулятор під кнопкою "надіслати" контролює рівень сигналу, що посилається на канал. +Можна прибирати і рухати канали ефектів через контекстне меню, якщо натиснути правою кнопкою миші по каналу ефектів. - Feedback amount: - + + Move &left + Рухати вліво &L - White noise amount: - + + Move &right + Рухати вправо &R + + + + Rename &channel + Перейменувати канал &C + + + + R&emove channel + Видалити канал &e + + + + Remove &unused channels + Видалити канали які &не використовуються - FreeBoyInstrument + FxMixer - Sweep time - Час поширення + + Master + Головний - Sweep direction - Напрям поширення + + + + FX %1 + Ефект %1 - Channel 1 volume - Гучність першого каналу + + Volume + Гучність - Volume sweep direction - Обсяг напрямку поширення + + Mute + Тиша - Length of each step in sweep - Довжина кожного такту в поширенні - - - Channel 2 volume - Гучність другого каналу - - - Channel 3 volume - Гучність третього каналу - - - Channel 4 volume - Гучність четвертого каналу - - - Channel 1 to SO2 (Left) - Від першого каналу до SO2 (лівий канал) - - - Channel 2 to SO2 (Left) - Від другого каналу до SO2 (лівий канал) - - - Channel 3 to SO2 (Left) - Від третього каналу до SO2 (лівий канал) - - - Channel 4 to SO2 (Left) - Від четвертого каналу до SO2 (лівий канал) - - - Channel 1 to SO1 (Right) - Від першого каналу до SO1 (правий канал) - - - Channel 2 to SO1 (Right) - Від другого каналу до SO1 (правий канал) - - - Channel 3 to SO1 (Right) - Від третього каналу до SO1 (правий канал) - - - Channel 4 to SO1 (Right) - Від четвертого каналу до SO1 (правий канал) - - - Treble - Дискант - - - Bass - Бас - - - Shift Register width - Зміщення ширини регістра - - - Sweep rate shift amount - - - - Wave pattern duty cycle - - - - Right output level - - - - Left output level - + + Solo + Соло - FreeBoyInstrumentView + FxMixerView - Length of each step in sweep: - Довжина кожного кроку в розгортці: + + FX-Mixer + Мікшер Ефектів - Length of each step in sweep - Довжина кожного кроку в розгортці + + FX Fader %1 + Повзунок Ефекту %1 - Treble: - Дискант: + + Mute + Тиша - Treble - Дискант + + Mute this FX channel + Тиша на цьому каналі Ефекту - Bass: - Бас: + + Solo + Соло - Bass - Бас + + Solo FX channel + Соло каналу ЕФ + + + FxRoute - Sweep time: - - - - Sweep time - Час поширення - - - Sweep rate shift amount: - - - - Sweep rate shift amount - - - - Wave pattern duty cycle: - - - - Wave pattern duty cycle - - - - Square channel 1 volume: - - - - Square channel 1 volume - - - - Square channel 2 volume: - - - - Square channel 2 volume - - - - Wave pattern channel volume: - - - - Wave pattern channel volume - - - - Noise channel volume: - - - - Noise channel volume - - - - SO1 volume (Right): - - - - SO1 volume (Right) - - - - SO2 volume (Left): - - - - SO2 volume (Left) - - - - Sweep direction - Напрям поширення - - - Volume sweep direction - Обсяг напрямку поширення - - - Shift register width - - - - Channel 1 to SO1 (Right) - Від першого каналу до SO1 (правий канал) - - - Channel 2 to SO1 (Right) - Від другого каналу до SO1 (правий канал) - - - Channel 3 to SO1 (Right) - Від третього каналу до SO1 (правий канал) - - - Channel 4 to SO1 (Right) - Від четвертого каналу до SO1 (правий канал) - - - Channel 1 to SO2 (Left) - Від першого каналу до SO2 (лівий канал) - - - Channel 2 to SO2 (Left) - Від другого каналу до SO2 (лівий канал) - - - Channel 3 to SO2 (Left) - Від третього каналу до SO2 (лівий канал) - - - Channel 4 to SO2 (Left) - Від четвертого каналу до SO2 (лівий канал) - - - Wave pattern graph - + + + Amount to send from channel %1 to channel %2 + Величина відправки з каналу %1 на канал %2 GigInstrument + Bank Банк + Patch Патч + Gain Підсилення @@ -1194,1125 +2976,3784 @@ GigInstrumentView + + Open other GIG file + Відкрити інший GIG файл + + + + Click here to open another GIG file + Натисніть, щоб відкрити інший GIG файл + + + + Choose the patch + Вибрати патч + + + + Click here to change which patch of the GIG file to use + Натисніть для зміни використовуваного патчу GIG файлу + + + + + Change which instrument of the GIG file is being played + Змінити інструмент, який відтворює GIG файл + + + + Which GIG file is currently being used + Який GIG файл зараз використовується + + + + Which patch of the GIG file is currently being used + Який патч GIG файлу зараз використовується + + + + Gain + Підсилення + + + + Factor to multiply samples by + Фактор множення семплів + + + Open GIG file Відкрити GIG файл + GIG Files (*.gig) GIG Файли (*.gig) + + + GuiApplication - Choose patch - + + Working directory + Робочий каталог LMMS - Gain: - Підсилення: + + The LMMS working directory %1 does not exist. Create it now? You can change the directory later via Edit -> Settings. + Робочий каталог LMMS (%1) не існує. Створити його? Пізніше ви зможете змінити його через Правку -> Параметри. + + + + Preparing UI + Підготовка користувацького інтерфейсу + + + + Preparing song editor + Підготовка музичного редактора + + + + Preparing mixer + Підготовка міксера + + + + Preparing controller rack + Підготовка стійки контролерів + + + + Preparing project notes + Підготовка заміток проекту + + + + Preparing beat/bassline editor + Підготовка ритм/бас редактора + + + + Preparing piano roll + Підготовка нотного редактора + + + + Preparing automation editor + Підготовка редактора автоматизації + + + + InstrumentFunctionArpeggio + + + Arpeggio + Арпеджіо + + + + Arpeggio type + Тип арпеджіо + + + + Arpeggio range + Діапазон арпеджіо + + + + Cycle steps + Зациклити такти + + + + Skip rate + Частота пропуску + + + + Miss rate + Частота пропуску + + + + Arpeggio time + Період арпеджіо + + + + Arpeggio gate + Шлюз арпеджіо + + + + Arpeggio direction + Напрямок арпеджіо + + + + Arpeggio mode + Режим арпеджіо + + + + Up + Вгору + + + + Down + Вниз + + + + Up and down + Вгору та вниз + + + + Down and up + Вниз та вгору + + + + Random + Випадково + + + + Free + Вільно + + + + Sort + Сортувати + + + + Sync + Синхронізувати + + + + 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 + RANGE + + + + Arpeggio range: + Діапазон арпеджіо: + + + + octave(s) + Октав(а/и) + + + + Use this knob for setting the arpeggio range in octaves. The selected arpeggio will be played within specified number of octaves. + Використовуйте цю ручку, щоб встановити діапазон арпеджіо (в октавах). Обраний тип арпеджіо охоплюватиме вказану кількість октав. + + + + CYCLE + ЦИКЛ + + + + Cycle notes: + Зациклити ноти: + + + + note(s) + нота(и) + + + + 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 + ПРОПУСК + + + + Skip rate: + Частота пропуску: + + + + + + % + % + + + + 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 + TIME + + + + Arpeggio time: + Період арпеджіо: + + + + ms + мс + + + + Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. + Регулювання періоду арпеджіо - час (в мілісекундах), який має звучати кожен тон арпеджіо. + + + + GATE + GATE + + + + 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: + Акорд: + + + + Direction: + Напрямок: + + + + Mode: + Режим: + + + + InstrumentFunctionNoteStacking + + + octave + Октава + + + + + Major + Мажорний + + + + Majb5 + Majb5 + + + + 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 + Maj7 + + + + Maj7b5 + Maj7b5 + + + + Maj7#5 + Maj7#5 + + + + Maj7#11 + Maj7#11 + + + + Maj7add13 + Maj7add13 + + + + m7 + m7 + + + + m7b5 + m7b5 + + + + m7b9 + m7b9 + + + + m7add11 + m7add11 + + + + m7add13 + m7add13 + + + + m-Maj7 + m-Maj7 + + + + m-Maj7add11 + m-Maj7add11 + + + + m-Maj7add13 + m-Maj7add13 + + + + 9 + 9 + + + + 9sus4 + 9sus4 + + + + add9 + add9 + + + + 9#5 + 9#5 + + + + 9b5 + 9b5 + + + + 9#11 + 9#11 + + + + 9b13 + 9b13 + + + + Maj9 + Maj9 + + + + Maj9sus4 + Maj9sus4 + + + + Maj9#5 + Maj9#5 + + + + Maj9#11 + Maj9#11 + + + + m9 + m9 + + + + madd9 + madd9 + + + + m9b5 + m9b5 + + + + m9-Maj7 + m9-Maj7 + + + + 11 + 11 + + + + 11b9 + 11b9 + + + + Maj11 + Maj11 + + + + m11 + m11 + + + + m-Maj11 + m-Maj11 + + + + 13 + 13 + + + + 13#9 + 13#9 + + + + 13b9 + 13b9 + + + + 13b5b9 + 13b5b9 + + + + Maj13 + Maj13 + + + + m13 + m13 + + + + m-Maj13 + m-Maj13 + + + + Harmonic minor + Гармонійний мінор + + + + Melodic minor + Мелодійний мінор + + + + Whole tone + Цілий тон + + + + Diminished + Понижений + + + + Major pentatonic + Пентатонік major + + + + Minor pentatonic + Пентатонік major + + + + Jap in sen + Япон in sen + + + + Major bebop + Major Бібоп + + + + Dominant bebop + Домінтний бібоп + + + + Blues + Блюз + + + + Arabic + Арабська + + + + Enigmatic + Загадкова + + + + Neopolitan + Неаполітанська + + + + Neopolitan minor + Неаполітанський мінор + + + + Hungarian minor + Угорський мінор + + + + Dorian + Дорійська + + + + Phrygian + Фрігійський + + + + Lydian + Лідійська + + + + Mixolydian + Міксолідійська + + + + Aeolian + Еолійська + + + + Locrian + Локріанська + + + + Minor + Мінор + + + + Chromatic + Хроматична + + + + Half-Whole Diminished + Напів-зниження + + + + 5 + 5 + + + + Phrygian dominant + Фрігійська домінанта + + + + Persian + Перська + + + + Chords + Акорди + + + + Chord type + Тип акорду + + + + Chord range + Діапазон акорду + + + + InstrumentFunctionNoteStackingView + + + STACKING + Стиковка + + + + Chord: + Акорд: + + + + RANGE + ДІАПАЗОН + + + + Chord range: + Діапазон акорду: + + + + octave(s) + Октав[а/и] + + + + 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 + УВІМК MIDI ВХІД + + + + + CHANNEL + CHANNEL + + + + + VELOCITY + VELOCITY + + + + ENABLE MIDI OUTPUT + УВІМК MIDI ВИВІД + + + + PROGRAM + PROGRAM + + + + NOTE + NOTE + + + + MIDI devices to receive MIDI events from + MiDi пристрої-джерела подій + + + + MIDI devices to send MIDI events to + MiDi пристрої для відправки подій на них + + + + CUSTOM BASE VELOCITY + СВОЯ БАЗОВА ШВИДКІСТЬ + + + + Specify the velocity normalization base for MIDI-based instruments at 100% note velocity + Визначає базову швидкість нормальізаціі для MiDi інструментів при гучності ноти 100% + + + + BASE VELOCITY + БАЗОВА ШВИДКІСТЬ + + + + InstrumentMiscView + + + MASTER PITCH + ОСНОВНА ТОНАЛЬНІСТЬ + + + + Enables the use of Master Pitch + Включає використання основної тональності + + + + InstrumentSoundShaping + + + VOLUME + VOLUME + + + + Volume + Гучність + + + + CUTOFF + CUTOFF + + + + + Cutoff frequency + Зріз частоти + + + + RESO + RESO + + + + Resonance + Резонанс + + + + Envelopes/LFOs + Обвідні/LFO + + + + Filter type + Тип фільтру + + + + Q/Resonance + Кіл./Резонансу + + + + LowPass + Низ.ЧФ + + + + HiPass + Вис.ЧФ + + + + BandPass csg + Серед.ЧФ csg + + + + BandPass czpg + Серед.ЧФ czpg + + + + Notch + Смуго-загороджуючий + + + + Allpass + Всі проходять + + + + Moog + Муг + + + + 2x LowPass + 2х Низ.ЧФ + + + + RC LowPass 12dB + RC Низ.ЧФ 12дБ + + + + RC BandPass 12dB + RC Серед.ЧФ 12 дБ + + + + RC HighPass 12dB + RC Вис.ЧФ 12дБ + + + + RC LowPass 24dB + RC Низ.ЧФ 24дБ + + + + RC BandPass 24dB + RC Серед.ЧФ 24дБ + + + + RC HighPass 24dB + RC Вис.ЧФ 24дБ + + + + Vocal Formant Filter + Фільтр Вокальної форманти + + + + 2x Moog + 2x Муг + + + + SV LowPass + SV Низ.ЧФ + + + + SV BandPass + SV Серед.ЧФ + + + + SV HighPass + SV Вис.ЧФ + + + + SV Notch + SV Смуго-заг + + + + Fast Formant + Швидка форманта + + + + Tripole + Тріполі + + + + InstrumentSoundShapingView + + + TARGET + ЦЕЛЬ + + + + 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...! + Ця вкладка дозволяє вам налаштувати обвідні. Вони дуже важливі для налаштування звучання. +Наприклад, за допомогою обвідної гучності ви можете задати залежність гучності звучання від часу. Якщо вам знадобиться емулювати м'які струнні, просто задайте більше часу наростання і зникнення звуку. За допомогою обвідних і низькочастотного осциллятора (LFO) ви в кілька кліків миші зможете створити просто неймовірні звуки! + + + + 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 + ЧАСТ + + + + cutoff frequency: + Срез частот: + + + + 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 + РЕЗО + + + + Resonance: + Підсилення: + + + + 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. + Обвідні, LFO і фільтри не підтримуються цим інструментом. InstrumentTrack + + With this knob you can set the volume of the opened channel. + Регулювання гучності поточного каналу. + + + + + unnamed_track + безіменна_доріжка + + + + Base note + Опорна нота + + + + Volume + Гучність + + + + Panning + Стерео + + + + Pitch + Тональність + + + + Pitch range + Діапазон тональності + + + + FX channel + Канал ЕФ + + + + Master Pitch + Основна тональність + + + + Default preset Основна предустановка + + InstrumentTrackView + + + Volume + Гучність + + + + Volume: + Гучність: + + + + VOL + ГУЧН + + + + Panning + Баланс + + + + Panning: + Баланс: + + + + PAN + БАЛ + + + + MIDI + MIDI + + + + Input + Вхід + + + + Output + Вихід + + + + FX %1: %2 + ЕФ %1: %2 + + + + 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 + Обвідна, фільтр & LFO + + + + Chord stacking & arpeggio + Укладання акордів & арпеджіо + + + + Effects + Ефекти + + + + MIDI settings + Параметри MIDI + + + + Miscellaneous + Різне + + + + Save preset + Зберегти передустановку + + + + XML preset file (*.xpf) + XML файл налаштувань (*.xpf) + + + + Plugin + Модуль + + + + Knob + + + Set linear + Встановити лінійний + + + + Set logarithmic + Встановити логарифмічний + + + + Please enter a new value between -96.0 dBFS and 6.0 dBFS: + Введіть нове значення від -96,0 дБFS до 6,0 дБFS: + + + + Please enter a new value between %1 and %2: + Введіть нове значення від %1 до %2: + + + + LadspaControl + + + Link channels + Зв'язати канали + + LadspaControlDialog + Link Channels Зв'язати канали + Channel Канал + + LadspaControlView + + + Link channels + Зв'язати канали + + + + Value: + Значення: + + + + Sorry, no help available. + Вибачте, довідки немає. + + LadspaEffect + Unknown LADSPA plugin %1 requested. Запитаний невідомий модуль LADSPA «%1». + + LcdSpinBox + + + Please enter a new value between %1 and %2: + Введіть нове значення від %1 до %2: + + + + LeftRightNav + + + + + Previous + Попередній + + + + + + Next + Наступний + + + + Previous (%1) + Попередній (%1) + + + + Next (%1) + Наступний (%1) + + + + LfoController + + + LFO Controller + Контролер LFO + + + + Base value + Основне значення + + + + Oscillator speed + Швидкість хвилі + + + + Oscillator amount + Розмір хвилі + + + + Oscillator phase + Фаза хвилі + + + + Oscillator waveform + Форма хвилі + + + + Frequency Multiplier + Множник частоти + + + + LfoControllerDialog + + + LFO + LFO + + + + LFO Controller + Контролер LFO + + + + BASE + БАЗА + + + + Base amount: + Базове значення: + + + + todo + доробити + + + + SPD + ШВИД + + + + LFO-speed: + Швидкість LFO: + + + + Use this knob for setting speed of the LFO. The bigger this value the faster the LFO oscillates and the faster the effect. + Ця ручка встановлює швидкість LFO. Чим більше значення, тим більша частота осциллятора. + + + + AMNT + ГЛИБ + + + + Modulation amount: + Кількість модуляції: + + + + 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. + Ця ручка встановлює глибину модуляції для LFO. Чим більше значення, тим більшою мірою обрана характеристика (н-д, гучність або частота зрізу) буде залежати від ГНЧ (LFO). + + + + PHS + ФАЗА + + + + Phase offset: + Зсув фази: + + + + degrees + градуси + + + + 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. + Ця ручка встановлює початкову фазу НизькоЧастотного Осциллятора (LFO), т. б. Точку, з якої осциллятор починає виробляти сигнал. Наприклад, якщо ви задали синусоїдальну форму сигналу і початкову фазу 180º, хвиля спочатку піде вниз, а не вгору, так само як і для квадратної хвилі. + + + + Click here for a sine-wave. + Синусоїда. + + + + Click here for a triangle-wave. + Згенерувати трикутний сигнал. + + + + Click here for a saw-wave. + Згенерувати зигзаг. + + + + Click here for a square-wave. + Згенерувати квадратний сигнал. + + + + Click here for a moog saw-wave. + Натисніть для зигзагоподібної муг-хвилі. + + + + Click here for an exponential wave. + Генерувати експонентний сигнал. + + + + Click here for white-noise. + Згенерувати білий шум. + + + + Click here for a user-defined shape. +Double click to pick a file. + Натисніть тут для визначення своєї форми. +Подвійне натискання для вибору файлу. + + + + LmmsCore + + + Generating wavetables + Генерування синтезатора звукозаписів + + + + Initializing data structures + Ініціалізація структур даних + + + + Opening audio and midi devices + Відкриття аудіо та міді пристроїв + + + + Launching mixer threads + Запуск потоків міксера + + + + MainWindow + + + Configuration file + Файл налаштувань + + + + Error while parsing configuration file at line %1:%2: %3 + Помилка під час обробки файлу налаштувань в рядку %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! + Не вдалось відкрити файл %1 для запису. +Перевірте, чи маєте ви права на запис файлу і каталог що його містить і спробуйте знову! + + + + 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? + Присутній файл відновлення. Схоже, остання сесія не закінчилася належним чином або інший екземпляр LMMS вже запущений. Ви хочете, відновити проект цієї сесії? + + + + + + Recover + Відновлення + + + + Recover the file. Please don't run multiple instances of LMMS when you do this. + Відновлення файлу. Будь ласка, не запускайте кілька копій LMMS під час цієї операції. + + + + + + Discard + Відкинути + + + + Launch a default session and delete the restored files. This is not reversible. + Запуск за замовчуванням з видаленням файла відновлення. Ця дія не відворотня. + + + + Version %1 + Версія %1 + + + + Preparing plugin browser + Підготовка браузера плагінів + + + + Preparing file browsers + Підготовка переглядача файлів + + + + My Projects + Мої проекти + + + + My Samples + Мої записи + + + + My Presets + Мої передустановки + + + + My Home + Моя домашня тека + + + + Root directory + Кореневий каталог + + + + Volumes + Гучності + + + + My Computer + Мій комп'ютер + + + + Loading background artwork + Завантаження фонового зображення + + + + &File + &Файл + + + + &New + &N Новий + + + + New from template + Новий проект по шаблону + + + + &Open... + &O Відкрити... + + + + &Recently Opened Projects + &Нещодавно відкриті проекти + + + + &Save + &S Зберегти + + + + Save &As... + &A Зберегти як... + + + + Save as New &Version + Зберегти як нову &Версію + + + + Save as default template + Зберегти як шаблон за замовчуванням + + + + Import... + Імпорт... + + + + E&xport... + &X Експорт ... + + + + E&xport Tracks... + &Експортувати треки ... + + + + Export &MIDI... + Експорт в &MIDI ... + + + + &Quit + &Q Вийти + + + + &Edit + &E Редагування + + + + Undo + Скасувати + + + + Redo + Повторити + + + + Settings + Параметри + + + + &View + &V Перегляд + + + + &Tools + &T Сервіс + + + + &Help + &H Довідка + + + + Online Help + Онлайн Допомога + + + + Help + Довідка + + + + What's This? + Що це? + + + + About + Про програму + + + + Create new project + Створити новий проект + + + + Create new project from template + Створити новий проект по шаблону + + + + Open existing project + Відкрити існуючий проект + + + + Recently opened projects + Нещодавні проекти + + + + Save current project + Зберегти поточний проект + + + + Export current project + Експорт проекту + + + + What's this? + Що це? + + + + Toggle metronome + Переключити метроном + + + + Show/hide Song-Editor + Показати/сховати музичний редактор + + + + 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 + Показати/сховати ритм-бас редактор + + + + 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 + Показати/сховати нотний редактор + + + + Click here to show or hide the Piano-Roll. With the help of the Piano-Roll you can edit melodies in an easy way. + Запуск редатора нот. З його допомогою ви можете легко редагувати мелодії. + + + + Show/hide Automation Editor + Показати/сховати редактор автоматизації + + + + 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 + Показати/сховати мікшер ЕФ + + + + 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. + Сховати / показати мікшер ефектів. Він є потужним інструментом для управління ефектами. Ви можете вставляти ефекти в різні канали. + + + + Show/hide project notes + Показати/сховати замітки до проекту + + + + Click here to show or hide the project notes window. In this window you can put down your project notes. + Ця кнопка показує / ховає вікно з нотатками. У цьому вікні ви можете поміщати будь-які коментарі до своєї композиції. + + + + Show/hide controller rack + Показати/сховати керування контролерами + + + + Untitled + Без назви + + + + Recover session. Please save your work! + Відновлення сесії. Будь ласка, збережіть свою роботу! + + + + LMMS %1 + 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) + LMMS (*.mmp *.mmpz) + + + + Save Project + Зберегти проект + + + + LMMS Project + LMMS проект + + + + LMMS Project Template + Шаблон LMMS проекту + + + + 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. + Поки що довідка для LMMS не написана. +Ймовірно, Ви зможете знайти потрібні матеріали на http://lmms.sf.net/wiki. + + + + 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 + Включити позначення нот у музичному редакторі + + + + MeterDialog + + + + Meter Numerator + Шкала чисел + + + + + Meter Denominator + Шкала поділів + + + + TIME SIG + ПЕРІОД + + + + MeterModel + + + Numerator + Чисельник + + + + Denominator + Знаменник + + + + MidiController + + + MIDI Controller + Контролер MIDI + + + + unnamed_midi_controller + нерозпізнаний міді контролер + + 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. + Ви не встановили SoundFont за замовчуванням в налаштуваннях (Правка-> Налаштування), тому після імпорту міді файлу звук відтворюватися не буде. +Вам слід завантажити основний MiDi SoundFont, вказати його в налаштуваннях і спробувати знову. + + + 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. Ви не увімкнули підтримку програвача SoundFont2 при компіляції LMMS, він використовується для додавання основного звуку в імпортовані Міді файли, тому після імпорту цього міді файлу звуку не буде. + Track Трек + + + MidiJack - You have not 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. - + + JACK server down + When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (title) + JACK-сервер не доступний + + + + The JACK server seems to be shuted down. + When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (dialog message) + Здається, сервер JACK відключений. + + + + MidiPort + + + Input channel + Вхід + + + + Output channel + Вихід + + + + Input controller + Контролер входу + + + + Output controller + Контролер виходу + + + + Fixed input velocity + Постійна швидкість введення + + + + Fixed output velocity + Постійна швидкість виведення + + + + Fixed output note + Постійний вихід нот + + + + Output MIDI program + Програма для виведення MiDi + + + + Base velocity + Базова швидкість + + + + Receive MIDI-events + Приймати події MIDI + + + + Send MIDI-events + Відправляти події MIDI + + + + MidiSetupWidget + + + DEVICE + ПРИСТРІЙ MonstroInstrument + + Osc 1 Volume + Гучність осциллятора 1 + + + + Osc 1 Panning + Баланс осциллятора 1 + + + + Osc 1 Coarse detune + Грубе підстроювання осциллятора 1 + + + + Osc 1 Fine detune left + Точне підстроювання лівого каналу осциллятора 1 + + + + Osc 1 Fine detune right + Точне підстроювання правого каналу осциллятора 1 + + + + Osc 1 Stereo phase offset + Зміщення стерео-фази осциллятора 1 + + + + Osc 1 Pulse width + Довжина імпульсу осциллятора 1 + + + + Osc 1 Sync send on rise + Синхронізація підйому осциллятора 1 + + + + Osc 1 Sync send on fall + Синхронізація падіння осциллятора 1 + + + + Osc 2 Volume + Гучність осциллятора 2 + + + + Osc 2 Panning + Баланс осциллятора 2 + + + + Osc 2 Coarse detune + Грубе підстроювання осциллятора 2 + + + + Osc 2 Fine detune left + Точне підстроювання лівого каналу осциллятора 2 + + + + Osc 2 Fine detune right + Точне підстроювання правого каналу осциллятора 2 + + + + Osc 2 Stereo phase offset + Зміщення стерео-фази осциллятора 2 + + + + Osc 2 Waveform + Форма сигналу осциллятора 2 + + + + Osc 2 Sync Hard + Жорстка синхронізація осциллятора 2 + + + + Osc 2 Sync Reverse + Верерс синхронізація осциллятора 2 + + + + Osc 3 Volume + Гучність осциллятора 3 + + + + Osc 3 Panning + Баланс осциллятора 3 + + + + Osc 3 Coarse detune + Грубе підстроювання осциллятора 3 + + + Osc 3 Stereo phase offset Зміщення стерео-фази осциллятора 3 + + Osc 3 Sub-oscillator mix + Змішення суб-генератора осциллятора 3 + + + + Osc 3 Waveform 1 + Форма 1 сигналу осциллятора 3 + + + + Osc 3 Waveform 2 + Форма 2 сигналу осциллятора 3 + + + + Osc 3 Sync Hard + Жорстка синхронізація осциллятора 3 + + + + Osc 3 Sync Reverse + Верерс синхронізація осциллятора 3 + + + + LFO 1 Waveform + Форма сигналу LFO 1 + + + + LFO 1 Attack + Вступ LFO 1 + + + + LFO 1 Rate + Темп LFO 1 + + + + LFO 1 Phase + Фаза LFO 1 + + + + LFO 2 Waveform + Форма сигналу LFO 2 + + + + LFO 2 Attack + Вступ LFO 2 + + + + LFO 2 Rate + Темп LFO 2 + + + + LFO 2 Phase + Фаза LFO 2 + + + + Env 1 Pre-delay + Затримка обвідної 1 + + + + Env 1 Attack + Вступ обвідної 1 + + + + Env 1 Hold + Утримання обвідної 1 + + + + Env 1 Decay + Згасання обвідної 1 + + + + Env 1 Sustain + Витримка обвідної 1 + + + + Env 1 Release + Зменшення обвідної 1 + + + + Env 1 Slope + Нахил обвідної 1 + + + + Env 2 Pre-delay + Затримка обвідної 2 + + + + Env 2 Attack + Вступ обвідної 2 + + + + Env 2 Hold + Утримання обвідної 2 + + + + Env 2 Decay + Згасання обвідної 2 + + + + Env 2 Sustain + Витримка обвідної 2 + + + + Env 2 Release + Зменшення обвідної 2 + + + + Env 2 Slope + Нахил обвідної 2 + + + + Osc2-3 modulation + Модуляція осцилляторів 2-3 + + + Selected view Перегляд обраного + + Vol1-Env1 + Гучн1-Обв1 + + + + Vol1-Env2 + Гучн1-Обв2 + + + + Vol1-LFO1 + Гучн1-LFO1 + + + + Vol1-LFO2 + Гучн1-LFO2 + + + + Vol2-Env1 + Гучн2-Обв1 + + + + Vol2-Env2 + Гучн2-Обв2 + + + + Vol2-LFO1 + Гучн2-LFO1 + + + + Vol2-LFO2 + Гучн2-LFO2 + + + + Vol3-Env1 + Гучн3-Обв1 + + + + Vol3-Env2 + Гучн3-Обв2 + + + + Vol3-LFO1 + Гучн3-LFO1 + + + + Vol3-LFO2 + Гучн3-LFO2 + + + + Phs1-Env1 + Фаз1-Обв1 + + + + Phs1-Env2 + Фаз1-Обв2 + + + + Phs1-LFO1 + Фаз1-LFO1 + + + + Phs1-LFO2 + Фаз1-LFO2 + + + + Phs2-Env1 + Фаз2-Обв1 + + + + Phs2-Env2 + Фаз2-Обв2 + + + + Phs2-LFO1 + Фаз2-LFO1 + + + + Phs2-LFO2 + Фаз2-LFO2 + + + + Phs3-Env1 + Фаз3-Обв1 + + + + Phs3-Env2 + Фаз3-Обв2 + + + + Phs3-LFO1 + Фаз3-LFO1 + + + + Phs3-LFO2 + Фаз3-LFO2 + + + + Pit1-Env1 + Тон1-Обв1 + + + + Pit1-Env2 + Тон1-Обв2 + + + + Pit1-LFO1 + Тон1-LFO1 + + + + Pit1-LFO2 + Тон1-LFO2 + + + + Pit2-Env1 + Тон2-Обв1 + + + + Pit2-Env2 + Тон2-Обв2 + + + + Pit2-LFO1 + Тон2-LFO1 + + + + Pit2-LFO2 + Тон2-LFO2 + + + + Pit3-Env1 + Тон3-Обв1 + + + + Pit3-Env2 + Тон3-Обв2 + + + + Pit3-LFO1 + Тон3-LFO1 + + + + Pit3-LFO2 + Тон3-LFO2 + + + + PW1-Env1 + PW1-Обв1 + + + + PW1-Env2 + PW1-Обв2 + + + + PW1-LFO1 + PW1-LFO1 + + + + PW1-LFO2 + PW1-LFO2 + + + + Sub3-Env1 + Sub3-Обв1 + + + + Sub3-Env2 + Sub3-Обв2 + + + + Sub3-LFO1 + Sub3-LFO1 + + + + Sub3-LFO2 + Sub3-LFO2 + + + + Sine wave Синусоїда + Bandlimited Triangle wave Трикутна хвиля з обмеженою смугою + Bandlimited Saw wave Зигзаг хвиля з обмеженою смугою + Bandlimited Ramp wave Спадаюча хвиля з обмеженою смугою + Bandlimited Square wave Квадратна хвиля з обмеженою смугою + Bandlimited Moog saw wave Муг-зигзаг хвиля з обмеженою смугою + + Soft square wave М'яка прямокутна хвиля + Absolute sine wave Абсолютна синусоїдна хвиля + + Exponential wave Експоненціальна хвиля + White noise Білий шум + Digital Triangle wave Цифрова трикутна хвиля + Digital Saw wave Цифрова зигзаг хвиля + Digital Ramp wave Цифрова спадна хвиля + Digital Square wave Цифрова квадратна хвиля + Digital Moog saw wave Цифрова Муг-зигзаг хвиля + Triangle wave Трикутна хвиля + Saw wave Зигзаг + Ramp wave Спадна хвиля + Square wave Квадратна хвиля + Moog saw wave Муг-зигзаг хвиля + Abs. sine wave Синусоїда по модулю + Random Випадково + Random smooth Випадкове зглажування - - Osc 1 volume - - - - Osc 1 panning - - - - 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 - - - - Osc 2 panning - - - - 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 - - - - Osc 3 panning - - - - Osc 3 coarse detune - - - - Osc 3 sub-oscillator mix - - - - Osc 3 waveform 1 - - - - Osc 3 waveform 2 - - - - Osc 3 sync hard - - - - Osc 3 Sync reverse - - - - LFO 1 waveform - - - - LFO 1 attack - - - - LFO 1 rate - - - - LFO 1 phase - - - - LFO 2 waveform - - - - LFO 2 attack - - - - LFO 2 rate - - - - LFO 2 phase - - - - Env 1 pre-delay - - - - Env 1 attack - - - - 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 - - - - Osc 2+3 modulation - - - - Osc 1 - Vol env 1 - - - - Osc 1 - Vol env 2 - - - - Osc 1 - Vol LFO 1 - - - - Osc 1 - Vol LFO 2 - - - - Osc 2 - Vol env 1 - - - - Osc 2 - Vol env 2 - - - - Osc 2 - Vol LFO 1 - - - - Osc 2 - Vol LFO 2 - - - - Osc 3 - Vol env 1 - - - - Osc 3 - Vol env 2 - - - - Osc 3 - Vol LFO 1 - - - - Osc 3 - Vol LFO 2 - - - - Osc 1 - Phs env 1 - - - - Osc 1 - Phs env 2 - - - - Osc 1 - Phs LFO 1 - - - - Osc 1 - Phs LFO 2 - - - - Osc 2 - Phs env 1 - - - - Osc 2 - Phs env 2 - - - - Osc 2 - Phs LFO 1 - - - - Osc 2 - Phs LFO 2 - - - - Osc 3 - Phs env 1 - - - - Osc 3 - Phs env 2 - - - - Osc 3 - Phs LFO 1 - - - - Osc 3 - Phs LFO 2 - - - - Osc 1 - Pit env 1 - - - - Osc 1 - Pit env 2 - - - - Osc 1 - Pit LFO 1 - - - - Osc 1 - Pit LFO 2 - - - - Osc 2 - Pit env 1 - - - - Osc 2 - Pit env 2 - - - - Osc 2 - Pit LFO 1 - - - - Osc 2 - Pit LFO 2 - - - - Osc 3 - Pit env 1 - - - - Osc 3 - Pit env 2 - - - - Osc 3 - Pit LFO 1 - - - - Osc 3 - Pit LFO 2 - - - - Osc 1 - PW env 1 - - - - Osc 1 - PW env 2 - - - - Osc 1 - PW LFO 1 - - - - Osc 1 - PW LFO 2 - - - - Osc 3 - Sub env 1 - - - - Osc 3 - Sub env 2 - - - - Osc 3 - Sub LFO 1 - - - - Osc 3 - Sub LFO 2 - - MonstroView + Operators view Операторский вид + + 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 Матричний вигляд + + 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. + Матричний вид містить матрицю модуляції. Тут можна визначити модуляційні відношення між різними операторами. Кожен чутний оператор (осциллятори 1-3) мають 3-4 властивості, які можна модулювати будь-якими модуляторами. Використовуючи більше модуляцій збільшується навантаження на процесор. + +Вид ділиться на цілі модуляції, згруповані на цільовий осциллятор. Доступні цілі: гучність, тон, фаза, ширина пульсація і відношення з підлеглим (під-) осциллятором. Відзначимо що деякі цілі визначені тільки для одного осциллятора. + +Кожна ціль модуляції має 4 регулятори, по одному на кожен модулятор. За замовчуванням регулятори встановлені на 0, тобто без модуляції. Включення регуляторів на 1 веде до того, що модулятор впливає на ціль модуляції на стільки на скільки це можливо. Включення його в -1 робить те ж, але зі зворотньою модуляцією. + + + + + Volume Гучність + + + Panning Баланс + + + Coarse detune Грубе підстроювання + + + semitones півтон(а,ів) + + + Finetune left + Точне настроювання лівого каналу + + + + + + cents відсотків + + + Finetune right + Точне настроювання правого каналу + + + + + Stereo phase offset Зміщення стерео-фази + + + + + deg град + Pulse width Довжина імпульсу + Send sync on pulse rise Відправляти синхронізацію на підйомі імпульсу + Send sync on pulse fall Відправити синхронізацію на падінні пульсу + Hard sync oscillator 2 Жорстка синхронізація осциллятора 2 + Reverse sync oscillator 2 Верерс синхронізація осциллятора 2 + Sub-osc mix Мікс суб-осциляторів + Hard sync oscillator 3 Жорстка синхронізація осциллятора 3 + Reverse sync oscillator 3 Верерс синхронізація осциллятора 3 + + + + Attack Вступ + + Rate Частота вибірки + + Phase Фаза + + Pre-delay Передзатримка + + Hold Утримання + + Decay Згасання + + Sustain Витримка + + Release Зменшення + + Slope Нахил + + Mix Osc2 with Osc3 + Змішати Осц2 з Осц3 + + + + Modulate amplitude of Osc3 with Osc2 + Модулювати амплітуду осциллятора 3 сигналом з осц2 + + + + Modulate frequency of Osc3 with Osc2 + Модулювати частоту осциллятора 3 сигналом з осц2 + + + + Modulate phase of Osc3 with Osc2 + Модулювати фазу Осц3 осциллятором2 + + + + The CRS knob changes the tuning of oscillator 1 in semitone steps. + Регулятор CRS змінює налаштування осциллятора 1 у розмірі півтону. + + + + The CRS knob changes the tuning of oscillator 2 in semitone steps. + Регулятор CRS змінює налаштування осциллятора 2 у розмірі півтону. + + + + The CRS knob changes the tuning of oscillator 3 in semitone steps. + Регулятор CRS змінює налаштування осциллятора 3 у розмірі півтону. + + + + + + + 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. + FTL і FTR змінюють підстроювання осциллятора для лівого і правого каналів відповідно. Вони можуть додати стерео розстроювання осциллятора, яке розширює стерео картину і створює ілюзію космосу. + + + + + + The SPO knob modifies the difference in phase between left and right channels. Higher difference creates a wider stereo image. + Регулятор SPO змінює фазову різницю між лівим і правим каналами. Висока різниця створює більш широку стерео картину. + + + + 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. + PW регулятор контролює ширину пульсацій, також відому як робочий цикл осциллятора 1. Осциллятор 1 це цифровий імпульсний хвильовий генератор, він не відтворює сигнал з обмеженою смугою, це означає, що його можна використовувати як чутний осциллятор, але це призведе до накладення сигналів (або згладжування) . Його можна використовувати й як не чутне джерело синхронізуючого сигналу, для використання в синхронізації осцилляторів 2 і 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. + Надсилати синхронізацію при підвищенні: при включенні, сигнал синхронізації надсилається кожен раз коли стан осциллятора 1 змінюється з низького на високий, тобто коли амплітуда змінюється від -1 до 1. +Тон осциллятора 1, фаза і ширина пульсацій може впливати на час синхронізації, але гучність не має ефекту. Сигнал синхронізації надсилається незалежно для лівого і правого каналів. + + + + 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. + Надсилати синхронізацію при зниженні: при включенні, сигнал синхронізації надсилається кожен раз коли стан осциллятора 1 змінюється з виского на низьке, тобто коли амплітуда змінюється від 1 до -1. +Тон осциллятора 1, фаза і ширина пульсацій може впливати на час синхронізації, але гучність не має ефекту. Сигнал синхронізації надсилається незалежно для лівого і правого каналів. + + + + + Hard sync: Every time the oscillator receives a sync signal from oscillator 1, its phase is reset to 0 + whatever its phase offset is. + Жорстка синхронізація: Кожен раз при отриманні осциллятором сигналу синхронізації від осциллятора 1, його фаза скидається до 0 + його межа фази, якою б вона не була. + + + + + Reverse sync: Every time the oscillator receives a sync signal from oscillator 1, the amplitude of the oscillator gets inverted. + Реверс синхронізація: Кожен раз при отриманні сигналу синхронізації від осциллятора 1, амплітуда осциллятора перевертається. + + + + Choose waveform for oscillator 2. + Вибрати форму хвилі для осциллятора 2. + + + + Choose waveform for oscillator 3's first sub-osc. Oscillator 3 can smoothly interpolate between two different waveforms. + Виберіть форму хвилі для першого додаткового осциллятора осциллятора 3. Осциллятор 3 може м'яко переходити між двома різними хвилями. + + + + Choose waveform for oscillator 3's second sub-osc. Oscillator 3 can smoothly interpolate between two different waveforms. + Виберіть форму хвилі для другого додаткового осциллятора осциллятора 3. Осциллятор 3 може м'яко переходити між двома різними хвилями. + + + + 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. + SUB змінює змішування двох дод осцилляторів осциллятора 3. Кожен дод. осц. може бути встановлений для створення різних хвиль і осциллятор 3 може м'яко переходити між ними. Усі вхідні модуляції для осциллятора 3 застосовуються на обидва дод.осц./хвилі одним і тим же чином. + + + + 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. + На додаток до виділених модуляторів Монстро дозволяє виходу осциллятора 2 модулювати осцллятор 3. + +Змішаний (Mix) режим означає без модуляції: виходи осцилляторів просто змішуються один з одним. + + + + 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. + На додаток до виділених модуляторів Монстро дозволяє виходу осциллятора 2 модулювати осцллятор 3. + +AM режим значить Амплітуда Модуляції: Осциллятори 2 модулює амплітуду (гучність) осциллятора 3. + + + + 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. + На додаток до виділених модуляторів Монстро дозволяє виходу осциллятора 2 модулювати осцллятор 3. + +FM (ЧМ) режим означає Частотна Модуляція: осциллятор 2 модулює частоту (pitch, тональність) осциллятора 3. Частота модуляції відбувається у фазі модуляції, яка дає більш стабільний загальний тон, ніж "чиста" частотна модуляція. + + + + 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. + На додаток до виділених модуляторів Монстро дозволяє виходу осциллятора 2 модулювати осцллятор 3. + +PM (ФМ) режим означає Фазова Модуляція: Осциллятор 2 модулює фазу осциллятора 3. Це відрізняється від частотної модуляції тим, що зміни фаз не сумуються. + + + + 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... + Виберіть форму хвилі для LFO 1 (НизькоЧастотнийГенератор). +"Random" (Випадково) і "Random-smooth" (випадкове згладжування) - це спеціальні хвилі: вони створюють випадковий сигнал, де частота LFO контролює як часто змінюється стан генератора (LFO). +Згладжена версія переходить між цими станами з косинусоїдальною інтерполяцією. Ці випадкові режими можуть бути використані, щоб дати "життя" вашим налаштуванням - додати трішки аналогової непередбачуваності ... + + + + 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... + Виберіть форму хвилі для LFO 2 (НизкоЧастотнийГенератор). +"Random" (Випадково) і "Random-smooth" (випадкове згладжування) - це спеціальні хвилі: вони створюють випадковий сигнал, де частота LFO контролює як часто змінюється стан генератора (LFO). +Згладжена версія переходить між цими станами з косинусоїдальною інтерполяцією. Ці випадкові режими можуть бути використані, щоб дати "життя" вашим налаштуванням - додати трішки аналогової непередбачуваності ... + + + + + Attack causes the LFO to come on gradually from the start of the note. + Атака відповідає за плавність поведінки LFO від початку ноти. + + + + + Rate sets the speed of the LFO, measured in milliseconds per cycle. Can be synced to tempo. + Rate (Частота) встановлює швидкість LFO, вимірювану в мілісекундах за цикл. Може синхронізуватися з темпом. + + + + + PHS controls the phase offset of the LFO. + PHS контролює зсув фази LFO (НЧГ). + + + + + PRE, or pre-delay, delays the start of the envelope from the start of the note. 0 means no delay. + PRE передзатримка, затримує старт обвідної від початку ноти. 0 означає без затримки. + + + + + ATT, or attack, controls how fast the envelope ramps up at start, measured in milliseconds. A value of 0 means instant. + ATT атака контролює як швидко обвідна нарощується на старті, вимірюється в мілісекундах. Значення 0 означає миттєво. + + + + + HOLD controls how long the envelope stays at peak after the attack phase. + HOLD (УТРИМУВАТИ) контролює як довго обвідна залишається на піку після фази атаки. + + + + + 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. + DEC (decay) згасання контролює як швидко обвідна спадає з пікового значення, вимірюється в мілісекундах, як довго буде йти з піку до нуля. Реальне загасання може бути коротшим, якщо використовується витримка. + + + + + 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. + SUS (sustain) витримка, контролює рівень обвідної. Загасання фази не піде нижче цього рівня поки нота утримується. + + + + + 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. + REL (release) відпускання контролює як довго нота відпускається, вимірюється в довготі падіння від піку до нуля. Реальне відпускання може бути коротшим, залежно від фази, в якій нота відпущена. + + + + + 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. + Регулятор нахилу контролює криву або форму обвідної. Значення 0 створює прямі підйоми і спади. Від'ємні величини створюють криві з уповільненим початком, швидким піком і знову уповільненим спадом. Позитивні значення створюють криві які починаються і закінчуються швидко, але довше залишаються на піках. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Modulation amount Глибина модуляції - - Fine tune left - - - - Fine tune right - - - - Mix osc 2 with osc 3 - - - - Modulate amplitude of osc 3 by osc 2 - - - - Modulate frequency of osc 3 by osc 2 - - - - Modulate phase of osc 3 by osc 2 - - MultitapEchoControlDialog + Length Довжина + Step length: Довжина кроку: + Dry Сухий + + Dry Gain: + Сухе підсилення: + + + Stages Етапи + + Lowpass stages: + НЧ етапи: + + + Swap inputs Обмін входами - Dry gain: - - - - Low-pass stages: - - - - Swap left and right input channels for reflections - + + Swap left and right input channel for reflections + Дзеркальний обмін лівим і правим каналами NesInstrument + + Channel 1 Coarse detune + Грубе підстроювання 1 каналу + + + + Channel 1 Volume + Гучність 1 каналу + + + + Channel 1 Envelope length + Довжина обвідної 1 каналу + + + + Channel 1 Duty cycle + Робочий цикл 1 каналу + + + + Channel 1 Sweep amount + Кількість розгортки 1 каналу + + + + Channel 1 Sweep rate + Швидкість розгортки 1 каналу + + + Channel 2 Coarse detune Грубе підстроювання 2 каналу + Channel 2 Volume Гучність 2 каналу + + Channel 2 Envelope length + Довжина обвідної 2 каналу + + + + Channel 2 Duty cycle + Робочий цикл 2 каналу + + + + Channel 2 Sweep amount + Кількість розгортки 2 каналу + + + + Channel 2 Sweep rate + Швидкість розгортки 2 каналу + + + + Channel 3 Coarse detune + Грубе підстроювання 3 каналу + + + + Channel 3 Volume + Гучність 3 каналу + + + + Channel 4 Volume + Гучність 4 каналу + + + + Channel 4 Envelope length + Довжина обвідної 4 каналу + + + + Channel 4 Noise frequency + Частота шуму 4 каналу + + + + Channel 4 Noise frequency sweep + Частота розгортки шуму 4 каналу + + + Master volume Основна гучність + Vibrato Вібрато - - Channel 1 coarse detune - - - - Channel 1 volume - Гучність першого каналу - - - Channel 1 envelope length - - - - Channel 1 duty cycle - - - - Channel 1 sweep amount - - - - Channel 1 sweep rate - - - - Channel 2 envelope length - - - - Channel 2 duty cycle - - - - Channel 2 sweep amount - - - - Channel 2 sweep rate - - - - Channel 3 coarse detune - - - - Channel 3 volume - Гучність третього каналу - - - Channel 4 volume - Гучність четвертого каналу - - - Channel 4 envelope length - - - - Channel 4 noise frequency - - - - Channel 4 noise frequency sweep - - NesInstrumentView + + + + Volume Гучність + + + Coarse detune Грубе підстроювання + + + Envelope length Довжина обвідної + Enable channel 1 Увімкнути канал 1 + Enable envelope 1 Увімкнути обвідну 1 + Enable envelope 1 loop Увімкнти повтор обвідної 1 + Enable sweep 1 Увімкнути розгортку 1 + + Sweep amount Кількість розгортки + + Sweep rate Темп розгортки + + 12.5% Duty cycle 12.5% Робочого циклу + + 25% Duty cycle 25% Робочого циклу + + 50% Duty cycle 50% Робочого циклу + + 75% Duty cycle 75% Робочого циклу + Enable channel 2 Увімкнути канал 2 + Enable envelope 2 Увімкнути обвідну 2 + Enable envelope 2 loop Увімкнти повтор обвідної 2 + Enable sweep 2 Увімкнути розгортку 2 + Enable channel 3 Увімкнути канал 3 + Noise Frequency Частота шуму + Frequency sweep Частота темпу + Enable channel 4 Увімкнути канал 4 + Enable envelope 4 Увімкнути обвідну 4 + Enable envelope 4 loop Увімкнти повтор обвідної 4 + Quantize noise frequency when using note frequency Квантування частоту шуму при використанні частоти ноти + Use note frequency for noise Використовувати частоту ноти для шуму + Noise mode Форма шуму + + Master Volume + Основна гучність + + + Vibrato Вібрато - - Master volume - Основна гучність - - - - OpulenzInstrument - - Patch - Патч - - - Op 1 attack - - - - Op 1 decay - - - - Op 1 sustain - - - - Op 1 release - - - - Op 1 level - - - - Op 1 level scaling - - - - Op 1 frequency multiplier - - - - Op 1 feedback - - - - 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 multiplier - - - - Op 2 key scaling rate - - - - Op 2 percussive envelope - - - - Op 2 tremolo - - - - Op 2 vibrato - - - - Op 2 waveform - - - - FM - FM - - - Vibrato depth - - - - Tremolo depth - - - - - OpulenzInstrumentView - - Attack - Вступ - - - Decay - Згасання - - - Release - Зменшення - - - Frequency multiplier - Множник частоти - OscillatorObject - Osc %1 volume - Гучність осциллятора %1 - - - Osc %1 panning - Стереобаланс для осциллятора %1 - - - Osc %1 coarse detuning - Підстроювання осциллятора %1 грубе - - - Osc %1 fine detuning left - Точне підстроювання лівого каналу осциллятора %1 - - - Osc %1 fine detuning right - Підстроювання правого каналу осциллятора %1 тонка - - - Osc %1 phase-offset - Зміщення фази осциллятора %1 - - - Osc %1 stereo phase-detuning - Підстроювання стерео-фази осциллятора %1 - - - Osc %1 wave shape - Гладкість сигналу осциллятора %1 - - - Modulation type %1 - Тип модуляції %1 - - + Osc %1 waveform Форма сигналу осциллятора %1 + Osc %1 harmonic Осц %1 гармонійний + + + + Osc %1 volume + Гучність осциллятора %1 + + + + + Osc %1 panning + Стереобаланс для осциллятора %1 + + + + + Osc %1 fine detuning left + Точне підстроювання лівого каналу осциллятора %1 + + + + Osc %1 coarse detuning + Підстроювання осциллятора %1 грубе + + + + Osc %1 fine detuning right + Підстроювання правого каналу осциллятора %1 тонка + + + + Osc %1 phase-offset + Зміщення фази осциллятора %1 + + + + Osc %1 stereo phase-detuning + Підстроювання стерео-фази осциллятора %1 + + + + Osc %1 wave shape + Гладкість сигналу осциллятора %1 + + + + Modulation type %1 + Тип модуляції %1 + PatchesDialog + Qsynth: Channel Preset Q-Синтезатор: Канал передустановлено + Bank selector Селектор банку + Bank Банк + Program selector Селектор програм + Patch Патч + Name І'мя + OK ОК + Cancel Скасувати @@ -2320,244 +6761,1728 @@ PatmanView + + Open other patch + Відкрити інший патч + + + + Click here to open another patch-file. Loop and Tune settings are not reset. + Натисніть щоб відкрити інший патч-файл. Циклічність і налаштування при цьому збережуться. + + + Loop Повтор + Loop mode Режим повтору + + Here you can toggle the Loop mode. If enabled, PatMan will use the loop information available in the file. + Тут вмикається/вимикається режим повтору, при увімкнені PatMan буде використовувати інформацію про повтор з файлу. + + + Tune Підлаштувати + Tune mode Тип підстроювання + + Here you can toggle the Tune mode. If enabled, PatMan will tune the sample to match the note's frequency. + Тут вмикається/вимикається режим підстроювання. Якщо його увімкнено, то PatMan змінить запис так, щоб він збігався по частоті з нотою. + + + No file selected Файл не вибрано + Open patch file Відкрити патч-файл + Patch-Files (*.pat) Патч-файли (*.pat) + + + PatternView - Open patch - + + use mouse wheel to set velocity of a step + використовуйте колесо миші для встановлення кроку гучності + + + + double-click to open in Piano Roll + Відкрити в редакторі нот подвійним клацанням миші + + + + Open in piano-roll + Відкрити в редакторі нот + + + + Clear all notes + Очистити всі ноти + + + + Reset name + Скинути назву + + + + Change name + Перейменувати + + + + Add steps + Додати такти + + + + Remove steps + Видалити такти + + + + Clone Steps + Клонувати такти + + + + 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. + Через помилку в старій версії LMMS контролери вершин не можуть правильно підключатися. Будь-ласка переконайтеся, що контролери вершин правильно приєднані і перезбережіть цей файл, вибачте, за заподіяні незручності. + + + + PeakControllerDialog + + + PEAK + ПІК + + + + LFO Controller + Контролер LFO PeakControllerEffectControlDialog + BASE БАЗА - Modulation amount: - Глибина модуляції: - - - Attack: - Вступ: - - - Release: - Зменшення: + + Base amount: + Базове значення: + AMNT ГЛИБ + + Modulation amount: + Глибина модуляції: + + + MULT МНОЖ + + Amount Multiplicator: + Величина множника: + + + ATCK ВСТУП + + Attack: + Вступ: + + + DCAY ЗГАС + + Release: + Зменшення: + + + + TRSH + TRSH + + + Treshold: Поріг: - - TRSH - - - - Base: - - - - Amount multiplicator: - - - - Mute output - Заглушити вивід - - - Absolute value - - PeakControllerEffectControls + Base value Опорне значення + Modulation amount Глибина модуляції - Mute output - Заглушити вивід - - + Attack Вступ + Release Зменшення + Treshold Поріг - Absolute value - + + Mute output + Заглушити вивід - Amount multiplicator - + + Abs Value + Абс Значення + + + + Amount Multiplicator + Величина множника + + + + 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% + Гучність %1% + + + + Panning: %1% left + Баланс %1% лівий + + + + Panning: %1% right + Баланс %1% правий + + + + Panning: center + Баланс: по середині + + + + Please open a pattern by double-clicking on it! + Відкрийте шаблон за допомогою подвійного клацання мишею! + + + + + Please enter a new value between %1 and %2: + Введіть нове значення від %1 до %2: + + + + PianoRollWindow + + + Play/pause current pattern (Space) + Гра/Пауза поточної мелодії (Пробіл) + + + + Record notes from MIDI-device/channel-piano + Записати ноти з цифрового музичного інструмента (MIDI) + + + + Record notes from MIDI-device/channel-piano while playing song or BB track + Записати ноти з цифрового музичного інструменту (MIDI) під час відтворення пісні або доріжки Ритм-Басу + + + + 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. + Натисніть цю кнопку, якщо ви хочете записати ноти з пристрою MIDI або віртуального синтезатора відповідного каналу. Пізніше ви зможете відредагувати записаний шаблон. + + + + 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. + Натисніть цю кнопку, якщо ви хочете записати ноти з пристрою MIDI або віртуального синтезатора відповідного каналу. Під час запису всі ноти записуються в цей шаблон, і ви будете чути композицію або РБ доріжку на задньому плані. + + + + Click here to stop playback of current pattern. + Натисніть тут, якщо ви хочете зупинити відтворення поточного шаблону. + + + + Edit actions + Зміна + + + + Draw mode (Shift+D) + Режим малювання (Shift + D) + + + + Erase mode (Shift+E) + Режим стирання (Shift+E) + + + + Select mode (Shift+S) + Режим вибору нот (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. + Режим малювання нот, в ньому ви можете додавати/переміщати і змінювати тривалість одиночних нот. Це режим за замовчуванням і використовується більшу частину часу. +Для включення цього режиму можна скористатися комбінацією клавіш Shift+D, утримуйте %1 для тимчасового перемикання в режим вибору. + + + + 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. + Режим стирання. У цьому режимі ви можете стирати ноти. Для увімкнення цього режиму можна скористатися комбінацією клавіш Shift+E. + + + + 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. + Режим виділення. У цьому режимі можна виділяти ноти, також можна утримувати %1 в режимі малювання, щоб на час увійти в режим виділення. + + + + Pitch Bend mode (Shift+T) + Режим Pitch Bend (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. + Натисніть тут для активації Pitch Blend режиму. Ви зможете клікнути на ноту, щоб почати автоматичний детюн. Можна використовувати це для "ковзання" від однієї ноти до іншої. Можна включити цей режим за допомогою Shift + T. + + + + Quantize + Квантовать + + + + Copy paste controls + Управління копіюванням та вставкою + + + + Cut selected notes (%1+X) + Перемістити виділені ноти до буферу (%1+X) + + + + Copy selected notes (%1+C) + Копіювати виділені ноти до буферу (%1+X) + + + + Paste notes from clipboard (%1+V) + Вставити ноти з буферу (%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. + "Q" позначає квантування і контролює розмір нотної сітки і контрольні точки тяжіння. З меншою величиною квантування, можна малювати короткі ноти в редаторі нот і більш точно контролювати точки в редакторі Автоматизації. + + + + 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 + Дозволяє вибрати довжину нової ноти. "Остання Нота" означає, що LMMS буде використовувати довжину ноти, зміненої в останній раз + + + + 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! + Функція безпосередньо пов'язана з контекстним меню на віртуальній клавіатурі зліва в нотному редакторі. Після того, як обраний масштаб у випадаючому меню, можна натиснути правою кнопкою у віртуальній клавіатурі і вибрати "Mark Current Scale" (Відзначити поточний масштаб). LMMS підсвітить всі ноти які лежать в обраному масштабі для обраної клавіші! + + + + 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. + Дозволяє вибрати акорд, який LMMS потім зможе намалювати або підсвітити. У цьому меню можна знайти найбільш популярні акорди. Після того, як ви вибрали акорд, натисніть в будь-якому місці, щоб поставити його, а правим кліком по віртуальній клавіатурі відкривається контекстне меню і підсвічування акорду. Для повернення в режим однієї ноти потрібно вибрати "Без акорду" в цьому випадаючому меню. + + + + + Piano-Roll - %1 + Нотний редактор - %1 + + + + + Piano-Roll - no pattern + Нотний редактор - без шаблону + + + + PianoView + + + Base note + Опорна нота + + + + Plugin + + + Plugin not found + Модуль не знайдено + + + + The plugin "%1" wasn't found or could not be loaded! +Reason: "%2" + Модуль «%1» відсутній чи не може бути завантажений! +Причина: «%2» + + + + Error while loading plugin + Помилка завантаження модуля + + + + Failed to load plugin "%1"! + Не вдалося завантажити модуль «%1»! + + + + PluginBrowser + + + Instrument Plugins + Модулі інструментів + + + + Instrument browser + Огляд інструментів + + + + Drag an instrument into either the Song-Editor, the Beat+Bassline Editor or into an existing instrument track. + Ви можете переносити потрібні вам інструменти з цієї панелі в музичний, ритм-бас редактор або в існуючу доріжку інструменту. + + + + PluginFactory + + + Plugin not found. + Модуль не знайдено. + + + + LMMS plugin %1 does not have a plugin descriptor named %2! + LMMS плагін %1 не має опису плагіна з ім'ям %2! + + + + ProjectNotes + + + Project Notes + Примітки проекту + + + + Enter project notes here + Напишіть примітки до проекту тут + + + + Edit Actions + Зміна + + + + &Undo + &U Скасувати + + + + %1+Z + %1+Z + + + + &Redo + &R Повторити + + + + %1+Y + %1+Y + + + + &Copy + &C Копіювати + + + + %1+C + %1+C + + + + Cu&t + &t Вирізати + + + + %1+X + %1+X + + + + &Paste + &P Вставити + + + + %1+V + %1+V + + + + Format Actions + Форматування + + + + &Bold + Напів&жирний + + + + %1+B + %1+B + + + + &Italic + &Курсив + + + + %1+I + %1+I + + + + &Underline + &Підкреслити + + + + %1+U + %1+U + + + + &Left + По &лівому краю + + + + %1+L + %1+L + + + + C&enter + По &центрі + + + + %1+E + %1+E + + + + &Right + По &правому краю + + + + %1+R + %1+R + + + + &Justify + По &ширині + + + + %1+J + %1+J + + + + &Color... + &C Колір... + + + + ProjectRenderer + + + WAV-File (*.wav) + Файл WAV (*.wav) + + + + Compressed OGG-File (*.ogg) + Стиснутий файл OGG (*.ogg) + + + FLAC-File (*.flac) + + + + + Compressed MP3-File (*.mp3) + Стиснутий MP3-файл (* .mp3) QWidget + + + Name: І'мя: + + Maker: Розробник: + + Copyright: Авторське право: + + Requires Real Time: Потрібна обробка в реальному часі: + + + + + + Yes Так + + + + + + No Ні + + Real Time Capable: Робота в реальному часі: + + In Place Broken: Замість зламаного: + + Channels In: Канали в: + + Channels Out: Канали з: + + File: %1 + Файл: %1 + + + File: Файл: + + + RenameDialog - File: %1 - Файл: %1 + + Rename... + Перейменувати ... ReverbSCControlDialog + Input Ввід + + Input Gain: + Вхідне підсилення: + + + Size - + Розмір + Size: - + Розмір: + Color - + Колір + Color: - + Колір: + Output Вивід - Input gain: - Вхідне підсилення: - - - Output gain: - Вихідне підсилення: + + Output Gain: + Вихідне підсилення: ReverbSCControls + + Input Gain + Вхідне підсилення + + + Size - + Розмір + Color - + Колір - Input gain - Вхідне підсилення + + Output Gain + Вихідне підсилення + + + + SampleBuffer + + + Fail to open file + Не вдається відкрити файл - Output gain - Вихідне підсилення + + Audio files are limited to %1 MB in size and %2 minutes of playing time + Аудіофайли обмежено розміром в %1 МБ і %2 хвилин(и) програвання + + + + Open audio file + Відкрити звуковий файл + + + + All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + Всі Аудіо-файли (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + + + + Wave-Files (*.wav) + Файли Wave (*.wav) + + + + OGG-Files (*.ogg) + Файли OGG (*.ogg) + + + + DrumSynth-Files (*.ds) + Файли DrumSynth (*.ds) + + + + FLAC-Files (*.flac) + Файли FLAC (*.flac) + + + + SPEEX-Files (*.spx) + Файли SPEEX (*.spx) + + + + VOC-Files (*.voc) + Файли VOC (*.voc) + + + + AIFF-Files (*.aif *.aiff) + Файли AIFF (*.aif *.aiff) + + + + AU-Files (*.au) + Файли AU (*.au) + + + + RAW-Files (*.raw) + Файли RAW (*.raw) + + + + SampleTCOView + + + double-click to select sample + Виберіть запис подвійним натисненням миші + + + + Delete (middle mousebutton) + Видалити (середня кнопка мишки) + + + + Cut + Вирізати + + + + Copy + Копіювати + + + + Paste + Вставити + + + + Mute/unmute (<%1> + middle click) + Заглушити/включити (<%1> + середня кнопка миші) + + + + SampleTrack + + + Volume + Гучність + + + + Panning + Баланс + + + + + Sample track + Доріжка запису + + + + SampleTrackView + + + Track volume + Гучність доріжки + + + + Channel volume: + Гучність каналу: + + + + VOL + ГУЧН + + + + Panning + Баланс + + + + Panning: + Баланс: + + + + PAN + БАЛ + + + + SetupDialog + + + Setup LMMS + Налаштування 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 + Синхронізувати VST плагіни з хостом відтворення + + + + 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 + Використовувати вбудований обробник NaN + + + + PLUGIN EMBEDDING + ВСТАНОВИТИ УПРАВЛІННЯ + + + + No embedding + Не встановлено + + + + Embed using Qt API + Встановлення використовуючи Qt API + + + + Embed using native Win32 API + Встановлення використовуючи рідний Win32 API + + + + Embed using XEmbed protocol + Встановлення використовуючи протокол XEmbed + + + + LANGUAGE + МОВА + + + + + Paths + Шляхи + + + + Directories + Каталоги + + + + LMMS working directory + Робочий каталог LMMS + + + + Themes directory + Каталог тем + + + + Background artwork + Фонове зображення + + + + VST-plugin directory + Каталог модулів VST + + + + GIG directory + Каталог GIG + + + + SF2 directory + Каталог SF2 + + + + LADSPA plugin directories + Каталог модулів LADSPA + + + + STK rawwave directory + Каталог STK rawwave + + + + Default Soundfont File + Основний Soundfont файл + + + + + 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 + + + + MIDI INTERFACE + ІНТЕРФЕЙС MIDI + + + + OK + ОК + + + + Cancel + Скасувати + + + + Restart LMMS + Перезапустіть LMMS + + + + Please note that most changes won't take effect until you restart LMMS! + Врахуйте, що більшість налаштувань не вступлять в силу до перезапуску програми! + + + + Frames: %1 +Latency: %2 ms + Фрагментів: %1 +Затримка: %2 мс + + + + 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. + Тут ви можете налаштувати розмір внутрішнього звукового буфера LMMS. Менші значення дають менший час відгуку програми, але підвищують споживання ресурсів - це особливо помітно на старих машинах і системах, ядро ​​яких не підтримує пріоритету реального часу. Якщо спостерігається переривчастий звук, спробуйте збільшити розмір буферу. + + + + Choose LMMS working directory + Вибір робочого каталогу LMMS + + + + Choose your GIG directory + Виберіть каталог GIG + + + + Choose your SF2 directory + Виберіть каталог SF2 + + + + Choose your VST-plugin directory + Вибір свого каталогу для модулів VST + + + + Choose artwork-theme directory + Вибір каталогу з темою оформлення для LMMS + + + + Choose LADSPA plugin directory + Вибір каталогу з модулями LADSPA + + + + Choose STK rawwave directory + Вибір каталогу STK rawwave + + + + Choose default SoundFont + Вибрати головний SoundFont + + + + Choose background artwork + Вибрати фонове зображення + + + + minutes + хвилин + + + + minute + хвилина + + + + Disabled + Вимкнено + + + + Auto-save interval: %1 + Інтервал автоматичного збереження: %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. + Встановіть проміжок часу автоматичного резервного копіювання в %1. +Не забудьте також зберегти проект вручну. Ви можете вимкнути автозбереження, інколи деяким старим системи тяжко в таком режимі. + + + + 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. + Будь ласка, виберіть звукову систему. Залежно від конфігурації під час компілювання програми, ви можете використовувати ALSA, JACK, OSS та інші. У нижній частині вікна налаштування можна задати специфічні параметри обраної системи. + + + + 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. + Будь ласка, виберіть інтерфейс MIDI. Залежно від конфігурації під час компілювання програми, ви можете використовувати ALSA, OSS та інші. У нижній частині вікна налаштування можна задати специфічні параметри обраного інтерфейсу. + + + + Song + + + Tempo + Темп + + + + Master volume + Основна гучність + + + + Master pitch + Основна тональність + + + + LMMS Error report + Повідомлення про помилку в LMMS + + + + Project saved + Проект збережено + + + + The project %1 is now saved. + Проект %1 збережено. + + + + Project NOT saved. + Проект НЕ ЗБЕРЕЖЕНО. + + + + The project %1 was not saved! + Проект %1 не збережено! + + + + Import file + Імпорт файлу + + + + MIDI sequences + MiDi послідовність + + + + Hydrogen projects + Hydrogen проекти + + + + 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) + MIDI-файл (* mid) + + + + The following errors occured while loading: + Наступні помилки виникли при завантаженні: + + + + 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. + Неможливо відкрити файл %1, ймовірно, немає дозволу на його читання. +Будь-ласка переконайтеся, що є принаймні права на читання цього файлу і спробуйте ще раз. + + + + 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. + Неможливо відкрити %1 для запису, можливо, немає дозволу на запис в цей файл, будь-ласка упевніться, що є доступ до цього файлу і спробуйте знову. + + + + Error in file + Помилка у файлі + + + + The file %1 seems to contain errors and therefore can't be loaded. + Файл %1 можливо містить помилки через які не може завантажитися. + + + + Version difference + Різниця версій + + + + This %1 was created with LMMS %2. + Цей %1 було створено в LMMS версії %2 + + + + template + шаблон + + + + project + проект + + + + Tempo + Темп + + + + TEMPO/BPM + ТЕМП/BPM + + + + tempo of song + Темп музики + + + + 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). + Це значення задає темп музики в ударах в хвилину (англ. аббр. BPM). На кожен такт приходить чотири удари, так що темп в ударах в хвилину фактично вказує, скільки чвертей такту програється за хвилину (або, що те ж, кількість тактів, що програються за чотири хвилини). + + + + High quality mode + Висока якість + + + + + Master volume + Основна гучність + + + + master volume + основна гучність + + + + + Master pitch + Основна тональність + + + + master pitch + основна тональність + + + + Value: %1% + Значення: %1% + + + + Value: %1 semitones + Значення: %1 півтон(у/ів) + + + + SongEditorWindow + + + Song-Editor + Музичний редактор + + + + Play song (Space) + Почати відтворення (Пробіл) + + + + Record samples from Audio-device + Записати семпл зі звукового пристрою + + + + Record samples from Audio-device while playing song or BB track + Записати семпл з аудіо-пристрої під час відтворення в музичному чи ритм/бас редакторі + + + + Stop song (Space) + Зупинити відтворення (Пробіл) + + + + 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. + Натисніть, щоб прослухати створену мелодію. Відтворення почнеться з позиції курсора (зелений трикутник); ви можете рухати його під час програвання. + + + + 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 + Стежити + + + + Add beat/bassline + Додати ритм/бас + + + + Add sample-track + Додати доріжку запису + + + + Add automation-track + Додати доріжку автоматизації + + + + Edit actions + Зміна + + + + Draw mode + Режим малювання + + + + Edit mode (select and move) + Правка (виділення/переміщення) + + + + Timeline controls + Управління хронологією + + + + Zoom controls + Управління масштабом SpectrumAnalyzerControlDialog + Linear spectrum Лінійний спектр + Linear Y axis Лінійна вісь ординат @@ -2565,412 +8490,1042 @@ SpectrumAnalyzerControls + Linear spectrum Лінійний спектр + Linear Y axis Лінійна вісь ординат + Channel mode Режим каналу + + SubWindow + + + Close + Закрити + + + + Maximize + Розгорнути + + + + Restore + Відновити + + + + TabWidget + + + + Settings for %1 + Налаштування для %1 + + + + TempoSyncKnob + + + + Tempo Sync + Синхронізація темпу + + + + No Sync + Синхронізації немає + + + + Eight beats + Вісім ударів (дві ноти) + + + + Whole note + Ціла нота + + + + Half note + Півнота + + + + Quarter note + Чверть ноти + + + + 8th note + Восьма ноти + + + + 16th note + 1/16 ноти + + + + 32nd note + 1/32 ноти + + + + Custom... + Своя... + + + + Custom + Своя + + + + Synced to Eight Beats + Синхро по 8 ударам + + + + Synced to Whole Note + Синхро по цілій ноті + + + + Synced to Half Note + Синхро по половині ноти + + + + Synced to Quarter Note + Синхро по чверті ноти + + + + Synced to 8th Note + Синхро по 1/8 ноти + + + + Synced to 16th Note + Синхро по 1/16 ноти + + + + Synced to 32nd Note + Синхро по 1/32 ноти + + + + TimeDisplayWidget + + + click to change time units + натисніть для зміни одиниць часу + + + + MIN + ХВ + + + + SEC + С + + + + MSEC + МС + + + + BAR + БАР + + + + BEAT + БІТ + + + + TICK + ТІК + + + + TimeLineWidget + + + Enable/disable auto-scrolling + Увімк/вимк автопрокрутку + + + + Enable/disable loop-points + Увімк/вимк точки петлі + + + + After stopping go back to begin + Після зупинки переходити до початку + + + + After stopping go back to position at which playing was started + Після зупинки переходити до місця, з якого почалося відтворення + + + + After stopping keep position + Залишатися на місці зупинки + + + + + Hint + Підказка + + + + Press <%1> to disable magnetic loop points. + Натисніть <%1>, щоб прибрати прилипання точок циклу. + + + + Hold <Shift> to move the begin loop point; Press <%1> to disable magnetic loop points. + Зажміть <Shift> щоб змістити початок точок циклу; Натисніть <%1>, щоб прибрати прилипання точок циклу. + + + + Track + + + Mute + Тиша + + + + Solo + Соло + + TrackContainer + + Couldn't import file + Не можу імпортувати файл + + + + Couldn't find a filter for importing file %1. +You should convert this file into a format supported by LMMS using another software. + Не можу знайти фільтр для імпорту файла %1. +Для підключення цього файлу перетворіть його в формат, підтримуваний LMMS. + + + + Couldn't open file + Не можу відкрити файл + + + + 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! + Не можу відкрити файл %1 для запису. +Перевірте, чи володієте ви правами на запис в обраний файл і каталог що його містить і спробуйте знову! + + + + Loading project... + Завантаження проекту ... + + + + Cancel Скасувати + + Please wait... Зачекайте будь-ласка ... + + Loading cancelled + Завантаження скасовано + + + + Project loading was cancelled. + Завантаження проекту скасовано. + + + + Loading Track %1 (%2/Total %3) + Завантаження треку %1 (%2/з %3) + + + Importing MIDI-file... Імпортую файл MIDI... + + TrackContentObject + + + Mute + Тиша + + + + TrackContentObjectView + + + Current position + Позиція + + + + + Hint + Підказка + + + + Press <%1> and drag to make a copy. + Натисніть <%1> і перетягніть, щоб створити копію. + + + + Current length + Тривалість + + + + Press <%1> for free resizing. + Для вільної зміни розміру натисніть <%1>. + + + + + %1:%2 (%3:%4 to %5:%6) + %1:%2 (від %3:%4 до %5:%6) + + + + Delete (middle mousebutton) + Видалити (середня кнопка мишки) + + + + Cut + Вирізати + + + + Copy + Копіювати + + + + Paste + Вставити + + + + Mute/unmute (<%1> + middle click) + Заглушити/включити (<%1> + середня кнопка миші) + + + + TrackOperationsWidget + + + Press <%1> while clicking on move-grip to begin a new drag'n'drop-action. + Затисніть <%1> і натискайте мишку під час руху, щоб почати нову перезбірку. + + + + Actions for this track + Дії для цієї доріжки + + + + Mute + Тиша + + + + + Solo + Соло + + + + Mute this track + Відключити доріжку + + + + Clone this track + Клонувати доріжку + + + + Remove this track + Видалити доріжку + + + + Clear this track + Очистити цю доріжку + + + + FX %1: %2 + ЕФ %1: %2 + + + + Assign to new FX Channel + Призначити до нового каналу ефекту + + + + Turn all recording on + Включити все на запис + + + + Turn all recording off + Вимкнути всі записи + + TripleOscillatorView + + Use phase modulation for modulating oscillator 1 with oscillator 2 + Модулювати фазу осциллятора 2 сигналом з 1 + + + + Use amplitude modulation for modulating oscillator 1 with oscillator 2 + Модулювати амплітуду осциллятора 2 сигналом з 1 + + + + Mix output of oscillator 1 & 2 + Змішати виходи 1 і 2 осцилляторів + + + Synchronize oscillator 1 with oscillator 2 Синхронізувати 1 осциллятор по 2 + + Use frequency modulation for modulating oscillator 1 with oscillator 2 + Модулювати частоту осциллятора 2 сигналом з 1 + + + + Use phase modulation for modulating oscillator 2 with oscillator 3 + Модулювати фазу осциллятора 3 сигналом з 2 + + + + Use amplitude modulation for modulating oscillator 2 with oscillator 3 + Модулювати амплітуду осциллятора 3 сигналом з 2 + + + + Mix output of oscillator 2 & 3 + Поєднати виходи осцилляторів 2 і 3 + + + Synchronize oscillator 2 with oscillator 3 Синхронізувати осциллятор 2 і 3 + + Use frequency modulation for modulating oscillator 2 with oscillator 3 + Модулювати частоту осциллятора 3 сигналом з 2 + + + Osc %1 volume: Гучність осциллятора %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. + Ця ручка встановлює гучність осциллятора %1. Якщо 0, то осциллятор вимикається, інакше буде чутно настільки голосно, настільки тут встановлено. + + + Osc %1 panning: Баланс для осциллятора %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. + Регулятор стереобалансу осциллятора %1. Величина -100 позначає, що 100% сигналу йде в лівий канал, а 100 - в правий. + + + Osc %1 coarse detuning: Грубе підстроювання осциллятора %1: + semitones півтон(а,ів) + + 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. + Ця ручка встановлює грубе підстроювання осцилятора %1. Ви можете пістроїти осцилятор на 24 півтони (2 октави) вгору і вниз. Це корисно для створення звуків з акорду. + + + Osc %1 fine detuning left: Точне підстроювання лівого каналу осциллятора %1: + + cents Відсотки + + 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. + Ця ручка встановлює точне підстроювання для лівого каналу осциллятора %1. Підстроювання задається в діапазоні від -100 сотих до +100 сотих. Це корисно для створення "насичених" звуків. + + + Osc %1 fine detuning right: Точна підстройка правого канала осциллятора %1: + + 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. + Ця ручка встановлює точне підстроювання для правого каналу осциллятора %1. Підстроювання задається в діапазоні від -100 сотих до +100 сотих. Це корисно для створення "насичених" звуків. + + + Osc %1 phase-offset: Зміщення фази осциллятора %1: + + degrees градуси + + 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. + Ця ручка встановлює початкову фазу осциллятора %1, т. б. точку, з якої осциллятор починає виробляти сигнал. Наприклад, якщо ви задали синусоїдальну форму сигналу і початкову фазу 180º, хвиля спочатку піде вниз, а не вгору. Те ж саме для сигналу прямокутної форми. + + + Osc %1 stereo phase-detuning: Підстроювання стерео фази осциллятора %1: - Modulate phase of oscillator 1 by oscillator 2 - + + 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. + Ця ручка встановлює фазове підстроювання осциллятора %1 між каналами, тобто різницю фаз між лівим і правим каналами. Це зручно для створення розширення стереоефектів. - Modulate amplitude of oscillator 1 by oscillator 2 - + + Use a sine-wave for current oscillator. + Генерувати гармонійний (синусоїдальний) сигнал. - Mix output of oscillators 1 & 2 - + + Use a triangle-wave for current oscillator. + Генерувати трикутний сигнал. - Modulate frequency of oscillator 1 by oscillator 2 - + + Use a saw-wave for current oscillator. + Генерувати зигзагоподібний сигнал. - Modulate phase of oscillator 2 by oscillator 3 - + + Use a square-wave for current oscillator. + Генерувати квадрат. - Modulate amplitude of oscillator 2 by oscillator 3 - + + Use a moog-like saw-wave for current oscillator. + Використовувати муг-зигзаг для цього осциллятора. - Mix output of oscillators 2 & 3 - + + Use an exponential wave for current oscillator. + Використовувати експонентний сигнал для цього осциллятора. - Modulate frequency of oscillator 2 by oscillator 3 - + + Use white-noise for current oscillator. + Генерувати білий шум. - Sine wave - Синусоїда + + Use a user-defined waveform for current oscillator. + Задати форму сигналу. + + + + VersionedSaveDialog + + + Increment version number + Збільшуючийся номер версії - Triangle wave - + + Decrement version number + Зменшуючийся номер версії - Saw wave - Зигзаг - - - Square wave - - - - Moog-like saw wave - - - - Exponential wave - Експоненціальна хвиля - - - White noise - Білий шум - - - User-defined wave - + + already exists. Do you want to replace it? + вже існує. Замінити його? VestigeInstrumentView - Show/hide GUI - Показати / приховати інтерфейс + + Open other VST-plugin + Відкрити інший VST плагін - Turn off all notes - Вимкнути всі ноти + + 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. + Відкрити інший модуль VST. Після натискання на кнопку з'явиться стандартний діалог вибору файлу, де ви зможете вибрати потрібний модуль. - DLL-files (*.dll) - Бібліотеки DLL (*.dll) + + Control VST-plugin from LMMS host + Управління VST плагіном через LMMS хост - EXE-files (*.exe) - Програми EXE (*.exe) + + Click here, if you want to control VST-plugin from host. + Натисніть тут, для контролю VST плагіном через хост. + + Open VST-plugin preset + Відкрити передустановку VST плагіна + + + + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. + Відкрити іншу .fxp . fxb передустановку VST. + + + Previous (-) Попередній <-> + + + Click here, if you want to switch to another VST-plugin preset program. + Перемикання на іншу передустановку програми VST плагіна. + + + Save preset Зберегти передустановку + + Click here, if you want to save current VST-plugin preset program. + Зберегти поточну передустановку програми VST плагіна. + + + Next (+) Наступний <+> + + Click here to select presets that are currently loaded in VST. + Вибір із уже завантажених в VST предустановок. + + + + Show/hide GUI + Показати / приховати інтерфейс + + + + Click here to show or hide the graphical user interface (GUI) of your VST-plugin. + Приховує / показує графічний користувальницький інтерфейс (GUI) обраного модуля VST. + + + + Turn off all notes + Вимкнути всі ноти + + + + Open VST-plugin + Відкрити модуль VST + + + + DLL-files (*.dll) + Бібліотеки DLL (*.dll) + + + + EXE-files (*.exe) + Програми EXE (*.exe) + + + + No VST-plugin loaded + Модуль VST не завантажений + + + Preset Передустановка + by від + - VST plugin control - Управління VST плагіном + + + VisualizationWidget - Open VST plugin - + + click to enable/disable visualization of master-output + Натисніть, щоб увімкнути/вимкнути візуалізацію головного виводу - Control VST plugin from LMMS host - - - - Open VST plugin preset - - - - No VST plugin loaded - + + Click to enable + Натисніть для включення VstEffectControlDialog + Show/hide Показати/Сховати + + Control VST-plugin from LMMS host + Управління VST плагіном через LMMS хост + + + + Click here, if you want to control VST-plugin from host. + Натисніть тут, для контролю VST плагіном через хост. + + + + Open VST-plugin preset + Відкрити передустановку VST плагіна + + + + Click here, if you want to open another *.fxp, *.fxb VST-plugin preset. + Відкрити іншу .fxp . fxb передустановку VST. + + + Previous (-) Попередній <-> + + + Click here, if you want to switch to another VST-plugin preset program. + Перемикання на іншу передустановку програми VST плагіна. + + + Next (+) Наступний <+> + + Click here to select presets that are currently loaded in VST. + Вибір із уже завантажених в VST предустановок. + + + Save preset Зберегти налаштування + + Click here, if you want to save current VST-plugin preset program. + Зберегти поточну передустановку програми VST плагіна. + + + + Effect by: Ефекти по: + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> - - Control VST plugin from LMMS host - - - - Open VST plugin preset - - VstPlugin - Loading plugin - Завантаження модуля + + + The VST plugin %1 could not be loaded. + VST плагін %1 не може бути завантажено. + Open Preset Відкрити предустановку + + Vst Plugin Preset (*.fxp *.fxb) - Передустановка VST плагіна (*.fxp *.fxb) + Передустановка VST плагіна (*.fxp, *.fxb) + : default : основні + " " + ' ' + Save Preset Зберегти предустановку + .fxp .fxp + .FXP .FXP + .FXB .FXB + .fxb .fxb - Please wait while loading VST plugin... - Будь ласка, зачекайте доки завантажується VST плагін ... + + Loading plugin + Завантаження модуля - The VST plugin %1 could not be loaded. - VST плагін %1 не може бути завантажено. + + Please wait while loading VST plugin... + Будь ласка, зачекайте доки завантажується VST плагін ... WatsynInstrument + Volume A1 Гучність A1 + Volume A2 Гучність A2 + Volume B1 Гучність B1 + Volume B2 Гучність B2 + Panning A1 Баланс A1 + Panning A2 Баланс A2 + Panning B1 Баланс B1 + Panning B2 Баланс B2 + Freq. multiplier A1 Множник частоти A1 + Freq. multiplier A2 Множник частоти A2 + Freq. multiplier B1 Множник частоти B1 + Freq. multiplier B2 Множник частоти B2 + Left detune A1 Ліве підстроювання A1 + Left detune A2 Ліве підстроювання A2 + Left detune B1 Ліве підстроювання B1 + Left detune B2 Ліве підстроювання B2 + Right detune A1 Праве підстроювання A1 + Right detune A2 Праве підстроювання A2 + Right detune B1 Праве підстроювання B1 + Right detune B2 Праве підстроювання B2 + A-B Mix A-B Мікс + A-B Mix envelope amount A-B Мікс кіл. обвідної + A-B Mix envelope attack A-B Мікс атаки обвідної + A-B Mix envelope hold A-B Мікс утримання обвідної + A-B Mix envelope decay A-B Мікс згасання обвідної + A1-B2 Crosstalk Перехресні перешкоди A1-B2 + A2-A1 modulation Модуляція A2-A1 + B2-B1 modulation Модуляція B2-B1 + Selected graph Обраний графік @@ -2978,449 +9533,442 @@ WatsynView - Select oscillator A1 - Виберіть генератор A1 - - - Select oscillator A2 - Виберіть генератор A2 - - - Select oscillator B1 - Виберіть генератор B1 - - - Select oscillator B2 - Виберіть генератор B2 - - - Mix output of A2 to A1 - Змішати виходи A2 до A1 - - - Mix output of B2 to B1 - Змішати виходи В2 до В1 - - - Draw your own waveform here by dragging your mouse on this graph. - Тут ви можете малювати власний сигнал. - - - Load waveform - Завантаження форми звуку - - - Phase left - Фаза зліва - - - Phase right - Фаза праворуч - - - Normalize - Нормалізувати - - - Invert - Інвертувати - - - Smooth - Згладити - - - Sine wave - Синусоїда - - - Triangle wave - Трикутна хвиля - - - Square wave - Квадратна хвиля - - + + + + Volume Гучність + + + + Panning Баланс + + + + Freq. multiplier Множник частоти + + + + Left detune Ліве підстроювання + + + + + + + + cents відсотків + + + + Right detune Праве підстроювання + A-B Mix A-B Мікс + Mix envelope amount Мікс кількості обвідної + Mix envelope attack A-B Мікс вступу обвідної + Mix envelope hold A-B Мікс утримання обвідної + Mix envelope decay A-B Мікс згасання обвідної + Crosstalk Перехід - Modulate amplitude of A1 by output of A2 - + + Select oscillator A1 + Виберіть генератор A1 - Ring modulate A1 and A2 - + + Select oscillator A2 + Виберіть генератор A2 - Modulate phase of A1 by output of A2 - + + Select oscillator B1 + Виберіть генератор B1 - Modulate amplitude of B1 by output of B2 - + + Select oscillator B2 + Виберіть генератор B2 - Ring modulate B1 and B2 - + + Mix output of A2 to A1 + Змішати виходи A2 до A1 - Modulate phase of B1 by output of B2 - + + Modulate amplitude of A1 with output of A2 + Модулювати амплітуду А1 виходом з А2 - Load a waveform from a sample file - + + Ring-modulate A1 and A2 + Кільцева модуляція А1 і А2 - Shift phase by -15 degrees - + + Modulate phase of A1 with output of A2 + Модулювати фазу А1 виходом з А2 - Shift phase by +15 degrees - + + Mix output of B2 to B1 + Змішати виходи В2 до В1 - Saw wave - Зигзаг - - - - Xpressive - - Selected graph - Обраний графік + + Modulate amplitude of B1 with output of B2 + Модулювати амплітуду В1 виходом з В2 - A1 - + + Ring-modulate B1 and B2 + Кільцева модуляція В1 і В2 - A2 - + + Modulate phase of B1 with output of B2 + Модулювати фазу В1 виходом з В2 - A3 - - - - W1 smoothing - - - - W2 smoothing - - - - W3 smoothing - - - - Panning 1 - - - - Panning 2 - - - - Rel trans - - - - - XpressiveView - + + + + Draw your own waveform here by dragging your mouse on this graph. - Тут ви можете малювати власний сигнал. + Тут ви можете малювати власний сигнал. - Select oscillator W1 - + + Load waveform + Завантаження форми звуку - Select oscillator W2 - + + Click to load a waveform from a sample file + Натисніть для завантаження форми звуку з файлу із зразком - Select oscillator W3 - + + Phase left + Фаза зліва - Select output O1 - + + Click to shift phase by -15 degrees + Натисніть, щоб змістити фазу на -15 градусів - Select output O2 - + + Phase right + Фаза праворуч - Open help window - + + Click to shift phase by +15 degrees + Натисніть, щоб змістити фазу на +15 градусів + + Normalize + Нормалізувати + + + + Click to normalize + Натисніть для нормалізації + + + + Invert + Інвертувати + + + + Click to invert + Натисніть щоб інвертувати + + + + Smooth + Згладити + + + + Click to smooth + Натисніть щоб згладити + + + Sine wave - Синусоїда + Синусоїда - Moog-saw wave - - - - Exponential wave - Експоненціальна хвиля - - - Saw wave - Зигзаг - - - User-defined wave - + + Click for sine wave + Згенерувати гармонійний (синусоїдальний) сигнал + + Triangle wave - + Трикутна хвиля + + Click for triangle wave + Згенерувати трикутний сигнал + + + + Click for saw wave + Згенерувати зигзагоподібний сигнал + + + Square wave - + Квадратна хвиля - White noise - Білий шум - - - WaveInterpolate - - - - ExpressionValid - - - - General purpose 1: - - - - General purpose 2: - - - - General purpose 3: - - - - O1 panning: - - - - O2 panning: - - - - Release transition: - - - - Smoothness - + + Click for square wave + Згенерувати квадратний сигнал ZynAddSubFxInstrument + Portamento Портаменто + + Filter Frequency + Фільтр Частот + + + + Filter Resonance + Фільтр резонансу + + + Bandwidth Ширина смуги - Filter frequency - + + FM Gain + Підсил FM - Filter resonance - + + Resonance Center Frequency + Частоти центру резонансу - FM gain - + + Resonance Bandwidth + Ширина смуги резонансу - Resonance center frequency - - - - Resonance bandwidth - - - - Forward MIDI control change events - + + Forward MIDI Control Change Events + Переслати зміну подій MIDI управління ZynAddSubFxView - Show GUI - Показати інтерфейс - - + Portamento: Портаменто: + PORT PORT + + Filter Frequency: + Фільтр частот: + + + FREQ FREQ + + Filter Resonance: + Фільтр резонансу: + + + RES RES + Bandwidth: Смуга пропускання: + BW BW + + FM Gain: + Підсилення частоти модуляції (FM): + + + FM GAIN FM GAIN + Resonance center frequency: Частота центру резонансу: + RES CF RES CF + Resonance bandwidth: Ширина смуги резонансу: + RES BW RES BW - Filter frequency: - + + Forward MIDI Control Changes + Переслати зміну подій MiDi управління - Filter resonance: - + + Show GUI + Показати інтерфейс - FM gain: - - - - Forward MIDI control changes - + + Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. + Натисніть сюди щоб сховати чи показати графічний інтерфейс ZynAddSubFX. audioFileProcessor + Amplify Підсилення + Start of sample Початок запису + End of sample Кінець запису - Reverse sample - Перевернути запис - - - Stutter - Заїкання - - + Loopback point Точка повернення з повтору + + Reverse sample + Перевернути запис + + + Loop mode Режим повтору + + Stutter + Заїкання + + + Interpolation mode Режим Інтерполяції + None Нічого + Linear Лінійний + Sinc Синхронізований + Sample not found: %1 Запис не знайдено: %1 @@ -3428,470 +9976,270 @@ bitInvader - Sample length - + + Samplelength + Тривалість bitInvaderView - Sine wave - Синусоїда - - - Triangle wave - Трикутник - - - Saw wave - Зигзаг - - - Square wave - Квадрат - - - Interpolation - Інтерполяція - - - Normalize - Нормалізувати + + Sample Length + Тривалість запису + Draw your own waveform here by dragging your mouse on this graph. Тут ви можете малювати власний сигнал. - Sample length - + + Sine wave + Синусоїда - White noise - Білий шум + + Click for a sine-wave. + Генерувати гармонійний (синусоїдальний) сигнал. - User-defined wave - + + Triangle wave + Трикутник - Smooth waveform - Згладжений сигнал + + Click here for a triangle-wave. + Згенерувати трикутний сигнал. + + + + Saw wave + Зигзаг + + + + Click here for a saw-wave. + Згенерувати зигзаг. + + + + Square wave + Квадрат + + + + Click here for a square-wave. + Згенерувати квадратний сигнал. + + + + White noise wave + Білий шум + + + + Click here for white-noise. + Згенерувати білий шум. + + + + User defined wave + Користувацька + + + + Click here for a user-defined shape. + Задати форму сигналу вручну. + + + + Smooth + Згладити + + + + Click here to smooth waveform. + Клацніть щоб згладити форму сигналу. + + + + Interpolation + Інтерполяція + + + + Normalize + Нормалізувати dynProcControlDialog + INPUT ВХІД + Input gain: Вхідне підсилення: + OUTPUT ВИХІД + Output gain: Вихідне підсилення: + ATTACK ВСТУП + Peak attack time: Час пікової атаки: + RELEASE ЗМЕНШЕННЯ + Peak release time: Час відпуску піку: + + Reset waveform + Скидання сигналу + + + + Click here to reset the wavegraph back to default + Натисніть тут, щоб скинути граф хвилі назад за замовчуванням + + + + Smooth waveform + Згладжений сигнал + + + + Click here to apply smoothing to wavegraph + Натисніть тут, щоб застосувати згладжування графа хвилі + + + + Increase wavegraph amplitude by 1dB + Збільште амплітуди графа хвилі на 1дБ + + + + Click here to increase wavegraph amplitude by 1dB + Натисніть тут, щоб збільшити амплітуду графа хвилі на 1дБ + + + + Decrease wavegraph amplitude by 1dB + Зменшення амплітуди графа хвилі на 1дБ + + + + Click here to decrease wavegraph amplitude by 1dB + Натисніть тут, щоб зменшити амплітуду графа хвилі на 1дБ + + + + 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 Обробляє кожен стерео канал незалежно - - Reset wavegraph - - - - Smooth wavegraph - - - - Increase wavegraph amplitude by 1 dB - - - - Decrease wavegraph amplitude by 1 dB - - - - Stereo mode: maximum - - - - Stereo mode: average - - - - Stereo mode: unlinked - - dynProcControls + Input gain Вхідне підсилення + Output gain Вихідне підсилення + Attack time Час вступу + Release time Час зменшення + Stereo mode Стерео режим - kickerInstrument + expressiveView - Start frequency - Початкова частота + Select oscillator W1 + - End frequency - Кінцева частота + Select oscillator W2 + - Gain - Підсилення + Select oscillator W3 + - Length - Довжина + Select OUTPUT 1 + - Noise - Шум + Select OUTPUT 2 + - Click - Натисніть - - - Start from note - Почати з замітки - - - End to note - Закінчити заміткою - - - Start distortion - - - - End distortion - - - - Envelope slope - - - - Frequency slope - - - - - kickerInstrumentView - - Start frequency: - Початкова частота: - - - End frequency: - Кінцева частота: - - - Gain: - Підсилення: - - - Click: - Натиснення: - - - Noise: - Шум: - - - Frequency slope: - - - - Envelope length: - - - - Envelope slope: - - - - Start distortion: - - - - End distortion: - - - - - ladspaBrowserView - - Available Effects - Доступні ефекти - - - Unavailable Effects - Недоступні ефекти - - - Instruments - Інструменти - - - Analysis Tools - Аналізатори - - - Don't know - Невідомі - - - Type: - Тип: - - - - ladspaDescription - - Plugins - Модулі - - - Description - Опис - - - - ladspaPortDialog - - Ports - Порти - - - Name - І'мя - - - Rate - Частота вибірки - - - Direction - Напрямок - - - Type - Тип - - - Min < Default < Max - Менше < Стандарт <Більше - - - Logarithmic - Логарифмічний - - - SR Dependent - Залежність від SR - - - Audio - Аудіо - - - Control - Управління - - - Input - Ввід - - - Output - Вивід - - - Toggled - Увімкнено - - - Integer - Ціле - - - Float - Дробове - - - Yes - Так - - - - lb302Synth - - VCF Cutoff Frequency - Частота зрізу VCF - - - VCF Resonance - Посилення VCF - - - VCF Envelope Mod - Модуляція обвідної VCF - - - VCF Envelope Decay - Спад обвідної VCF - - - Distortion - Спотворення - - - Waveform - Форма хвилі - - - Slide Decay - Зміщення згасання - - - Slide - Зміщення - - - Accent - Акцент - - - Dead - Глухо - - - 24dB/oct Filter - 24дБ/окт фільтр - - - - lb302SynthView - - Cutoff Freq: - Частота зрізу: - - - Resonance: - Резонанс: - - - Env Mod: - Мод Обвідної: - - - Decay: - Згасання: - - - 303-es-que, 24dB/octave, 3 pole filter - 303-ій, 24дБ/октаву, 3-польний фільтр - - - Slide Decay: - Зміщення згасання: - - - DIST: - СПОТ: - - - Saw wave - Зигзаг - - - Click here for a saw-wave. - Згенерувати зигзаг. - - - Triangle wave - Трикутна хвиля - - - Click here for a triangle-wave. - Згенерувати трикутний сигнал. - - - Square wave - Квадрат - - - Click here for a square-wave. - Згенерувати квадратний сигнал. - - - Rounded square wave - Хвиля округленого квадрату - - - Click here for a square-wave with a rounded end. - Створити квадратну хвилю закруглену в кінці. - - - Moog wave - Муг хвиля - - - Click here for a moog-like wave. - Згенерувати хвилю схожу на муг. + Open help window + Sine wave @@ -3902,46 +10250,607 @@ Генерувати гармонійний (синусоїдальний) сигнал. - White noise wave - Білий шум + Moog-Saw wave + - Click here for an exponential wave. - Генерувати експонентний сигнал. + Click for a Moog-Saw-wave. + + + + Exponential wave + Експоненціальна хвиля + + + Click for an exponential wave. + + + + Saw wave + Зигзаг + + + Click here for a saw-wave. + Згенерувати зигзаг. + + + User defined wave + Користувацька + + + Click here for a user-defined shape. + Задати форму сигналу вручну. + + + Triangle wave + Трикутник + + + Click here for a triangle-wave. + Згенерувати трикутний сигнал. + + + Square wave + Квадратна хвиля + + + Click here for a square-wave. + Згенерувати квадратний сигнал. + + + White noise wave + Білий шум Click here for white-noise. Згенерувати білий шум. + WaveInterpolate + + + + ExpressionValid + + + + General purpose 1: + + + + General purpose 2: + + + + General purpose 3: + + + + O1 panning: + + + + O2 panning: + + + + Release transition: + + + + Smoothness + + + + + fxLineLcdSpinBox + + + Assign to: + Призначити до: + + + + New FX Channel + Новий ефект каналу + + + + graphModel + + + Graph + Графік + + + + kickerInstrument + + + Start frequency + Початкова частота + + + + End frequency + Кінцева частота + + + + Length + Довжина + + + + Distortion Start + Початкове спотворення + + + + Distortion End + Кінцеве спотворення + + + + Gain + Підсилення + + + + Envelope Slope + Нахил обвідної + + + + Noise + Шум + + + + Click + Натисніть + + + + Frequency Slope + Частота нахилу + + + + Start from note + Почати з замітки + + + + End to note + Закінчити заміткою + + + + kickerInstrumentView + + + Start frequency: + Початкова частота: + + + + End frequency: + Кінцева частота: + + + + Frequency Slope: + Частота нахилу: + + + + Gain: + Підсилення: + + + + Envelope Length: + Довжина обвідної: + + + + Envelope Slope: + Нахил обвідної: + + + + Click: + Натиснення: + + + + Noise: + Шум: + + + + Distortion Start: + Початкове спотворення: + + + + Distortion End: + Кінцеве спотворення: + + + + ladspaBrowserView + + + + Available Effects + Доступні ефекти + + + + + Unavailable Effects + Недоступні ефекти + + + + + Instruments + Інструменти + + + + + Analysis Tools + Аналізатори + + + + + Don't know + Невідомі + + + + 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. + У цьому вікні показана інформація про всі модулі LADSPA, які виявила LMMS. Вони розділені на п'ять категорій, залежно від назв і типів портів. + +Доступні ефекти - це ті, які можуть бути використані в LMMS. Щоб ефект LADSPA міг бути використаний, він повинен, по-перше, бути власне ефектом, т. б. мати як вхідні так і вихідні канали. LMMS в якості вхідного каналу сприймає аудіопорти, що містять у назві "in", а вихідні вгадує по підстрочці "out". Для використання в LMMS число вхідних каналів має збігатися з числом вихідних, і ефект повинен мати можливість використання в реальному часі. + +Недоступні ефекти - це модулі LADSPA, розпізнані як ефекти, однак або з незбіжною кількістю вхідних/вихідних каналів, або не призначені для використання в реальному часі. + +Інструменти - це модулі, у яких є тільки вихідні канали. + +Аналізатори - це модулі, що володіють лише вхідними каналами. + +Невідомі - модулі, у яких не було виявлено ні вхідних, ні вихідних каналів. + +Подвійне клацання лівою кнопкою миші по модулю дасть інформацію по його портах. + + + + Type: + Тип: + + + + ladspaDescription + + + Plugins + Модулі + + + + Description + Опис + + + + ladspaPortDialog + + + Ports + Порти + + + + Name + І'мя + + + + Rate + Частота вибірки + + + + Direction + Напрямок + + + + Type + Тип + + + + Min < Default < Max + Менше < Стандарт <Більше + + + + Logarithmic + Логарифмічний + + + + SR Dependent + Залежність від SR + + + + Audio + Аудіо + + + + Control + Управління + + + + Input + Ввід + + + + Output + Вивід + + + + Toggled + Увімкнено + + + + Integer + Ціле + + + + Float + Дробове + + + + + Yes + Так + + + + lb302Synth + + + VCF Cutoff Frequency + Частота зрізу VCF + + + + VCF Resonance + Посилення VCF + + + + VCF Envelope Mod + Модуляція обвідної VCF + + + + VCF Envelope Decay + Спад обвідної VCF + + + + Distortion + Спотворення + + + + Waveform + Форма хвилі + + + + Slide Decay + Зміщення згасання + + + + Slide + Зміщення + + + + Accent + Акцент + + + + Dead + Глухо + + + + 24dB/oct Filter + 24дБ/окт фільтр + + + + lb302SynthView + + + Cutoff Freq: + Частота зрізу: + + + + Resonance: + Резонанс: + + + + Env Mod: + Мод Обвідної: + + + + Decay: + Згасання: + + + + 303-es-que, 24dB/octave, 3 pole filter + 303-ій, 24дБ/октаву, 3-польний фільтр + + + + Slide Decay: + Зміщення згасання: + + + + DIST: + СПОТ: + + + + Saw wave + Зигзаг + + + + Click here for a saw-wave. + Згенерувати зигзаг. + + + + Triangle wave + Трикутна хвиля + + + + Click here for a triangle-wave. + Згенерувати трикутний сигнал. + + + + Square wave + Квадрат + + + + Click here for a square-wave. + Згенерувати квадратний сигнал. + + + + Rounded square wave + Хвиля округленого квадрату + + + + Click here for a square-wave with a rounded end. + Створити квадратну хвилю закруглену в кінці. + + + + Moog wave + Муг хвиля + + + + Click here for a moog-like wave. + Згенерувати хвилю схожу на муг. + + + + Sine wave + Синусоїда + + + + Click for a sine-wave. + Генерувати гармонійний (синусоїдальний) сигнал. + + + + + White noise wave + Білий шум + + + + Click here for an exponential wave. + Генерувати експонентний сигнал. + + + + Click here for white-noise. + Згенерувати білий шум. + + + 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. Натисніть тут для муг-зигзаг хвилі з обмеженою смугою. @@ -3949,286 +10858,562 @@ malletsInstrument + Hardness Жорсткість + Position Положення + + Vibrato Gain + Посилення вібрато + + + + Vibrato Freq + Частота вібрато + + + + Stick Mix + Зведення рученят + + + Modulator Модулятор + Crossfade Перехід + + LFO Speed + Швидкість LFO + + + + LFO Depth + Глибина LFO + + + ADSR ADSR + Pressure Тиск + Motion Рух + Speed Швидкість + Bowed Нахил + Spread Розкид + Marimba Марімба + Vibraphone Віброфон + Agogo Дискотека + + Wood1 + Дерево1 + + + Reso Ресо + + Wood2 + Дерево2 + + + Beats Удари + + Two Fixed + Два фіксованих + + + Clump Важка хода + + Tubular Bells + Трубні дзвони + + + + Uniform Bar + Рівномірні смуги + + + + Tuned Bar + Підстроєні смуги + + + Glass Скло - Vibrato gain - - - - Vibrato frequency - - - - Stick mix - - - - LFO speed - Швидкість LFO - - - LFO depth - - - - Wood 1 - - - - Wood 2 - - - - Two fixed - - - - Tubular bells - - - - Uniform bar - - - - Tuned bar - - - - Tibetan bowl - + + Tibetan Bowl + Тибетські кулі malletsInstrumentView + Instrument Інструмент + Spread Розкид + Spread: Розкид: - Hardness - Жорсткість - - - Hardness: - Жорсткість: - - - Position - Положення - - - Position: - Положення: - - - Modulator - Модулятор - - - Modulator: - Модулятор: - - - Crossfade - Перехід - - - Crossfade: - Перехід: - - - ADSR - ADSR - - - ADSR: - ADSR: - - - Pressure - Тиск - - - Pressure: - Тиск: - - - Speed - Швидкість - - - Speed: - Швидкість: - - + Missing files Відсутні файли + Your Stk-installation seems to be incomplete. Please make sure the full Stk-package is installed! Схоже, що встановлені не всі пакети Stk. Вам слід це перевірити! - Vibrato gain - + + Hardness + Жорсткість - Vibrato gain: - + + Hardness: + Жорсткість: - Vibrato frequency - + + Position + Положення - Vibrato frequency: - + + Position: + Положення: - Stick mix - + + Vib Gain + Підс. вібрато - Stick mix: - + + Vib Gain: + Підс. вібрато: - LFO speed - Швидкість LFO + + Vib Freq + Част. віб - LFO speed: - Швидкість LFO: + + Vib Freq: + Вібрато: - LFO depth - + + Stick Mix + Зведення рученят - LFO depth: - + + Stick Mix: + Зведення рученят: + + + + Modulator + Модулятор + + + + Modulator: + Модулятор: + + + + Crossfade + Перехід + + + + Crossfade: + Перехід: + + + + LFO Speed + Швидкість LFO + + + + LFO Speed: + Швидкість LFO: + + + + LFO Depth + Глибина LFO + + + + LFO Depth: + Глибина LFO: + + + + ADSR + ADSR + + + + ADSR: + ADSR: + + + + Pressure + Тиск + + + + Pressure: + Тиск: + + + + Speed + Швидкість + + + + Speed: + Швидкість: manageVSTEffectView + - VST parameter control Управление VST параметрами + + VST Sync + VST синхронізація + + + + Click here if you want to synchronize all parameters with VST plugin. + Натисніть тут для синхронізації всіх параметрів VST плагіна. + + + + Automated Автоматизовано + + Click here if you want to display automated parameters only. + Натисніть тут, якщо хочете бачити тільки автоматизовані параметри. + + + Close Закрити - VST sync - + + Close VST effect knob-controller window. + Закрити вікно управління регуляторами VST плагіна. manageVestigeInstrumentView + + - VST plugin control Управління VST плагіном + VST Sync VST синхронізація + + Click here if you want to synchronize all parameters with VST plugin. + Натисніть тут для синхронізації всіх параметрів VST плагіна. + + + + Automated Автоматизовано + + Click here if you want to display automated parameters only. + Натисніть тут, якщо хочете бачити тільки автоматизовані параметри. + + + Close Закрити + + + Close VST plugin knob-controller window. + Закрити вікно управління регуляторами VST плагіна. + + + + opl2instrument + + + Patch + Патч + + + + Op 1 Attack + ОП 1 Вступ + + + + Op 1 Decay + ОП 1 Спад + + + + Op 1 Sustain + ОП 1 Видержка + + + + Op 1 Release + ОП 1 Зменшення + + + + Op 1 Level + ОП 1 Рівень + + + + Op 1 Level Scaling + ОП 1 Рівень збільшення + + + + Op 1 Frequency Multiple + ОП 1 Множник частот + + + + Op 1 Feedback + ОП 1 Повернення + + + + Op 1 Key Scaling Rate + ОП 1 Ключова ставка множника + + + + Op 1 Percussive Envelope + ОП 1 Ударна обвідна + + + + Op 1 Tremolo + ОП 1 Тремоло + + + + Op 1 Vibrato + Оп 1 Вібрато + + + + Op 1 Waveform + ОП 1 Хвиля + + + + Op 2 Attack + ОП 2 Вступ + + + + Op 2 Decay + ОП 2 Спад + + + + Op 2 Sustain + ОП 2 Видержка + + + + Op 2 Release + ОП 2 Зменшення + + + + Op 2 Level + ОП 2 Рівень + + + + Op 2 Level Scaling + ОП 2 Рівень збільшення + + + + Op 2 Frequency Multiple + ОП 2 Множник частот + + + + Op 2 Key Scaling Rate + ОП 2 Ключова ставка множника + + + + Op 2 Percussive Envelope + ОП 2 Ударна обвідна + + + + Op 2 Tremolo + ОП 2 Тремоло + + + + Op 2 Vibrato + Оп 2 Вібрато + + + + Op 2 Waveform + ОП 2 Хвиля + + + + FM + FM + + + + Vibrato Depth + Глибина вібрато + + + + Tremolo Depth + Глибина тремоло + + + + opl2instrumentView + + + + Attack + Вступ + + + + + Decay + Згасання + + + + + Release + Зменшення + + + + + Frequency multiplier + Множник частоти + organicInstrument + Distortion Спотворення + Volume Гучність @@ -4236,73 +11421,458 @@ organicInstrumentView + Distortion: Спотворення: + + The distortion knob adds distortion to the output of the instrument. + Спотворення додає спотворення до виходу інструменту. + + + 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: Форма сигналу осциллятора %1: + Osc %1 volume: Гучність осциллятора %1: + Osc %1 panning: Баланс для осциллятора %1: - cents - соті - - + Osc %1 stereo detuning Осц %1 стерео расстройка + + cents + соті + + + Osc %1 harmonic: Осц %1 гармоніка: + + FreeBoyInstrument + + + Sweep time + Час поширення + + + + Sweep direction + Напрям поширення + + + + Sweep RtShift amount + Кіл-ть розгортки зсуву вправо + + + + + Wave Pattern Duty + Робоча форма хвилі + + + + Channel 1 volume + Гучність першого каналу + + + + + + Volume sweep direction + Обсяг напрямку поширення + + + + + + Length of each step in sweep + Довжина кожного кроку в розгортці + + + + Channel 2 volume + Гучність другого каналу + + + + Channel 3 volume + Гучність третього каналу + + + + Channel 4 volume + Гучність четвертого каналу + + + + Shift Register width + Зміщення ширини регістра + + + + Right Output level + Вихідний рівень праворуч + + + + Left Output level + Вихідний рівень зліва + + + + Channel 1 to SO2 (Left) + Від першого каналу до SO2 (лівий канал) + + + + Channel 2 to SO2 (Left) + Від другого каналу до SO2 (лівий канал) + + + + Channel 3 to SO2 (Left) + Від третього каналу до SO2 (лівий канал) + + + + Channel 4 to SO2 (Left) + Від четвертого каналу до SO2 (лівий канал) + + + + Channel 1 to SO1 (Right) + Від першого каналу до SO1 (правий канал) + + + + Channel 2 to SO1 (Right) + Від другого каналу до SO1 (правий канал) + + + + Channel 3 to SO1 (Right) + Від третього каналу до SO1 (правий канал) + + + + Channel 4 to SO1 (Right) + Від четвертого каналу до SO1 (правий канал) + + + + Treble + Дискант + + + + Bass + Бас + + + + FreeBoyInstrumentView + + + 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: + Гучність квадратного каналу 1: + + + + Square Channel 1 Volume + Гучність квадратного каналу 1 + + + + + + Length of each step in sweep: + Довжина кожного кроку в розгортці: + + + + + + Length of each step in sweep + Довжина кожного кроку в розгортці + + + + + + The delay between step change + Затримка між змінами кроку + + + + Wave pattern duty + Робоча форма хвилі + + + + Square Channel 2 Volume: + Гучність квадратного каналу 2: + + + + + Square Channel 2 Volume + Гучність квадратного каналу 2 + + + + Wave Channel Volume: + Гучність хвильового каналу: + + + + + Wave Channel Volume + Гучність хвильового каналу + + + + Noise Channel Volume: + Гучність каналу шуму: + + + + + Noise Channel Volume + Гучність каналу шуму + + + + SO1 Volume (Right): + Гучність SO1 (Правий): + + + + SO1 Volume (Right) + Гучність SO1 (Правий) + + + + SO2 Volume (Left): + Гучність SO2 (Лівий): + + + + SO2 Volume (Left) + Гучність SO2 (Лівий) + + + + Treble: + Дискант: + + + + Treble + Дискант + + + + Bass: + Бас: + + + + Bass + Бас + + + + Sweep Direction + Напрямок розгортки + + + + + + + + Volume Sweep Direction + Гучність напрямки розгортки + + + + Shift Register Width + Зміщення ширини регістра + + + + Channel1 to SO1 (Right) + Канал1 в SO1 (Правий) + + + + Channel2 to SO1 (Right) + Канал2 в SO1 (Правий) + + + + Channel3 to SO1 (Right) + Канал3 в SO1 (Правий) + + + + Channel4 to SO1 (Right) + Канал4 в SO1 (Правий) + + + + Channel1 to SO2 (Left) + Канал1 в SO2 (Лівий) + + + + Channel2 to SO2 (Left) + Канал2 в SO2 (Лівий) + + + + Channel3 to SO2 (Left) + Канал3 в SO2 (Лівий) + + + + Channel4 to SO2 (Left) + Канал4 в SO2 (Лівий) + + + + Wave Pattern + Малюнок хвилі + + + + Draw the wave here + Малювати хвилю тут + + patchesDialog + Qsynth: Channel Preset Q-Синтезатор: Канал передустановлено + Bank selector Селектор банку + Bank Банк + Program selector Селектор програм + Patch Патч + Name І'мя + OK ОК + Cancel Скасувати @@ -4310,449 +11880,634 @@ pluginBrowser - Incomplete monophonic imitation tb303 - Незавершена монофонічна імітація tb303 + + no description + опис відсутній - Plugin for freely manipulating stereo output - Модуль для довільного управління стереовиходом + + A native amplifier plugin + Рідний плагін підсилення - Plugin for controlling knobs with sound peaks - Модуль для встановлення значень регуляторів на піках гучності + + Simple sampler with various settings for using samples (e.g. drums) in an instrument-track + Простий семплер з різними налаштуваннями для використання записів (наприклад, ударні) в інструментальному трекі - Plugin for enhancing stereo separation of a stereo input file - Модуль, що підсилює різницю між каналами стереозапису + + Boost your bass the fast and simple way + Накачай свій бас швидко і просто + + Customizable wavetable synthesizer + Налаштовуваний синтезатор звукозаписів (wavetable) + + + + An oversampling bitcrusher + Перевибірка малого дробдення + + + + Carla Patchbay Instrument + Carla Комутаційний інструмент + + + + Carla Rack Instrument + Carla підставочний інструмент + + + + A 4-band Crossover Equalizer + 4-смуговий еквалайзер Кросовер + + + + A native delay plugin + Рідний плагін затримки + + + + A Dual filter plugin + Плагін подвійного фільтру + + + + plugin for processing dynamics in a flexible way + плагін для обробки динаміки гнучким методом + + + + A native eq plugin + Рідний eq плагін + + + + A native flanger plugin + Рідний фланжер плагін + + + + Player for GIG files + Програвач GIG файлів + + + + Filter for importing Hydrogen files into LMMS + Фільтр для імпорту Hydrogen файлів в LMMS + + + + Versatile drum synthesizer + Універсальний барабанний синтезатор + + + List installed LADSPA plugins Показати встановлені модулі LADSPA - GUS-compatible patch instrument - Патч-інструмент, сумісний з GUS - - - Additive Synthesizer for organ-like sounds - Синтезатор звуків нашталт органу - - - Tuneful things to bang on - Мелодійні ударні - - - VST-host for using VST(i)-plugins within LMMS - VST - хост для підтримки модулів VST(i) в LMMS - - - Vibrating string modeler - Емуляція вібруючих струн - - + plugin for using arbitrary LADSPA-effects inside LMMS. Модуль, що дозволяє використовувати в LMMS будь які ефекти LADSPA. + + Incomplete monophonic imitation tb303 + Незавершена монофонічна імітація tb303 + + + + Filter for exporting MIDI-files from LMMS + Фільтри для експорту MIDI-файлів з LMMS + + + Filter for importing MIDI-files into LMMS Фільтр для включення файлу MIDI в проект ЛММС + + Monstrous 3-oscillator synth with modulation matrix + Монстро 3-осцилляторний синт з матрицею модуляції + + + + A multitap echo delay plugin + Плагін багаторазової послідовної затримки відлуння + + + + A NES-like synthesizer + NES-подібний синтезатор + + + + 2-operator FM Synth + 2-режимний синт модуляції частот (FM synth) + + + + Additive Synthesizer for organ-like sounds + Синтезатор звуків нашталт органу + + + + Emulation of GameBoy (TM) APU + Емуляція GameBoy (ТМ) + + + + GUS-compatible patch instrument + Патч-інструмент, сумісний з GUS + + + + Plugin for controlling knobs with sound peaks + Модуль для встановлення значень регуляторів на піках гучності + + + + Reverb algorithm by Sean Costello + Алгоритм реверберації Шона Костелло + + + + Player for SoundFont files + Програвач файлів SoundFont + + + + LMMS port of sfxr + LMMS порт SFXR + + + Emulation of the MOS6581 and MOS8580 SID. This chip was used in the Commodore 64 computer. Емуляція MOS6581 і MOS8580. Використовувалося на комп'ютері Commodore 64. - Player for SoundFont files - Програвач файлів SoundFont - - - Emulation of GameBoy (TM) APU - Емуляція GameBoy (ТМ) - - - Customizable wavetable synthesizer - Налаштовуваний синтезатор звукозаписів (wavetable) - - - Embedded ZynAddSubFX - Вбудований ZynAddSubFX - - - 2-operator FM Synth - 2-режимний синт модуляції частот (FM synth) - - - Filter for importing Hydrogen files into LMMS - Фільтр для імпорту Hydrogen файлів в LMMS - - - LMMS port of sfxr - LMMS порт SFXR - - - Monstrous 3-oscillator synth with modulation matrix - Монстро 3-осцилляторний синт з матрицею модуляції - - - Three powerful oscillators you can modulate in several ways - Три потужних генераторів можна модулювати декількома способами - - - A native amplifier plugin - Рідний плагін підсилення - - - Carla Rack Instrument - Carla підставочний інструмент - - - 4-oscillator modulatable wavetable synth - 4-генераторний модулюючий синтезатор звукозаписів - - - plugin for waveshaping - плагін формування сигналу - - - Boost your bass the fast and simple way - Накачай свій бас швидко і просто - - - Versatile drum synthesizer - Універсальний барабанний синтезатор - - - Simple sampler with various settings for using samples (e.g. drums) in an instrument-track - Простий семплер з різними налаштуваннями для використання записів (наприклад, ударні) в інструментальному трекі - - - plugin for processing dynamics in a flexible way - плагін для обробки динаміки гнучким методом - - - Carla Patchbay Instrument - Carla Комутаційний інструмент - - - plugin for using arbitrary VST effects inside LMMS. - плагін для використання довільних VST ефектів всередині LMMS. - - + Graphical spectrum analyzer plugin Плагін графічного аналізу спектру - A NES-like synthesizer - NES-подібний синтезатор + + Plugin for enhancing stereo separation of a stereo input file + Модуль, що підсилює різницю між каналами стереозапису - A native delay plugin - Рідний плагін затримки + + Plugin for freely manipulating stereo output + Модуль для довільного управління стереовиходом - Player for GIG files - Програвач GIG файлів + + Tuneful things to bang on + Мелодійні ударні - A multitap echo delay plugin - Плагін багаторазової послідовної затримки відлуння + + Three powerful oscillators you can modulate in several ways + Три потужних генераторів можна модулювати декількома способами - A native flanger plugin - Рідний фланжер плагін + + VST-host for using VST(i)-plugins within LMMS + VST - хост для підтримки модулів VST(i) в LMMS - An oversampling bitcrusher - Перевибірка малого дробдення + + Vibrating string modeler + Емуляція вібруючих струн - A native eq plugin - Рідний eq плагін + + plugin for using arbitrary VST effects inside LMMS. + плагін для використання довільних VST ефектів всередині LMMS. - A 4-band Crossover Equalizer - 4-смуговий еквалайзер Кросовер + + 4-oscillator modulatable wavetable synth + 4-генераторний модулюючий синтезатор звукозаписів - A Dual filter plugin - Плагін подвійного фільтру + + plugin for waveshaping + плагін формування сигналу - Filter for exporting MIDI-files from LMMS - Фільтри для експорту MIDI-файлів з LMMS - - - Reverb algorithm by Sean Costello - + + Embedded ZynAddSubFX + Вбудований ZynAddSubFX Mathematical expression parser - + sf2Instrument + Bank Банк + Patch Патч + 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 не вдається завантажити. - - Reverb room size - - - - Reverb damping - - - - Reverb width - - - - Reverb level - - - - Chorus voices - - - - Chorus level - - - - Chorus speed - - - - Chorus depth - - sf2InstrumentView + + Open other SoundFont file + Відкрити інший файл SoundFront + + + + Click here to open another SF2 file + Натисніть тут щоб відкрити інший файл SF2 + + + + 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 Відкрити файл SoundFront - Choose patch - - - - Gain: - Підсилення: - - - Room size: - - - - Damping: - - - - Width: - Ширина: - - - Level: - - - - Voices: - - - - Speed: - Швидкість: - - - Depth: - Глибина: - - - SoundFont Files (*.sf2 *.sf3) - + + SoundFont2 Files (*.sf2) + Файли SoundFont2 (*.sf2) sfxrInstrument - Wave - + + Wave Form + Форма хвилі sidInstrument + + Cutoff + Зріз + + + Resonance Підсилення + Filter type Тип фільтру + Voice 3 off Голос 3 відкл + Volume Гучність + Chip model Модель чіпа - - Cutoff frequency - Зріз частоти - sidInstrumentView + Volume: Гучність: + Resonance: Підсилення: + + Cutoff frequency: Частота зрізу: + + High-Pass filter + Вис.ЧФ + + + + Band-Pass filter + Серед.ЧФ + + + + Low-Pass filter + Низ.ЧФ + + + + Voice3 Off + Голос 3 відкл + + + MOS6581 SID MOS6581 SID + MOS8580 SID MOS8580 SID + + Attack: Вступ: + + Attack rate determines how rapidly the output of Voice %1 rises from zero to peak amplitude. + Тривалість вступу визначає, наскільки швидко гучність %1-го голосу зростає від нуля до максимального значення. + + + + Decay: Згасання: + + Decay rate determines how rapidly the output falls from the peak amplitude to the selected Sustain level. + Тривалість спаду визначає, наскільки швидко гучність падає від максимуму до залишкового рівня. + + + Sustain: Витримка: + + Output of Voice %1 will remain at the selected Sustain amplitude as long as the note is held. + Гучність %1-го голосу залишатиметься на рівні амплітуди витримки, поки триває нота. + + + + Release: Зменшення: + + The output of of Voice %1 will fall from Sustain amplitude to zero amplitude at the selected Release rate. + Гучність %1-го голосу буде падати від залишкового рівня до нуля з вказаною тут швидкістю. + + + + 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. + Тривалість імпульсу дозволяє м'яко регулювати проходження імпульсу без помітних збоїв. Імпульсна хвиля повинна бути обрана на осцилляторі %1, щоб отримати звучання. + + + Coarse: Грубість: + + The Coarse detuning allows to detune Voice %1 one octave up or down. + Грубі налаштування дозволяють підлаштувати Голос %1 на одну октаву вгору або вниз. + + + + Pulse Wave + Пульсуюча хвиля + + + + Triangle Wave + Трикутник + + + + SawTooth + Зигзаг + + + Noise Шум + Sync Синхро + + Sync synchronizes the fundamental frequency of Oscillator %1 with the fundamental frequency of Oscillator %2 producing "Hard Sync" effects. + Синхро синхронізує фундаментальну частоту осцилляторів %1 фундаментальною частотою осциллятора %2, створюючи ефект "Залізної синхронізації". + + + + Ring-Mod + Круговий режим + + + + Ring-mod replaces the Triangle Waveform output of Oscillator %1 with a "Ring Modulated" combination of Oscillators %1 and %2. + Круговий режим замінює трикутні хвилі на виході осциллятора %1 "Круговою модуляцією" комбінацією осцилляторів %1 і %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. + Якщо цей прапорець встановлено, то %1-й голос буде проходити через фільтр. Інакше голос № %1 буде подаватися прямо на вихід. + + + Test Тест - High-pass filter - - - - Band-pass filter - - - - Low-pass filter - - - - Voice 3 off - - - - Pulse wave - - - - Triangle wave - - - - Saw wave - Зигзаг - - - Ring modulation - - - - Pulse width: - + + Test, when set, resets and locks Oscillator %1 at zero until Test is turned off. + Якщо «прапорець» встановлено, то %1-й осциллятор видає нульовий сигнал (поки прапорець не зніметься). stereoEnhancerControlDialog - Width: - Ширина: + + WIDE + ШИРШЕ - WIDTH - + + Width: + Ширина: stereoEnhancerControls + Width Ширина @@ -4760,18 +12515,22 @@ This chip was used in the Commodore 64 computer. stereoMatrixControlDialog + Left to Left Vol: Від лівого на лівий: + Left to Right Vol: Від лівого на правий: + Right to Left Vol: Від правого на лівий: + Right to Right Vol: Від правого на правий: @@ -4779,18 +12538,22 @@ This chip was used in the Commodore 64 computer. stereoMatrixControls + Left to Left Від лівого на лівий + Left to Right Від лівого на правий + Right to Left Від правого на лівий + Right to Right Від правого на правий @@ -4798,191 +12561,380 @@ This chip was used in the Commodore 64 computer. vestigeInstrument + Loading plugin Завантаження модуля - Please wait while loading the VST plugin... - + + Please wait while loading VST-plugin... + Будь ласка зачекайте поки завантажеться модуль VST... vibed + String %1 volume Гучність %1-й струни + String %1 stiffness Жорсткість %1-й струни + Pick %1 position Лад %1 + Pickup %1 position Положення %1-го звукознімача + + Pan %1 + Бал %1 + + + + Detune %1 + Підстроювання %1 + + + + Fuzziness %1 + Нечіткість %1 + + + + Length %1 + Довжина %1 + + + Impulse %1 Імпульс %1 - String %1 panning - - - - String %1 detune - - - - String %1 fuzziness - - - - String %1 length - - - - String %1 - + + Octave %1 + Октава %1 vibedView + + Volume: + Гучність: + + + + The 'V' knob sets the volume of the selected string. + Регулятор 'V' встановлює гучність поточної струни. + + + 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. + Регулятор 'S' встановлює жорсткість поточної струни. Цей параметр відповідає за тривалість звучання струни (чим більше значення жорсткості, тим довше дзвенить струна). + + + Pick position: Ударна позиція: + + 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. + Регулятор 'P' встановлює місце струни, де вона буде "притиснута". Чим нижче значення, тим ближче це місце буде до кобилки. + + + Pickup position: Положення звукознімача: + + 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. + Регулятор 'PU' встановлює місце струни, звідки буде зніматися звук. Чим нижче значення, тим ближче це місце буде до мосту. + + + + Pan: + Бал: + + + + The Pan knob determines the location of the selected string in the stereo field. + Ця ручка встановлює стереобаланс для поточної струни. + + + + 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: + Нечіткість: + + + + 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: + Довжина: + + + + 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. + Перемикач "Imp" встановлює режим роботи струни: якщо він включений, то зазначена форма сигналу інтерпретується як початковий імпульс, інакше - як початкова форма струни. + + + Octave Октава + + 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. + Перемикач октав дозволяє вказати гармоніку основної частоти, на якій буде звучати струна. Наприклад, "-2" означає, що струна буде звучати двома октавами нижче основної частоти, "F" змусить струну дзвеніти на основній частоті інструменту, а "6" - на частоті, на шість октав більш високій, ніж основна. + + + Impulse Editor Редактор сигналу + + 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. + Редактор форми дозволяє явно вказати профіль струни в початковий момент часу, або її початковий імпульс (в залежності від стану перемикача "Imp"). +Кнопки праворуч від малюнка дозволяють задавати деякі стандартні форми, причому кнопка '?' служить для задання форми з довільного звукового файлу (завантажуються перші 128 елементів вибірки). + +Також форма сигналу може бути просто намальована за допомогою миші. + +Кнопка 'S' згладить поточну форму. + +Кнопка 'N' нормалізує рівень. + + + + 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. + Інструмент "Vibed" моделює до дев'яти незалежних одночасно звучних струн. + +Перемикач "Strings" дозволяє вибрати струну, чиї властивості редагуються. + +Перемикач "Imp" встановлює режим роботи струни: якщо він включений, то зазначена форма сигналу інтерпретується як початковий імпульс, інакше - як початкова форма струни. + +Перемикач "Octave" дозволяє вказати гармоніку основної частоти, на якій буде звучати струна. + +Редактор форми дозволяє явно вказати профіль струни в початковий момент часу, або її початковий імпульс. + +Ручка 'V' встановлює гучність поточної струни, 'S' - жорсткість, 'P' - місце, де притиснута струна, а 'PU' '- положення звукознімача. + +Ручка підстроювання і стереобалансу, сподіваємося не потребує пояснень. + +Ручка "Довжина" регулює довжину струни + +Індикатор-перемикач зліва внизу визначає, чи включена поточна струна. + + + Enable waveform Включити сигнал + + Click here to enable/disable waveform. + Натисніть, щоб увімкнути/вимкнути сигнал. + + + String Струна + + 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. + Перемикач струн дозволяє вибрати струну, чиї властивості редагуються. Інструмент Vibed містить до дев'яти незалежно звучних струн, індикатор в лівому нижньому куті показує, активна чи поточна струна (тобто чи буде вона чутна). + + + Sine wave Синусоїда + + Use a sine-wave for current oscillator. + Генерувати гармонійний (синусоїдальний) сигнал. + + + Triangle wave Трикутник + + Use a triangle-wave for current oscillator. + Генерувати трикутний сигнал. + + + Saw wave Зигзаг + + Use a saw-wave for current oscillator. + Генерувати зигзагоподібний сигнал. + + + Square wave Квадратна хвиля - String volume: - + + Use a square-wave for current oscillator. + Генерувати квадрат. - String panning: - + + White noise wave + Білий шум - String detune: - + + Use white-noise for current oscillator. + Генерувати білий шум. - String fuzziness: - + + User defined wave + Користувацька - String length: - + + Use a user-defined waveform for current oscillator. + Задати форму сигналу. - Impulse - + + Smooth + Згладити - Enable/disable string - + + Click here to smooth waveform. + Клацніть щоб згладити форму сигналу. - White noise - Білий шум + + Normalize + Нормалізувати - User-defined wave - - - - Smooth waveform - Згладжений сигнал - - - Normalize waveform - + + Click here to normalize waveform. + Натисніть, щоб нормалізувати сигнал. voiceObject + Voice %1 pulse width Голос %1 довжина сигналу + Voice %1 attack Вступ %1-го голосу + Voice %1 decay Згасання %1-го голосу + Voice %1 sustain Витримка для %1-го голосу + Voice %1 release Зменшення %1-го голосу + Voice %1 coarse detuning Підналаштування %1-голосу (грубо) + Voice %1 wave shape Форма сигналу для %1-го голосу + Voice %1 sync Синхронізація %1-го голосу + Voice %1 ring modulate Голос %1 кільцевий модулятор + Voice %1 filtered Фільтрований %1-й голос + Voice %1 test Голос %1 тест @@ -4990,53 +12942,85 @@ This chip was used in the Commodore 64 computer. waveShaperControlDialog + INPUT ВХІД + Input gain: Вхідне підсилення: + OUTPUT ВИХІД + Output gain: Вихідне підсилення: + + Reset waveform + Скидання сигналу + + + + Click here to reset the wavegraph back to default + Натисніть тут, щоб скинути граф хвилі назад за замовчуванням + + + + Smooth waveform + Згладжений сигнал + + + + Click here to apply smoothing to wavegraph + Натисніть тут, щоб застосувати згладжування графа хвилі + + + + Increase graph amplitude by 1dB + Збільште амплітуди графа хвилі на 1дБ + + + + Click here to increase wavegraph amplitude by 1dB + Натисніть тут, щоб збільшити амплітуду графа хвилі на 1дБ + + + + Decrease graph amplitude by 1dB + Зменшення амплітуди графа хвилі на 1дБ + + + + Click here to decrease wavegraph amplitude by 1dB + Натисніть тут, щоб зменшити амплітуду графа хвилі на 1дБ + + + Clip input Зрізати вхідний сигнал - Reset wavegraph - - - - Smooth wavegraph - - - - Increase wavegraph amplitude by 1 dB - - - - Decrease wavegraph amplitude by 1 dB - - - - Clip input signal to 0 dB - + + Clip input signal to 0dB + Зрізати вхідний сигнал до 0дБ waveShaperControls + Input gain Вхідне підсилення + Output gain Вихідне підсилення diff --git a/data/locale/zh_TW.ts b/data/locale/zh_TW.ts index 15c0059bc..261d7c666 100644 --- a/data/locale/zh_TW.ts +++ b/data/locale/zh_TW.ts @@ -1,37 +1,123 @@ - - - + + + AboutDialog + + + About LMMS + 關於 LMMS + + + + LMMS + LMMS + + + + Version %1 (%2/%3, Qt %4, %5) + 版本 %1 (%2/%3, Qt %4, %5) + + + + About + 關於 + + + + LMMS - easy music production for everyone + LMMS - 人人都是作曲家 + + + + Copyright © %1 + 版權所有 © %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 + 作者 + + + + Involved + 參與者 + + + + Contributors ordered by number of commits: + 貢獻者名單(以提交次數排序): + + + + Translation + 翻譯 + + + + 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! + 當前語言是中文(台灣) + +翻譯人員: +TonyChyi <tonychee1989 at gmail.com> +Min Zhang <zm1990s at gmail.com> +Jeff Bai <jeffbaichina at gmail.com> +Mingye Wang <arthur2e5@aosc.xyz> +Zixing Liu <liushuyu@aosc.xyz> +BrLi <brli at chakraos.org> + +若你有興趣提高翻譯品質,請聯絡維護團隊 (https://github.com/AOSC-Dev/translations)、之前的譯者或本項目維護者! + + + + License + 授權協議 + + AmplifierControlDialog + VOL VOL + Volume: 音量: + PAN PAN + Panning: 聲相: + LEFT + Left gain: 左增益: + RIGHT + Right gain: 右增益: @@ -39,95 +125,725 @@ AmplifierControls + Volume 音量 + Panning 聲相 + Left gain 左增益 + Right gain 右增益 + + AudioAlsaSetupWidget + + + DEVICE + 裝置 + + + + CHANNELS + 聲道數 + + AudioFileProcessorView + + Open other sample + 開啟其他取樣 + + + + 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. + 如果想打開另一個音訊檔,請點擊這裡。接著會出現檔案選擇視窗。諸如循環模式 (looping-mode),起始/結束點,放大率 (amplify-value) 之類的值不會被重置。因此聽起來會和取樣來源有差異。 + + + Reverse sample 反轉取樣 - Amplify: - 放大: - - - Continue sample playback across notes - 跨音符繼續播放採樣 + + If you enable this button, the whole sample is reversed. This is useful for cool effects, e.g. a reversed crash. + 如果點擊此按鈕,整個取樣將會被反轉。能用於製作很酷的效果,例如 reversed crash. + Disable loop 停用循環 + + This button disables looping. The sample plays only once from start to end. + 點擊此按鈕可以禁止循環播放。取樣檔案將從頭到尾播放一次。 + + + + Enable loop 啟用循環 + + This button enables forwards-looping. The sample loops between the end point and the loop point. + 點擊此按鈕後,Forwards-looping 會被打開,採樣將在終止點(End Point)和循環點(Loop Point)之間播放。 + + + + This button enables ping-pong-looping. The sample loops backwards and forwards between the end point and the loop point. + 點擊此按鈕後,Ping-pong-looping 會被打開,採樣將在終止點 (End Point) 和循環點 (Loop Point) 之間來回播放。 + + + + Continue sample playback across notes + 跨音符繼續播放採樣 + + + + 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) + + + + + Amplify: + 放大: + + + + 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!) + 此旋鈕用於調整放大比率。當設爲100% 時採樣不會變化。除此之外,不是放大就是減弱(原始的採樣文件不會被改變) + + + + Startpoint: + 起始點: + + + + With this knob you can set the point where AudioFileProcessor should begin playing your sample. + 調節此旋鈕,以告訴 AudioFileProcessor 在哪裏開始播放。 + + + + Endpoint: + 終點: + + + + With this knob you can set the point where AudioFileProcessor should stop playing your sample. + 調節此旋鈕,以告訴 AudioFileProcessor 在哪裏停止播放。 + + + Loopback point: 循環點: - Open sample - - - - Enable ping-pong loop - - - - Start point: - - - - End point: - + + With this knob you can set the point where the loop starts. + 調節此旋鈕,以設置循環開始的地方。 AudioFileProcessorWaveView + Sample length: 採樣長度: + + AudioJack + + + JACK client restarted + JACK 客戶端已重啓 + + + + 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 由於某些原因與 JACK 中斷連線,因此 LMMS 的 JACK 後端已重新啟動,您必須手動重新連線。 + + + + JACK server down + JACK 伺服器發生問題 + + + + 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. + JACK 伺服器似乎發生問題,而且無法重新啟動,因此 LMMS 無法繼續執行。請儲存專案,然後重新啟動 JACK 和 LMMS。 + + + + CLIENT-NAME + 客戶端名稱 + + + + CHANNELS + 聲道數 + + + + AudioOss::setupWidget + + + DEVICE + 裝置 + + + + CHANNELS + 聲道數 + + + + AudioPortAudio::setupWidget + + + BACKEND + 後端 + + + + DEVICE + 裝置 + + + + AudioPulseAudio::setupWidget + + + DEVICE + 裝置 + + + + CHANNELS + 聲道數 + + + + AudioSdl::setupWidget + + + DEVICE + 裝置 + + + + AudioSndio::setupWidget + + + DEVICE + 裝置 + + + + CHANNELS + 聲道數 + + + + AudioSoundIo::setupWidget + + + BACKEND + 後端 + + + + DEVICE + 裝置 + + + + AutomatableModel + + + &Reset (%1%2) + 重設(%1%2)(&R) + + + + &Copy value (%1%2) + 複製值(%1%2)(&C) + + + + &Paste value (%1%2) + 貼上值(%1%2)(&P) + + + + Edit song-global automation + 編輯歌曲全局的自動控制裝置 + + + + Remove song-global automation + 移除歌曲全域自動控制裝置 + + + + Remove all linked controls + 移除所有已連線的控制器 + + + + Connected to %1 + 已連線至 %1 + + + + Connected to controller + 連線至控制器 + + + + Edit connection... + 編輯連線… + + + + Remove connection + 移除連線 + + + + Connect to controller... + 連線至控制器… + + + + AutomationEditor + + + Please open an automation pattern with the context menu of a control! + 請透過控制的右鍵選單開啟自動控制模式! + + + + Values copied + 值已複製 + + + + All selected values were copied to the clipboard. + 所有選中的值已複製。 + + + + 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) + 繪製模式 (Shift+D) + + + + Erase mode (Shift+E) + 擦除模式 (Shift+E) + + + + Flip vertically + 垂直翻轉 + + + + Flip horizontally + 水平翻轉 + + + + Click here and the pattern will be inverted.The points are flipped in the y direction. + 點擊這裡來翻轉圖形 (pattern)。圖上的點會隨y軸翻轉。 + + + + Click here and the pattern will be reversed. The points are flipped in the x direction. + 點擊這裡來翻轉圖形 (pattern)。圖上的點會隨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. + 點擊這裏啓用繪製模式。在此模式下你可以增加或移動單個值。 大部分時間下默認使用此模式。你也可以按鍵盤上的 ‘Shift+D’激活此模式。 + + + + 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. + 點擊啓用擦除模式。此模式下你可以擦除單個值。你可以按鍵盤上的 'Shift+E' 啓用此模式。 + + + + Interpolation controls + 補間控制 + + + + Discrete progression + 區間進程 (Discrete progression) + + + + Linear 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) + 剪下選擇的值 (%1+X) + + + + Copy selected values (%1+C) + 複製選擇的值 (%1+C) + + + + Paste values from clipboard (%1+V) + 從剪貼簿貼上值 (%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 + 自動控制編輯器 - %1 + + + + Model is already connected to this pattern. + 模型已連接到此片段。 + + + + AutomationPattern + + + Drag a control while pressing <%1> + 按住<%1>拖動控制器 + + + + AutomationPatternView + + + double-click to open this pattern in automation editor + 雙擊在自動編輯器中打開此片段 + + + + Open in Automation editor + 在自動編輯器(Automation editor)中打開 + + + + Clear + 清除 + + + + Reset name + 重置名稱 + + + + Change name + 修改名稱 + + + + Set/clear record + 設置/清除錄製 + + + + Flip Vertically (Visible) + 垂直翻轉 (可見) + + + + Flip Horizontally (Visible) + 水平翻轉 (可見) + + + + %1 Connections + %1個連接 + + + + Disconnect "%1" + 斷開“%1”的連接 + + + + Model is already connected to this pattern. + 模型已連接到此片段。 + + + + AutomationTrack + + + Automation track + 自動控制軌道 + + + + BBEditor + + + Beat+Bassline Editor + 節拍+低音線編輯器 + + + + Play/pause current beat/bassline (Space) + 播放/暫停當前節拍/低音線(空格) + + + + Stop playback of current beat/bassline (Space) + 停止播放當前節拍/低音線(空格) + + + + Click here to play the current beat/bassline. The beat/bassline is automatically looped when its end is reached. + 點擊這裏停止播放當前節拍/低音線。當結束時節拍/低音線會自動循環播放。 + + + + Click here to stop playing of current beat/bassline. + 點擊這裏停止播發當前節拍/低音線。 + + + + Beat selector + 節拍選擇器 + + + + Track and step actions + + + + + Add beat/bassline + 添加節拍/低音線 + + + + Add sample-track + 新增採樣音軌 + + + + Add automation-track + 添加自動控制軌道 + + + + Remove steps + 移除音階 + + + + Add steps + 添加音階 + + + + Clone Steps + + + + + BBTCOView + + + Open in Beat+Bassline-Editor + 在節拍+Bassline編輯器中打開 + + + + Reset name + 重置名稱 + + + + Change name + 修改名稱 + + + + Change color + 改變顏色 + + + + Reset color to default + 重置顏色 + + + + BBTrack + + + Beat/Bassline %1 + 節拍/Bassline %1 + + + + Clone of %1 + %1 的副本 + + BassBoosterControlDialog + FREQ 頻率 + Frequency: 頻率: + GAIN 增益 + Gain: 增益: + RATIO 比率 + Ratio: 比率: @@ -135,14 +851,17 @@ BassBoosterControls + Frequency 頻率 + Gain 增益 + Ratio 比率 @@ -150,1043 +869,2095 @@ BitcrushControlDialog + IN 輸入 + OUT 輸出 + + GAIN 增益 + + Input Gain: + 輸入增益: + + + + NOISE + + + + + Input Noise: + 輸入噪音: + + + + Output Gain: + 輸出增益: + + + CLIP 壓限 - Sample rate: - 採樣率: + + Output Clip: + 輸出壓限: - Stereo difference: - 雙聲道差異: + + Rate Enabled + - Levels: - 級別: + + Enable samplerate-crushing + - NOISE - + + Depth Enabled + 深度已啓用 + + Enable bitdepth-crushing + + + + FREQ 頻率 + + Sample rate: + 採樣率: + + + STEREO - + + + Stereo difference: + 雙聲道差異: + + + QUANT - + - Input gain: - 輸入增益: - - - Input noise: - - - - Output gain: - 輸出增益: - - - Output clip: - - - - Rate enabled - - - - Enable sample-rate crushing - - - - Depth enabled - - - - Enable bit-depth crushing - + + Levels: + 級別: - BitcrushControls + CaptionMenu - Input gain - 輸入增益 + + &Help + 幫助(&H) - Input noise - - - - Output gain - 輸出增益 - - - Output clip - - - - Sample rate - - - - Stereo difference - - - - Levels - - - - Rate enabled - - - - Depth enabled - + + Help (not available) + 幫助(不可用) CarlaInstrumentView + Show GUI 顯示圖形界面 + + + Click here to show or hide the graphical user interface (GUI) of Carla. + 點擊此處可以顯示或隱藏 Carla 的圖形界面。 + + + + Controller + + + Controller %1 + 控制器%1 + + + + ControllerConnectionDialog + + + Connection Settings + 連接設置 + + + + MIDI CONTROLLER + MIDI控制器 + + + + Input channel + 輸入通道 + + + + CHANNEL + 通道 + + + + Input controller + 輸入控制器 + + + + CONTROLLER + 控制器 + + + + + Auto Detect + 自動檢測 + + + + MIDI-devices to receive MIDI-events from + 用來接收 MIDI 事件的MIDI 設備 + + + + USER CONTROLLER + 用戶控制器 + + + + MAPPING FUNCTION + 映射函數 + + + + OK + 確定 + + + + Cancel + 取消 + + + + LMMS + LMMS + + + + Cycle Detected. + 檢測到環路。 + + + + ControllerRackView + + + Controller Rack + 控制器機架 + + + + Add + 增加 + + + + Confirm Delete + 刪除前確認 + + + + Confirm delete? There are existing connection(s) associated with this controller. There is no way to undo. + 確定要刪除嗎?此控制器仍處於被連接狀態。此操作不可撤銷。 + + + + ControllerView + + + Controls + 控制器 + + + + Controllers are able to automate the value of a knob, slider, and other controls. + 控制器可以自動控制旋鈕,滑塊和其他控件的值。 + + + + Rename controller + 重命名控制器 + + + + Enter the new name for this controller + 輸入這個控制器的新名稱 + + + + LFO + + + + + &Remove this controller + + + + + Re&name this controller + + 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 - + + Band 1 Gain: + - Band 1 gain: - + + Band 2 Gain: + - Band 2 gain - + + Band 3 Gain: + - Band 2 gain: - + + Band 4 Gain: + - Band 3 gain - + + Band 1 Mute + - Band 3 gain: - + + Mute Band 1 + - Band 4 gain - + + Band 2 Mute + - Band 4 gain: - + + Mute Band 2 + - Band 1 mute - + + Band 3 Mute + - Mute band 1 - + + Mute Band 3 + - Band 2 mute - + + Band 4 Mute + - Mute band 2 - - - - Band 3 mute - - - - Mute band 3 - - - - Band 4 mute - - - - Mute band 4 - + + Mute Band 4 + DelayControls - Feedback - + + Delay Samples + + + Feedback + + + + + Lfo Frequency + + + + + Lfo Amount + + + + Output gain 輸出增益 - - Delay samples - - - - LFO frequency - - - - LFO amount - - DelayControlsDialog + + DELAY + + + + + Delay Time + 延遲時間 + + + + FDBK + + + + + Feedback Amount + + + + + RATE + + + + + Lfo + + + + + AMNT + + + + + Lfo Amt + + + + + Out Gain + + + + Gain 增益 - - DELAY - - - - FDBK - - - - RATE - - - - AMNT - - - - Delay time - - - - Feedback amount - - - - LFO frequency - - - - LFO amount - - - - Out gain - - DualFilterControlDialog - Filter 1 enabled - 已啓用過濾器 1 - - - Filter 2 enabled - 已啓用過濾器 2 - - + + FREQ 頻率 + + Cutoff frequency 切除頻率 + + RESO - + + + Resonance 共鳴 + + GAIN 增益 + + Gain 增益 + MIX - + + Mix 混合 - Enable/disable filter 1 - + + Filter 1 enabled + 已啓用過濾器 1 - Enable/disable filter 2 - + + Filter 2 enabled + 已啓用過濾器 2 + + + + Click to enable/disable Filter 1 + 點擊啓用/禁用過濾器 1 + + + + Click to enable/disable Filter 2 + 點擊啓用/禁用過濾器 2 DualFilterControls + Filter 1 enabled 過濾器1 已啓用 + Filter 1 type 過濾器 1 類型 + + Cutoff 1 frequency + 濾波器 1 截頻 + + + Q/Resonance 1 濾波器 1 Q值 + Gain 1 增益 1 + Mix 混合 + Filter 2 enabled 已啓用過濾器 2 + Filter 2 type 過濾器 1 類型 {2 ?} + + Cutoff 2 frequency + 濾波器 2 截頻 + + + Q/Resonance 2 濾波器 2 Q值 + Gain 2 增益 2 + + + LowPass + 低通 + + + + + HiPass + 高通 + + + + + BandPass csg + 帶通 csg + + + + + BandPass czpg + 帶通 czpg + + + + Notch 凹口濾波器 + + + Allpass + 全通 + + + + Moog Moog + + + 2x LowPass + 2 個低通串聯 + + + + + RC LowPass 12dB + RC 低通(12dB) + + + + + RC BandPass 12dB + RC 帶通(12dB) + + + + + RC HighPass 12dB + RC 高通(12dB) + + + + + RC LowPass 24dB + RC 低通(24dB) + + + + + RC BandPass 24dB + RC 帶通(24dB) + + + + + RC HighPass 24dB + RC 高通(24dB) + + + + + Vocal Formant Filter + 人聲移除過濾器 + + + + 2x Moog - + + + + SV LowPass + + + + + + SV BandPass + + + + + + SV HighPass + + + + + SV Notch - + + + Fast Formant - + + + Tripole - + + + + + Editor + + + Transport controls + - Cutoff frequency 1 - + + Play (Space) + 播放(空格) - Cutoff frequency 2 - + + Stop (Space) + 停止(空格) - Low-pass - + + Record + 錄音 - Hi-pass - + + Record while playing + 播放時錄音 + + + + Effect + + + Effect enabled + 啓用效果器 - Band-pass csg - + + Wet/Dry mix + 幹/溼混合 - Band-pass czpg - + + Gate + 門限 - All-pass - + + Decay + 衰減 + + + + EffectChain + + + Effects enabled + 啓用效果器 + + + + EffectRackView + + + EFFECTS CHAIN + 效果器鏈 - 2x Low-pass - + + Add effect + 增加效果器 + + + + EffectSelectDialog + + + Add effect + 增加效果器 - RC Low-pass 12 dB/oct - + + + Name + 名稱 - RC Band-pass 12 dB/oct - + + Type + 類型 - RC High-pass 12 dB/oct - + + Description + 描述 - RC Low-pass 24 dB/oct - + + Author + + + + + EffectView + + + Toggles the effect on or off. + 打開或關閉效果. - RC Band-pass 24 dB/oct - + + On/Off + 開/關 - RC High-pass 24 dB/oct - + + W/D + W/D - Vocal Formant - + + Wet Level: + 效果度: - SV Low-pass - + + The Wet/Dry knob sets the ratio between the input signal and the effect signal that forms the output. + 旋轉幹溼度旋鈕以調整原信號與有效果的信號的比例。 - SV Band-pass - + + DECAY + 衰減 - SV High-pass - + + 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. + 衰減旋鈕控制在插件停止工作前,緩衝區中加入的靜音時常。較小的數值會降低CPU佔用率但是可能導致延遲或混響產生撕裂。 + + + + 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. + +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 + 向上移(&U) + + + + Move &down + 向下移(&D) + + + + &Remove this plugin + 移除此插件(&R) + + + + EnvelopeAndLfoParameters + + + Predelay + 預延遲 + + + + Attack + 打進聲 + + + + Hold + 保持 + + + + Decay + 衰減 + + + + Sustain + 持續 + + + + Release + 釋放 + + + + Modulation + 調製 + + + + LFO Predelay + LFO 預延遲 + + + + LFO Attack + LFO 打進聲(attack) + + + + LFO speed + LFO 速度 + + + + LFO Modulation + LFO 調製 + + + + LFO Wave Shape + LFO 波形形狀 + + + + Freq x 100 + 頻率 x 100 + + + + Modulate Env-Amount + 調製所有包絡 + + + + EnvelopeAndLfoView + + + + DEL + DEL + + + + Predelay: + 預延遲: + + + + 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: + 打進聲: + + + + 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: + 持續: + + + + 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 + 衰減 + + + + 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 + 持續 + + + + 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 + 釋音 + + + + 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 + + + + + + Modulation amount: + 調製量: + + + + 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對此包絡的調製量,較大的值會對此包絡控制的值(如音量或截頻)影響更大。 + + + + LFO predelay: + 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: + + + + + 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 + + + + + LFO speed: + + + + + 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. + 點擊這裡使用正弦波。 + + + + Click here for a triangle-wave. + 點擊這裡使用三角波。 + + + + Click here for a saw-wave for current. + 點擊這裡使用鋸齒波。 + + + + Click here for a square-wave. + 點擊這裡使用方形波。 + + + + Click here for a user-defined wave. Afterwards, drag an according sample-file onto the LFO graph. + 點擊這裡使用自訂波形。之後請把所用波形的樣本檔案拖到LFO Graph上。 + + + + Click here for random wave. + 點擊這裡使用隨機波形。 + + + + FREQ x 100 + 頻率 x 100 + + + + Click here if the frequency of this LFO should be multiplied by 100. + 點擊這裡把這個LFO的頻率乘以100。 + + + + multiply LFO-frequency by 100 + + + + + MODULATE ENV-AMOUNT + + + + + Click here to make the envelope-amount controlled by this LFO. + + + + + control envelope-amount by this LFO + + + + + ms/LFO: + + + + + Hint + 提示 + + + + Drag a sample from somewhere and drop it in this window. + 把樣本檔案拖到這個視窗上放開。 EqControls + Input gain 輸入增益 + Output gain 輸出增益 + + Low shelf gain + + + + Peak 1 gain - + + Peak 2 gain - + + Peak 3 gain - + + Peak 4 gain - + + + High Shelf gain + + + + HP res - + + + Low Shelf res + + + + Peak 1 BW - + + Peak 2 BW - + + Peak 3 BW - + + Peak 4 BW - + + + High Shelf res + + + + LP res - + + HP freq - + + + Low Shelf freq + + + + Peak 1 freq - + + Peak 2 freq - + + Peak 3 freq - + + Peak 4 freq - + + + High shelf freq + + + + LP freq - + + HP active - + + + Low shelf active + + + + Peak 1 active - + + Peak 2 active - + + Peak 3 active - + + Peak 4 active - + + + High shelf active + + + + LP active - + + LP 12 - + + LP 24 - + + LP 48 - + + HP 12 - + + HP 24 - + + HP 48 - + + + low pass type + + + + + high pass type + + + + Analyse IN - + + Analyse OUT - - - - Low-shelf gain - - - - High-shelf gain - - - - Low-shelf res - - - - High-shelf res - - - - Low-shelf freq - - - - High-shelf freq - - - - Low-shelf active - - - - High-shelf active - - - - Low-pass type - - - - High-pass type - + EqControlsDialog + HP - + + + Low Shelf + + + + Peak 1 - + + Peak 2 - + + Peak 3 - + + Peak 4 - + + + High Shelf + + + + LP - + + + In Gain + + + + + + Gain 增益 + + Out Gain + + + + Bandwidth: - + + + Octave + + + + Resonance : - + + Frequency: 頻率: - Octave - + + lp grp + - Low-shelf - - - - High-shelf - - - - Input gain - 輸入增益 - - - Output gain - 輸出增益 - - - LP group - - - - HP group - + + hp grp + EqHandle + Reso: - + + BW: - + + + Freq: - + + + + + ExportProjectDialog + + + Export project + 導出工程 + + + + Output + 輸出 + + + + File format: + 檔案格式: + + + + Samplerate: + 採樣率: + + + + 44100 Hz + 44100 Hz + + + + 48000 Hz + 48000 Hz + + + + 88200 Hz + 88200 Hz + + + + 96000 Hz + 96000 Hz + + + + 192000 Hz + 192000 Hz + + + + Depth: + 位深: + + + + 16 Bit Integer + 16 位整形 + + + + 24 Bit Integer + 24 位元整數 + + + + 32 Bit Float + 32 位浮點型 + + + + Stereo mode: + + + + + Stereo + + + + + Joint Stereo + + + + + Mono + + + + + Bitrate: + 碼率: + + + + 64 KBit/s + 64 KBit/s + + + + 128 KBit/s + 128 KBit/s + + + + 160 KBit/s + 160 KBit/s + + + + 192 KBit/s + 192 KBit/s + + + + 256 KBit/s + 256 KBit/s + + + + 320 KBit/s + 320 KBit/s + + + + Use variable bitrate + 使用可變位元率 + + + + Quality settings + 質量設置 + + + + Interpolation: + 補間: + + + + Zero Order Hold + 零階保持 + + + + Sinc Fastest + 最快 Sinc 補間 + + + + Sinc Medium (recommended) + 中等 Sinc 補間 (推薦) + + + + Sinc Best (very slow!) + 最佳 Sinc 補間 (很慢!) + + + + Oversampling (use with care!): + 過採樣 (請謹慎使用!): + + + + 1x (None) + 1x (無) + + + + 2x + 2x + + + + 4x + 4x + + + + 8x + 8x + + + + Export as loop (remove end silence) + 導出爲迴環loop(移除結尾的靜音) + + + + Export between loop markers + 只導出迴環標記中間的部分 + + + + Start + 開始 + + + + Cancel + 取消 + + + + 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! + 無法開啟 %1 以進行寫入。 +請確認您有權限存取此檔案,以及包含此檔案的目錄後再試一次。 + + + + Export project to %1 + 導出項目到 %1 + + + + Error + 錯誤 + + + + Error while determining file-encoder device. Please try to choose a different output format. + 偵測檔案編碼裝置時發生錯誤。請嘗試使用其他輸出格式。 + + + + Rendering: %1% + 渲染中:%1% + + + Compression level: + + + + (fastest) + + + + (default) + + + + (smallest) + + + + + Expressive + + Selected graph + + + + A1 + + + + A2 + + + + A3 + + + + W1 smoothing + + + + W2 smoothing + + + + W3 smoothing + + + + PAN1 + + + + PAN2 + + + + REL TRANS + + + + + Fader + + + + Please enter a new value between %1 and %2: + 請輸入一個介於%1和%2之間的數值: + + + + FileBrowser + + + Browser + 瀏覽器 + + + Search + + + + Refresh list + + + + + FileBrowserTreeWidget + + + Send to active instrument-track + 發送到活躍的樂器軌道 + + + + Open in new instrument-track/Song Editor + 在新的樂器軌道/歌曲編輯器中打開 + + + + Open in new instrument-track/B+B Editor + 在新樂器軌道/B+B 編輯器中打開 + + + + Loading sample + 加載採樣中 + + + + Please wait, loading sample for preview... + 請稍候,加載採樣中... + + + + Error + 錯誤 + + + + does not appear to be a valid + 並不是一個有效的 + + + + file + 檔案 + + + + --- Factory files --- + --- 內建檔案 --- FlangerControls + + Delay Samples + + + + + Lfo Frequency + + + + Seconds + Regen - + + Noise 噪音 + Invert 反轉 - - Delay samples - - - - LFO frequency - - FlangerControlsDialog + DELAY - + + + Delay Time: + 延遲時間: + + + RATE - + + + Period: + + + + AMNT - + + Amount: - + + FDBK - + + + Feedback Amount: + + + + NOISE - + + + White Noise Amount: + 白噪音數量: + + + Invert 反轉 + + + FxLine - Period: - + + Channel send amount + 通道發送的數量 - Delay time: - + + 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. + + - Feedback amount: - + + Move &left + 向左移(&L) - White noise amount: - + + Move &right + 向右移(&R) + + + + Rename &channel + 重命名通道(&C) + + + + R&emove channel + 刪除通道(&E) + + + + Remove &unused channels + 移除所有未用通道(&U) - FreeBoyInstrument + FxMixer - Sweep time - + + Master + 主控 - Sweep direction - + + + + FX %1 + FX %1 - Channel 1 volume - + + Volume + 音量 - Volume sweep direction - + + Mute + 靜音 - Length of each step in sweep - - - - Channel 2 volume - - - - Channel 3 volume - - - - Channel 4 volume - - - - Channel 1 to SO2 (Left) - - - - Channel 2 to SO2 (Left) - - - - Channel 3 to SO2 (Left) - - - - Channel 4 to SO2 (Left) - - - - Channel 1 to SO1 (Right) - - - - Channel 2 to SO1 (Right) - - - - Channel 3 to SO1 (Right) - - - - Channel 4 to SO1 (Right) - - - - Treble - - - - Bass - 低音 - - - Shift Register width - - - - Sweep rate shift amount - - - - Wave pattern duty cycle - - - - Right output level - - - - Left output level - + + Solo + 獨奏 - FreeBoyInstrumentView + FxMixerView - Length of each step in sweep: - + + FX-Mixer + 效果混合器 - Length of each step in sweep - + + FX Fader %1 + FX 衰減器 %1 - Treble: - + + Mute + 靜音 - Treble - + + Mute this FX channel + 靜音此效果通道 - Bass: - + + Solo + 獨奏 - Bass - 低音 + + Solo FX channel + 獨奏效果通道 + + + FxRoute - Sweep time: - - - - Sweep time - - - - Sweep rate shift amount: - - - - Sweep rate shift amount - - - - Wave pattern duty cycle: - - - - Wave pattern duty cycle - - - - Square channel 1 volume: - - - - Square channel 1 volume - - - - Square channel 2 volume: - - - - Square channel 2 volume - - - - Wave pattern channel volume: - - - - Wave pattern channel volume - - - - Noise channel volume: - - - - Noise channel volume - - - - SO1 volume (Right): - - - - SO1 volume (Right) - - - - SO2 volume (Left): - - - - SO2 volume (Left) - - - - Sweep direction - - - - Volume sweep direction - - - - Shift register width - - - - Channel 1 to SO1 (Right) - - - - Channel 2 to SO1 (Right) - - - - Channel 3 to SO1 (Right) - - - - Channel 4 to SO1 (Right) - - - - Channel 1 to SO2 (Left) - - - - Channel 2 to SO2 (Left) - - - - Channel 3 to SO2 (Left) - - - - Channel 4 to SO2 (Left) - - - - Wave pattern graph - + + + Amount to send from channel %1 to channel %2 + 從通道 %1 發送到通道 %2 的量 GigInstrument + Bank + Patch 音色 + Gain 增益 @@ -1194,1125 +2965,3760 @@ GigInstrumentView + + Open other GIG file + 打開另外的 GIG 文件 + + + + Click here to open another GIG file + 點擊這裏打開另外一個 GIG 文件 + + + + Choose the patch + 選擇路徑 + + + + Click here to change which patch of the GIG file to use + 點擊這裏選擇另一種 GIG 音色 + + + + + Change which instrument of the GIG file is being played + 更換正在使用的 GIG 文件中的樂器 + + + + Which GIG file is currently being used + 哪一個 GIG 文件正在被使用 + + + + Which patch of the GIG file is currently being used + GIG 文件的哪一個音色正在被使用 + + + + Gain + 增益 + + + + Factor to multiply samples by + + + + Open GIG file - 打開 GIG 文件 + 開啟 GIG 檔案 + GIG Files (*.gig) - GIG 文件 (*.gig) + GIG 檔案 (*.gig) + + + + GuiApplication + + + Working directory + 工作目錄 - Choose patch - + + The LMMS working directory %1 does not exist. Create it now? You can change the directory later via Edit -> Settings. + LMMS工作目錄%1不存在,現在新建一個嗎?你可以稍後在 編輯 -> 設置 中更改此設置。 - Gain: - 增益: + + Preparing UI + 正在準備界面 + + + + Preparing song editor + 正在準備歌曲編輯器 + + + + Preparing mixer + 正在準備混音器 + + + + Preparing controller rack + 正在準備控制機架 + + + + Preparing project notes + 正在準備專案音符 + + + + Preparing beat/bassline editor + 正在準備節拍/低音線編輯器 + + + + Preparing piano roll + 正在準備鋼琴捲簾 + + + + Preparing automation editor + 正在準備自動化控制編輯器 + + + + InstrumentFunctionArpeggio + + + Arpeggio + + + + + Arpeggio type + + + + + Arpeggio range + + + + + Cycle steps + + + + + Skip rate + + + + + Miss rate + + + + + Arpeggio time + + + + + Arpeggio gate + + + + + Arpeggio direction + + + + + Arpeggio mode + + + + + Up + 向上 + + + + Down + 向下 + + + + Up and down + 上和下 + + + + Down and up + 下和上 + + + + Random + 隨機 + + + + Free + 自由 + + + + Sort + 排序 + + + + Sync + 同步 + + + + InstrumentFunctionArpeggioView + + + 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 + 範圍 + + + + Arpeggio range: + + + + + octave(s) + + + + + Use this knob for setting the arpeggio range in octaves. The selected arpeggio will be played within specified number of octaves. + + + + + CYCLE + + + + + Cycle notes: + + + + + note(s) + + + + + 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 + + + + + Skip rate: + + + + + + + % + % + + + + 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 + 時長 + + + + Arpeggio time: + + + + + ms + 毫秒 + + + + Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. + + + + + GATE + 門限 + + + + 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: + 和絃: + + + + Direction: + 方向: + + + + Mode: + 模式: + + + + InstrumentFunctionNoteStacking + + + octave + octave + + + + + Major + Major + + + + Majb5 + Majb5 + + + + 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 + Maj7 + + + + Maj7b5 + Maj7b5 + + + + Maj7#5 + Maj7#5 + + + + Maj7#11 + Maj7#11 + + + + Maj7add13 + Maj7add13 + + + + m7 + m7 + + + + m7b5 + m7b5 + + + + m7b9 + m7b9 + + + + m7add11 + m7add11 + + + + m7add13 + m7add13 + + + + m-Maj7 + m-Maj7 + + + + m-Maj7add11 + m-Maj7add11 + + + + m-Maj7add13 + m-Maj7add13 + + + + 9 + 9 + + + + 9sus4 + 9sus4 + + + + add9 + add9 + + + + 9#5 + 9#5 + + + + 9b5 + 9b5 + + + + 9#11 + 9#11 + + + + 9b13 + 9b13 + + + + Maj9 + Maj9 + + + + Maj9sus4 + Maj9sus4 + + + + Maj9#5 + Maj9#5 + + + + Maj9#11 + Maj9#11 + + + + m9 + m9 + + + + madd9 + madd9 + + + + m9b5 + m9b5 + + + + m9-Maj7 + m9-Maj7 + + + + 11 + 11 + + + + 11b9 + 11b9 + + + + Maj11 + Maj11 + + + + m11 + m11 + + + + m-Maj11 + m-Maj11 + + + + 13 + 13 + + + + 13#9 + 13#9 + + + + 13b9 + 13b9 + + + + 13b5b9 + 13b5b9 + + + + Maj13 + Maj13 + + + + m13 + m13 + + + + m-Maj13 + m-Maj13 + + + + Harmonic minor + Harmonic minor + + + + Melodic minor + Melodic minor + + + + Whole tone + + + + + Diminished + Diminished + + + + Major pentatonic + Major pentatonic + + + + Minor pentatonic + Minor pentatonic + + + + Jap in sen + Jap in sen + + + + Major bebop + Major bebop + + + + Dominant bebop + Dominant 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 + + + + + 5 + 5 + + + + Phrygian dominant + + + + + Persian + + + + + Chords + Chords + + + + Chord type + Chord type + + + + Chord range + Chord range + + + + InstrumentFunctionNoteStackingView + + + STACKING + 堆疊 + + + + Chord: + 和絃: + + + + RANGE + 範圍 + + + + Chord range: + 和絃範圍: + + + + octave(s) + + + + + 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 + 啓用MIDI輸入 + + + + + CHANNEL + 通道 + + + + + VELOCITY + 力度 + + + + ENABLE MIDI OUTPUT + 啓用MIDI輸出 + + + + PROGRAM + 樂器 + + + + NOTE + 音符 + + + + MIDI devices to receive MIDI events from + 用於接收 MIDI 事件的 MIDI 設備 + + + + MIDI devices to send MIDI events to + 用於發送 MIDI 事件的 MIDI 設備 + + + + CUSTOM BASE VELOCITY + 自定義基準力度 + + + + Specify the velocity normalization base for MIDI-based instruments at 100% note velocity + + + + + BASE VELOCITY + 基準力度 + + + + InstrumentMiscView + + + MASTER PITCH + 主音高 + + + + Enables the use of Master Pitch + 啓用主音高 + + + + InstrumentSoundShaping + + + VOLUME + 音量 + + + + Volume + 音量 + + + + CUTOFF + 切除 + + + + + Cutoff frequency + 切除頻率 + + + + RESO + + + + + Resonance + 共鳴 + + + + Envelopes/LFOs + 壓限/低頻振盪 + + + + Filter type + 過濾器類型 + + + + Q/Resonance + + + + + LowPass + 低通 + + + + HiPass + 高通 + + + + BandPass csg + 帶通 csg + + + + BandPass czpg + 帶通 czpg + + + + Notch + 凹口濾波器 + + + + Allpass + 全通 + + + + Moog + Moog + + + + 2x LowPass + 2 個低通串聯 + + + + RC LowPass 12dB + RC 低通(12dB) + + + + RC BandPass 12dB + RC 帶通(12dB) + + + + RC HighPass 12dB + RC 高通(12dB) + + + + RC LowPass 24dB + RC 低通(24dB) + + + + RC BandPass 24dB + RC 帶通(24dB) + + + + RC HighPass 24dB + RC 高通(24dB) + + + + Vocal Formant Filter + 人聲移除過濾器 + + + + 2x Moog + + + + + SV LowPass + + + + + SV BandPass + + + + + SV HighPass + + + + + SV Notch + + + + + Fast Formant + + + + + Tripole + + + + + InstrumentSoundShapingView + + + TARGET + 目標 + + + + 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 + + + + + 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 + 頻率 + + + + cutoff frequency: + + + + + 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 + + + + + Resonance: + 共鳴: + + + + 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. + 包絡和低頻振盪 (LFO) 不被當前樂器支持。 InstrumentTrack + + With this knob you can set the volume of the opened channel. + 使用此旋鈕可以設置開放通道的音量。 + + + + + unnamed_track + 未命名軌道 + + + + Base note + 基本音 + + + + Volume + 音量 + + + + Panning + 聲相 + + + + Pitch + 音高 + + + + Pitch range + 音域範圍 + + + + FX channel + 效果通道 + + + + Master Pitch + 主音高 + + + + Default preset 預置 + + InstrumentTrackView + + + Volume + 音量 + + + + Volume: + 音量: + + + + VOL + VOL + + + + Panning + 聲相 + + + + Panning: + 聲相: + + + + PAN + PAN + + + + MIDI + MIDI + + + + Input + 輸入 + + + + Output + 輸出 + + + + FX %1: %2 + 效果 %1: %2 + + + + InstrumentTrackWindow + + + GENERAL SETTINGS + 常規設置 + + + + Use these controls to view and edit the next/previous track in the song editor. + 使用這些控制選項來查看和編輯在歌曲編輯器中的上個/下個軌道。 + + + + Instrument volume + 樂器音量 + + + + Volume: + 音量: + + + + VOL + VOL + + + + Panning + 聲相 + + + + Panning: + 聲相: + + + + PAN + PAN + + + + Pitch + 音高 + + + + Pitch: + 音高: + + + + cents + 音分 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 + MIDI設置 + + + + Miscellaneous + + + + + Save preset + 保存預置 + + + + XML preset file (*.xpf) + XML 預設集檔案 (*.xpf) + + + + Plugin + + + + + 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: + 請輸入一個介於%1和%2之間的數值: + + + + LadspaControl + + + Link channels + 關聯通道 + + LadspaControlDialog + Link Channels 連接通道 + Channel 通道 + + LadspaControlView + + + Link channels + 連接通道 + + + + Value: + 值: + + + + Sorry, no help available. + 啊哦,這個沒有幫助文檔。 + + LadspaEffect + Unknown LADSPA plugin %1 requested. 已請求未知 LADSPA 插件 %1. + + LcdSpinBox + + + Please enter a new value between %1 and %2: + 請輸入一個介於%1和%2之間的數值: + + + + LeftRightNav + + + + + Previous + 上個 + + + + + + Next + 下個 + + + + Previous (%1) + 上 (%1) + + + + Next (%1) + 下 (%1) + + + + LfoController + + + LFO Controller + LFO 控制器 + + + + Base value + 基準值 + + + + Oscillator speed + 振動速度 + + + + Oscillator amount + + + + + Oscillator phase + + + + + Oscillator waveform + 振動波形 + + + + Frequency Multiplier + + + + + LfoControllerDialog + + + LFO + + + + + LFO Controller + LFO 控制器 + + + + BASE + 基準 + + + + Base amount: + 基礎值: + + + + todo + + + + + SPD + + + + + LFO-speed: + + + + + Use this knob for setting speed of the LFO. The bigger this value the faster the LFO oscillates and the faster the effect. + + + + + AMNT + + + + + Modulation amount: + 調製量: + + + + 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 + + + + + Phase offset: + + + + + degrees + + + + + 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. + 點擊這裡使用正弦波。 + + + + Click here for a triangle-wave. + 點擊這裡使用三角波。 + + + + Click here for a saw-wave. + + + + + Click here for a square-wave. + 點擊這裡使用方形波。 + + + + Click here for a moog saw-wave. + + + + + Click here for an exponential wave. + + + + + Click here for white-noise. + + + + + Click here for a user-defined shape. +Double click to pick a file. + + + + + LmmsCore + + + Generating wavetables + 正在生成波形表 + + + + Initializing data structures + 正在初始化數據結構 + + + + Opening audio and midi devices + 正在啓動音頻和 MIDI 設備 + + + + Launching mixer threads + 生在啓動混音器線程 + + + + MainWindow + + + Configuration file + 設定檔 + + + + Error while parsing configuration file at line %1:%2: %3 + 解析設定檔時發生錯誤(行 %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! + 無法開啟 %1 以進行寫入。 +請確認您有權限存取此檔案,以及包含此檔案的目錄後再試一次。 + + + + 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? + 發現復原檔案。可能是上一個工作階段未正常結束,或者另一個 LMMS 已在執行。您想要復原這個專案嗎? + + + + + + Recover + 恢復 + + + + Recover the file. Please don't run multiple instances of LMMS when you do this. + 復原檔案。請不要在復原檔案時同時開啟多個 LMMS 視窗。 + + + + + + Discard + 丟棄 + + + + Launch a default session and delete the restored files. This is not reversible. + 開啟新的預設工作階段並刪除已復原的檔案。此操作無法復原。 + + + + Version %1 + 版本 %1 + + + + Preparing plugin browser + 正在準備插件瀏覽器 + + + + Preparing file browsers + 正在準備檔案瀏覽器 + + + + My Projects + 我的工程 + + + + My Samples + 我的採樣 + + + + My Presets + 我的預設 + + + + My Home + 我的主目錄 + + + + Root directory + 根目錄 + + + + Volumes + 音量 + + + + My Computer + 我的電腦 + + + + Loading background artwork + 正在加載背景圖案 + + + + &File + 檔案(&F) + + + + &New + 新建(&N) + + + + New from template + 從模版新建工程 + + + + &Open... + 打開(&O)... + + + + &Recently Opened Projects + 最近打開的工程(&R) + + + + &Save + 保存(&S) + + + + Save &As... + 另存爲(&A)... + + + + Save as New &Version + 保存爲新版本(&V) + + + + Save as default template + 保存爲默認模板 + + + + Import... + 導入... + + + + E&xport... + 導出(&E)... + + + + E&xport Tracks... + 導出音軌(&X)... + + + + Export &MIDI... + 導出 MIDI (&M)... + + + + &Quit + 退出(&Q) + + + + &Edit + 編輯(&E) + + + + Undo + 撤銷 + + + + Redo + 重做 + + + + Settings + 設置 + + + + &View + 視圖 (&V) + + + + &Tools + 工具(&T) + + + + &Help + 幫助(&H) + + + + Online Help + 在線幫助 + + + + Help + 幫助 + + + + What's This? + 這是什麼? + + + + About + 關於 + + + + Create new project + 新建工程 + + + + Create new project from template + 從模版新建工程 + + + + Open existing project + 打開已有工程 + + + + Recently opened projects + 最近打開的工程 + + + + Save current project + 保存當前工程 + + + + Export current project + 導出當前工程 + + + + What's this? + 這是什麼? + + + + Toggle metronome + 開啓/關閉節拍器 + + + + Show/hide Song-Editor + 顯示/隱藏歌曲編輯器 + + + + 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. + 點擊這個按鈕, 你可以顯示/隱藏歌曲編輯器。在歌曲編輯器的幫助下, 你可以編輯歌曲播放列表並且設置哪個音軌在哪個時間播放。你還可以在播放列表中直接插入和移動採樣(如 RAP 採樣)。 + + + + Show/hide Beat+Bassline Editor + 顯示/隱藏節拍+旋律編輯器 + + + + 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 + 顯示/隱藏鋼琴窗 + + + + Click here to show or hide the Piano-Roll. With the help of the Piano-Roll you can edit melodies in an easy way. + 點擊這裏顯示或隱藏鋼琴窗。在鋼琴窗的幫助下, 你可以很容易地編輯旋律。 + + + + Show/hide Automation Editor + 顯示/隱藏自動控制編輯器 + + + + 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 + 顯示/隱藏混音器 + + + + 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. + 點擊這裏顯示或隱藏 FX 混音器。FX 混音器是管理你歌曲中不同音效的強大工具。你可以向不同的通道添加不同的效果。 + + + + Show/hide project notes + 顯示/隱藏工程註釋 + + + + Click here to show or hide the project notes window. In this window you can put down your project notes. + 點擊這裏顯示或隱藏工程註釋窗。在此窗口中你可以寫下工程的註釋。 + + + + Show/hide controller rack + 顯示/隱藏控制器機架 + + + + Untitled + 未命名 + + + + Recover session. Please save your work! + 恢復會話。請保存你的工作! + + + + LMMS %1 + 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) + LMMS (*.mmp *.mmpz) + + + + Save Project + 保存工程 + + + + LMMS Project + LMMS 工程 + + + + LMMS Project Template + LMMS 工程模板 + + + + 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. + LMMS現在沒有可用的幫助 +請訪問 http://lmms.sf.net/wiki 瞭解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 + 在鋼琴窗中顯示音號 + + + + MeterDialog + + + + Meter Numerator + + + + + + Meter Denominator + + + + + TIME SIG + 拍子記號 + + + + MeterModel + + + Numerator + + + + + Denominator + + + + + MidiController + + + MIDI Controller + MIDI控制器 + + + + unnamed_midi_controller + + + MidiImport + + Setup incomplete 設置不完整 - 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. - 你在編譯 LMMS 時沒有加入 SoundFont2 播放器支持, 此播放器默認用於添加導入的 MIDI 文件。因此在 MIDI 文件導入後, 將沒有聲音。 + + 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. + 你還沒有在設置(在編輯->設置)中設置默認的 Soundfont。因此在導入此 MIDI 文件後將會沒有聲音。你需要下載一個通用 MIDI (GM) 的 Soundfont, 並且在設置對話框中選中後再試一次。 + + 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. + 您在編譯 LMMS 時未一併啟用 SoundFont2 播放器支援,此播放器用於為匯入的 MIDI 檔案加入預設聲音,因此在匯入此 MIDI 檔後不會有聲音。 + + + Track 軌道 + + + MidiJack - You have not 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. - + + JACK server down + When JACK(JACK Audio Connection Kit) disconnects, it will show the following message (title) + JACK服務崩潰 + + + + 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 + 輸入通道 + + + + Output channel + 輸出通道 + + + + Input controller + 輸入控制器 + + + + Output controller + 輸出控制器 + + + + Fixed input velocity + + + + + Fixed output velocity + + + + + Fixed output note + + + + + Output MIDI program + + + + + Base velocity + 基準力度 + + + + Receive MIDI-events + 接受 MIDI 事件 + + + + Send MIDI-events + 發送 MIDI 事件 + + + + MidiSetupWidget + + + DEVICE + 設備 MonstroInstrument + + Osc 1 Volume + + + + + Osc 1 Panning + + + + + 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 + + + + + Osc 2 Panning + + + + + 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 + + + + + Osc 3 Panning + + + + + 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 + + + + + LFO 1 Attack + + + + + LFO 1 Rate + + + + + LFO 1 Phase + + + + + LFO 2 Waveform + + + + + LFO 2 Attack + + + + + LFO 2 Rate + + + + + LFO 2 Phase + + + + + Env 1 Pre-delay + + + + + Env 1 Attack + + + + + 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 - + + + Vol1-Env1 + + + + + Vol1-Env2 + + + + + Vol1-LFO1 + + + + + Vol1-LFO2 + + + + + Vol2-Env1 + + + + + Vol2-Env2 + + + + + Vol2-LFO1 + + + + + Vol2-LFO2 + + + + + Vol3-Env1 + + + + + Vol3-Env2 + + + + + Vol3-LFO1 + + + + + Vol3-LFO2 + + + + + Phs1-Env1 + + + + + Phs1-Env2 + + + + + Phs1-LFO1 + + + + + Phs1-LFO2 + + + + + Phs2-Env1 + + + + + Phs2-Env2 + + + + + Phs2-LFO1 + + + + + Phs2-LFO2 + + + + + Phs3-Env1 + + + + + Phs3-Env2 + + + + + Phs3-LFO1 + + + + + Phs3-LFO2 + + + + + Pit1-Env1 + + + + + Pit1-Env2 + + + + + Pit1-LFO1 + + + + + Pit1-LFO2 + + + + + Pit2-Env1 + + + + + Pit2-Env2 + + + + + Pit2-LFO1 + + + + + Pit2-LFO2 + + + + + Pit3-Env1 + + + + + Pit3-Env2 + + + + + Pit3-LFO1 + + + + + Pit3-LFO2 + + + + + PW1-Env1 + + + + + PW1-Env2 + + + + + PW1-LFO1 + + + + + PW1-LFO2 + + + + + Sub3-Env1 + + + + + Sub3-Env2 + + + + + Sub3-LFO1 + + + + + Sub3-LFO2 + + + + + Sine wave 正弦波 + Bandlimited Triangle wave - + + Bandlimited Saw wave - + + Bandlimited Ramp wave - + + Bandlimited Square wave - + + Bandlimited Moog saw wave - + + + Soft square wave - + + Absolute sine wave - + + + Exponential wave - + + White noise - + + Digital Triangle wave - + + Digital Saw wave - + + Digital Ramp wave - + + Digital Square wave - + + Digital Moog saw wave - + + Triangle wave 三角波 + Saw wave 鋸齒波 + Ramp wave - + + Square wave 方波 + Moog saw wave - + + Abs. sine wave - + + Random 隨機 + Random smooth - - - - Osc 1 volume - - - - Osc 1 panning - - - - 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 - - - - Osc 2 panning - - - - 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 - - - - Osc 3 panning - - - - Osc 3 coarse detune - - - - Osc 3 sub-oscillator mix - - - - Osc 3 waveform 1 - - - - Osc 3 waveform 2 - - - - Osc 3 sync hard - - - - Osc 3 Sync reverse - - - - LFO 1 waveform - - - - LFO 1 attack - - - - LFO 1 rate - - - - LFO 1 phase - - - - LFO 2 waveform - - - - LFO 2 attack - - - - LFO 2 rate - - - - LFO 2 phase - - - - Env 1 pre-delay - - - - Env 1 attack - - - - 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 - - - - Osc 2+3 modulation - - - - Osc 1 - Vol env 1 - - - - Osc 1 - Vol env 2 - - - - Osc 1 - Vol LFO 1 - - - - Osc 1 - Vol LFO 2 - - - - Osc 2 - Vol env 1 - - - - Osc 2 - Vol env 2 - - - - Osc 2 - Vol LFO 1 - - - - Osc 2 - Vol LFO 2 - - - - Osc 3 - Vol env 1 - - - - Osc 3 - Vol env 2 - - - - Osc 3 - Vol LFO 1 - - - - Osc 3 - Vol LFO 2 - - - - Osc 1 - Phs env 1 - - - - Osc 1 - Phs env 2 - - - - Osc 1 - Phs LFO 1 - - - - Osc 1 - Phs LFO 2 - - - - Osc 2 - Phs env 1 - - - - Osc 2 - Phs env 2 - - - - Osc 2 - Phs LFO 1 - - - - Osc 2 - Phs LFO 2 - - - - Osc 3 - Phs env 1 - - - - Osc 3 - Phs env 2 - - - - Osc 3 - Phs LFO 1 - - - - Osc 3 - Phs LFO 2 - - - - Osc 1 - Pit env 1 - - - - Osc 1 - Pit env 2 - - - - Osc 1 - Pit LFO 1 - - - - Osc 1 - Pit LFO 2 - - - - Osc 2 - Pit env 1 - - - - Osc 2 - Pit env 2 - - - - Osc 2 - Pit LFO 1 - - - - Osc 2 - Pit LFO 2 - - - - Osc 3 - Pit env 1 - - - - Osc 3 - Pit env 2 - - - - Osc 3 - Pit LFO 1 - - - - Osc 3 - Pit LFO 2 - - - - Osc 1 - PW env 1 - - - - Osc 1 - PW env 2 - - - - Osc 1 - PW LFO 1 - - - - Osc 1 - PW LFO 2 - - - - Osc 3 - Sub env 1 - - - - Osc 3 - Sub env 2 - - - - Osc 3 - Sub LFO 1 - - - - Osc 3 - Sub LFO 2 - + MonstroView + Operators view - + + + 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 矩陣視圖 + + 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 音量 + + + Panning 聲相 + + + Coarse detune - + + + + semitones 半音 + + + Finetune left + + + + + + + cents - + + + + 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 打進聲 + + Rate - + + + Phase - + + + Pre-delay - + + + Hold 保持 + + Decay 衰減 + + Sustain 持續 + + 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. + + + + + 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 調製量 - - Fine tune left - - - - Fine tune right - - - - Mix osc 2 with osc 3 - - - - Modulate amplitude of osc 3 by osc 2 - - - - Modulate frequency of osc 3 by osc 2 - - - - Modulate phase of osc 3 by osc 2 - - MultitapEchoControlDialog + Length 長度 + Step length: 步進長度: + Dry 幹聲 + + Dry Gain: + 幹聲增益: + + + Stages - + + + Lowpass stages: + + + + Swap inputs - + - Dry gain: - - - - Low-pass stages: - - - - Swap left and right input channels for reflections - + + Swap left and right input channel for reflections + NesInstrument + + Channel 1 Coarse detune + + + + + Channel 1 Volume + + + + + Channel 1 Envelope length + + + + + Channel 1 Duty cycle + + + + + Channel 1 Sweep amount + + + + + Channel 1 Sweep rate + + + + Channel 2 Coarse detune - + + Channel 2 Volume - + + + Channel 2 Envelope length + + + + + Channel 2 Duty cycle + + + + + Channel 2 Sweep amount + + + + + Channel 2 Sweep rate + + + + + Channel 3 Coarse detune + + + + + Channel 3 Volume + + + + + Channel 4 Volume + + + + + Channel 4 Envelope length + + + + + Channel 4 Noise frequency + + + + + Channel 4 Noise frequency sweep + + + + Master volume 主音量 + Vibrato - - - - Channel 1 coarse detune - - - - Channel 1 volume - - - - Channel 1 envelope length - - - - Channel 1 duty cycle - - - - Channel 1 sweep amount - - - - Channel 1 sweep rate - - - - Channel 2 envelope length - - - - Channel 2 duty cycle - - - - Channel 2 sweep amount - - - - Channel 2 sweep rate - - - - Channel 3 coarse detune - - - - Channel 3 volume - - - - Channel 4 volume - - - - Channel 4 envelope length - - - - Channel 4 noise frequency - - - - Channel 4 noise frequency sweep - + NesInstrumentView + + + + Volume 音量 + + + Coarse detune - + + + + Envelope length - + + Enable channel 1 - + + Enable envelope 1 - + + Enable envelope 1 loop - + + Enable sweep 1 - + + + Sweep amount - + + + Sweep rate - + + + 12.5% Duty cycle - + + + 25% Duty cycle - + + + 50% Duty cycle - + + + 75% Duty cycle - + + Enable channel 2 - + + Enable envelope 2 - + + Enable envelope 2 loop - + + Enable sweep 2 - + + Enable channel 3 - + + Noise Frequency - + + Frequency sweep - + + Enable channel 4 - + + Enable envelope 4 - + + Enable envelope 4 loop - + + Quantize noise frequency when using note frequency - + + Use note frequency for noise - + + Noise mode - + + + Master Volume + 主音量 + + + Vibrato - - - - Master volume - 主音量 - - - - OpulenzInstrument - - Patch - 音色 - - - Op 1 attack - - - - Op 1 decay - - - - Op 1 sustain - - - - Op 1 release - - - - Op 1 level - - - - Op 1 level scaling - - - - Op 1 frequency multiplier - - - - Op 1 feedback - - - - 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 multiplier - - - - Op 2 key scaling rate - - - - Op 2 percussive envelope - - - - Op 2 tremolo - - - - Op 2 vibrato - - - - Op 2 waveform - - - - FM - - - - Vibrato depth - - - - Tremolo depth - - - - - OpulenzInstrumentView - - Attack - 打進聲 - - - Decay - 衰減 - - - Release - 釋放 - - - Frequency multiplier - + OscillatorObject - Osc %1 volume - Osc %1 音量 - - - Osc %1 panning - Osc %1 聲像 - - - Osc %1 coarse detuning - - - - Osc %1 fine detuning left - - - - Osc %1 fine detuning right - - - - Osc %1 phase-offset - - - - Osc %1 stereo phase-detuning - - - - Osc %1 wave shape - - - - Modulation type %1 - - - + Osc %1 waveform Osc %1 波形 + Osc %1 harmonic - + + + + + + Osc %1 volume + Osc %1 音量 + + + + + Osc %1 panning + 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 + + + + + Modulation type %1 + PatchesDialog + Qsynth: Channel Preset Qsynth: 通道預設 + Bank selector 音色選擇器 + Bank + Program selector - + + Patch 音色 + Name 名稱 + OK 確定 + Cancel 取消 @@ -2320,244 +6726,1726 @@ PatmanView + + Open other patch + 打開其他音色 + + + + Click here to open another patch-file. Loop and Tune settings are not reset. + 點擊這裏打開另一個音色文件。循環和調音設置不會被重設。 + + + Loop 循環 + Loop mode 循環模式 + + Here you can toggle the Loop mode. If enabled, PatMan will use the loop information available in the file. + 在這裏你可以開關循環模式。如果啓用,PatMan 會使用文件中的循環信息。 + + + Tune 調音 + Tune mode 調音模式 - No file selected - 未選擇文件 + + Here you can toggle the Tune mode. If enabled, PatMan will tune the sample to match the note's frequency. + 這裏可以開關調音模式。如果啓用,PatMan 會將採樣調成和音符一樣的頻率。 + + No file selected + 未選擇檔案 + + + Open patch file 打開音色文件 + Patch-Files (*.pat) 音色文件 (*.pat) + + + PatternView - Open patch - + + use mouse wheel to set velocity of a step + + + + + double-click to open in Piano Roll + + + + + Open in piano-roll + 在鋼琴窗中打開 + + + + Clear all notes + 清除所有音符 + + + + Reset name + 重置名稱 + + + + Change name + 修改名稱 + + + + Add steps + 添加音階 + + + + Remove steps + 移除音階 + + + + Clone Steps + + + + + PeakController + + + Peak Controller + 峯值控制器 + + + + Peak Controller Bug + 峯值控制器 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. + 由於在舊版 LMMS 中的錯誤,峰值控制器可能並未正確地連線。請確認峰值控制器正確地連線後再次儲存檔案。造成您的不便,深感抱歉。 + + + + PeakControllerDialog + + + PEAK + + + + + LFO Controller + LFO 控制器 PeakControllerEffectControlDialog + BASE 基準 + + Base amount: + 基礎值: + + + + AMNT + + + + Modulation amount: 調製量: - Attack: - 打擊聲: - - - Release: - 釋音: - - - AMNT - - - + MULT - + + + Amount Multiplicator: + + + + ATCK 打擊 + + Attack: + 打擊聲: + + + DCAY - + - Treshold: - + + Release: + 釋音: + TRSH - + - Base: - - - - Amount multiplicator: - - - - Mute output - 輸出靜音 - - - Absolute value - + + Treshold: + PeakControllerEffectControls + Base value 基準值 + Modulation amount 調製量 - Mute output - 輸出靜音 - - + Attack 打進聲 + Release 釋放 + Treshold 閥值 - Absolute value - + + Mute output + 輸出靜音 - Amount multiplicator - + + Abs Value + + + + + Amount Multiplicator + + + + + 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% + 音量:%1% + + + + Panning: %1% left + 聲相:%1% 偏左 + + + + Panning: %1% right + 聲相:%1% 偏右 + + + + Panning: center + 聲相:居中 + + + + Please open a pattern by double-clicking on it! + 雙擊打開片段! + + + + + Please enter a new value between %1 and %2: + 請輸入一個介於 %1 和 %2 的值: + + + + PianoRollWindow + + + Play/pause current pattern (Space) + 播放/暫停當前片段(空格) + + + + Record notes from MIDI-device/channel-piano + 從 MIDI 設備/通道鋼琴(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) + 繪製模式 (Shift+D) + + + + Erase mode (Shift+E) + 擦除模式 (Shift+E) + + + + Select mode (Shift+S) + 選擇模式 (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. + + + + + 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. + 點擊啓用擦除模式。此模式下你可以擦除音符。你可以按鍵盤上的 'Shift+E' 啓用此模式。 + + + + 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 + + + + + Copy paste controls + + + + + Cut selected notes (%1+X) + 剪切選定音符 (%1+X) + + + + Copy selected notes (%1+C) + 複製選定音符 (%1+C) + + + + Paste notes from clipboard (%1+V) + 從剪貼板粘貼音符 (%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 + 鋼琴窗 - %1 + + + + + Piano-Roll - no pattern + 鋼琴窗 - 沒有片段 + + + + PianoView + + + Base note + 基本音 + + + + Plugin + + + Plugin not found + 未找到插件 + + + + The plugin "%1" wasn't found or could not be loaded! +Reason: "%2" + 插件“%1”無法找到或無法載入! +原因:%2 + + + + Error while loading plugin + 載入插件時發生錯誤 + + + + Failed to load plugin "%1"! + 載入插件“%1”失敗! + + + + PluginBrowser + + + Instrument Plugins + + + + + Instrument browser + 樂器瀏覽器 + + + + Drag an instrument into either the Song-Editor, the Beat+Bassline Editor or into an existing instrument track. + 將樂器插件拖入歌曲編輯器, 節拍低音線編輯器, 或者現有的樂器軌道。 + + + + PluginFactory + + + Plugin not found. + 未找到插件。 + + + + LMMS plugin %1 does not have a plugin descriptor named %2! + + + + + ProjectNotes + + + Project Notes + 顯示/隱藏工程註釋 + + + + Enter project notes here + + + + + Edit Actions + 編輯功能 + + + + &Undo + 撤銷(&U) + + + + %1+Z + %1+Z + + + + &Redo + 重做(&R) + + + + %1+Y + %1+Y + + + + &Copy + 複製(&C) + + + + %1+C + %1+C + + + + Cu&t + 剪切(&T) + + + + %1+X + %1+X + + + + &Paste + 粘貼(&P) + + + + %1+V + %1+V + + + + Format Actions + 格式功能 + + + + &Bold + 加粗(&B) + + + + %1+B + %1+B + + + + &Italic + 斜體(&I) + + + + %1+I + %1+I + + + + &Underline + 下劃線(&U) + + + + %1+U + %1+U + + + + &Left + 左對齊(&L) + + + + %1+L + %1+L + + + + C&enter + 居中(&E) + + + + %1+E + %1+E + + + + &Right + 右對齊(&R) + + + + %1+R + %1+R + + + + &Justify + 勻齊(&J) + + + + %1+J + %1+J + + + + &Color... + 顏色(&C)... + + + + ProjectRenderer + + + WAV-File (*.wav) + WAV-文件 (*.wav) + + + + Compressed OGG-File (*.ogg) + 壓縮的 OGG 文件(*.ogg) + + + FLAC-File (*.flac) + + + + + Compressed MP3-File (*.mp3) + QWidget + + + Name: 名稱: + + Maker: 製作者: + + Copyright: 版權: + + Requires Real Time: 要求實時: + + + + + + Yes + + + + + + No + + Real Time Capable: 是否支持實時: + + In Place Broken: - + + + Channels In: 輸入通道: + + Channels Out: 輸出通道: - File: - 文件: + + File: %1 + 檔案:%1 - File: %1 - 文件:%1 + + File: + 檔案: + + + + RenameDialog + + + Rename... + 重命名... ReverbSCControlDialog + Input 輸入 + + Input Gain: + 輸入增益: + + + Size - + + Size: - + + Color - + + Color: - + + Output 輸出 - Input gain: - 輸入增益: - - - Output gain: - 輸出增益: + + Output Gain: + 輸出增益: ReverbSCControls + + Input Gain + + + + Size - + + Color - + - Input gain - 輸入增益 + + Output Gain + + + + + SampleBuffer + + + Fail to open file + 無法開啟檔案 - Output gain - 輸出增益 + + Audio files are limited to %1 MB in size and %2 minutes of playing time + 音訊檔案的檔案大小已限制為 %1 MB,播放時間已限制為 %2 分鐘。 + + + + Open audio file + 開啟音訊檔案 + + + + All Audio-Files (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + 所有音訊檔案 (*.wav *.ogg *.ds *.flac *.spx *.voc *.aif *.aiff *.au *.raw) + + + + Wave-Files (*.wav) + Wave 波形檔案 (*.wav) + + + + OGG-Files (*.ogg) + OGG 檔案 (*.ogg) + + + + DrumSynth-Files (*.ds) + DrumSynth 檔案 (*.ds) + + + + FLAC-Files (*.flac) + FLAC 檔案 (*.flac) + + + + SPEEX-Files (*.spx) + SPEEX 檔案 (*.spx) + + + + VOC-Files (*.voc) + VOC 檔案 (*.voc) + + + + AIFF-Files (*.aif *.aiff) + AIFF 檔案 (*.aif *.aiff) + + + + AU-Files (*.au) + AU 檔案 (*.au) + + + + RAW-Files (*.raw) + RAW 檔案 (*.raw) + + + + SampleTCOView + + + double-click to select sample + 雙擊選擇採樣 + + + + Delete (middle mousebutton) + 刪除 (鼠標中鍵) + + + + Cut + 剪切 + + + + Copy + 複製 + + + + Paste + 粘貼 + + + + Mute/unmute (<%1> + middle click) + 靜音/取消靜音 (<%1> + 鼠標中鍵) + + + + SampleTrack + + + Volume + 音量 + + + + Panning + 聲相 + + + + + Sample track + 採樣軌道 + + + + SampleTrackView + + + Track volume + 軌道音量 + + + + Channel volume: + 通道音量: + + + + VOL + VOL + + + + Panning + 聲相 + + + + Panning: + 聲相: + + + + PAN + PAN + + + + SetupDialog + + + Setup LMMS + 設置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 + 同步 VST 插件和主機回放 + + + + 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 + LMMS工作目錄 + + + + Themes directory + 主題文件目錄 + + + + Background artwork + 背景圖片 + + + + VST-plugin directory + VST插件目錄 + + + + GIG directory + GIG 目錄 + + + + SF2 directory + SF2 目錄 + + + + LADSPA plugin directories + LADSPA 插件目錄 + + + + STK rawwave directory + STK rawwave 目錄 + + + + Default Soundfont File + 預設 SoundFont 檔案 + + + + + Performance settings + 性能設置 + + + + Auto save + 自動保存 + + + + Enable auto-save + + + + + Allow auto-save while playing + + + + + UI effects vs. performance + 界面特效 vs 性能 + + + + Smooth scroll in Song Editor + 歌曲編輯器中啓用平滑滾動 + + + + Show playback cursor in AudioFileProcessor + 在 AudioFileProcessor 中顯示播放指標 + + + + + Audio settings + 音頻設置 + + + + AUDIO INTERFACE + 音頻接口 + + + + + MIDI settings + MIDI設置 + + + + MIDI INTERFACE + MIDI接口 + + + + OK + 確定 + + + + Cancel + 取消 + + + + Restart LMMS + 重啓LMMS + + + + Please note that most changes won't take effect until you restart LMMS! + 請注意很多設置需要重啓LMMS纔可生效! + + + + Frames: %1 +Latency: %2 ms + 幀數: %1 +延遲: %2 毫秒 + + + + 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. + 在這裏,你可以設置 LMMS 所用緩衝區的大小。緩衝區越小,延遲越小,但聲音質量和性能可能會受影響。 + + + + Choose LMMS working directory + 選擇 LMMS 工作目錄 + + + + Choose your GIG directory + 選擇 GIG 目錄 + + + + Choose your SF2 directory + 選擇 SF2 目錄 + + + + Choose your VST-plugin directory + 選擇 VST 插件目錄 + + + + Choose artwork-theme directory + 選擇插圖目錄 + + + + Choose LADSPA plugin directory + 選擇 LADSPA 插件目錄 + + + + Choose STK rawwave directory + 選擇 STK rawwave 目錄 + + + + Choose default SoundFont + 選擇默認的 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. + 在這裏你可以選擇你想要的音頻接口。取決於你的系統和編譯時的設置, 你可以選擇 ALSA, JACK, OSS 等選項。在下面的方框中你可以設置音頻接口的控制項目。 + + + + 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. + 在這裏你可以選擇你想要的 MIDI 接口。取決於你的系統和編譯時的設置, 你可以選擇 ALSA, OSS 等選項。在下面的方框中你可以設置 MIDI 接口的控制項目。 + + + + Song + + + Tempo + 節奏 + + + + Master volume + 主音量 + + + + Master pitch + 主音高 + + + + LMMS Error report + LMMS錯誤報告 + + + + Project saved + 工程已保存 + + + + The project %1 is now saved. + 工程 %1 已保存。 + + + + Project NOT saved. + 工程 **沒有** 保存。 + + + + The project %1 was not saved! + 工程%1沒有保存! + + + + Import file + 匯入檔案 + + + + MIDI sequences + MIDI 音序器 + + + + Hydrogen projects + Hydrogen工程 + + + + 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) + MIDI 檔案 (*.mid) + + + + The following errors occured while loading: + 載入時發生以下錯誤: + + + + 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. + 無法開啟 %1。 +請確認您至少有權限讀取此檔案後再試一次。 + + + + 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. + 無法開啟 %1 以進行寫入。請確認您有權限寫入此檔案後再試一次。 + + + + Error in file + 於檔案中發現錯誤 + + + + The file %1 seems to contain errors and therefore can't be loaded. + 檔案 %1 似乎包含錯誤,無法進行載入。 + + + + Version difference + + + + + This %1 was created with LMMS %2. + + + + + template + + + + + project + + + + + Tempo + 節奏 + + + + TEMPO/BPM + 節奏/BPM + + + + tempo of song + 歌曲的節奏 + + + + 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 + 高質量模式 + + + + + Master volume + 主音量 + + + + master volume + 主音量 + + + + + Master pitch + 主音高 + + + + master pitch + 主音高 + + + + Value: %1% + 值: %1% + + + + Value: %1 semitones + 值: %1 半音程 + + + + SongEditorWindow + + + Song-Editor + 歌曲編輯器 + + + + Play song (Space) + 播放歌曲(空格) + + + + Record samples from Audio-device + 從音頻設備錄製樣本 + + + + Record samples from Audio-device while playing song or BB track + 在播放歌曲或BB軌道時從音頻設備錄入樣本 + + + + Stop song (Space) + 停止歌曲(空格) + + + + 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. + 點擊這裏完整播放歌曲。將從綠色歌曲標記開始播放。在播放的同時可以對它進行移動。 + + + + 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 + 軌道動作 + + + + Add beat/bassline + 添加節拍/Bassline + + + + Add sample-track + 添加採樣軌道 + + + + Add automation-track + 添加自動控制軌道 + + + + Edit actions + 編輯動作 + + + + Draw mode + 繪製模式 + + + + Edit mode (select and move) + 編輯模式(選定和移動) + + + + Timeline controls + 時間線控制 + + + + Zoom controls + 縮放控制 SpectrumAnalyzerControlDialog + Linear spectrum 線性頻譜圖 + Linear Y axis 線性 Y 軸 @@ -2565,862 +8453,1485 @@ SpectrumAnalyzerControls + Linear spectrum 線性頻譜圖 + Linear Y axis 線性 Y 軸 + Channel mode 通道模式 + + SubWindow + + + Close + + + + + Maximize + + + + + Restore + + + + + TabWidget + + + + Settings for %1 + %1 的設定 + + + + TempoSyncKnob + + + + Tempo Sync + + + + + No Sync + 無同步 + + + + Eight beats + + + + + Whole note + + + + + Half note + + + + + Quarter note + + + + + 8th note + + + + + 16th note + + + + + 32nd note + + + + + Custom... + + + + + Custom + + + + + 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 + 點擊改變時間單位 + + + + MIN + + + + + SEC + + + + + MSEC + + + + + BAR + + + + + BEAT + + + + + TICK + + + + + TimeLineWidget + + + Enable/disable auto-scrolling + 啓用/禁用自動滾動 + + + + Enable/disable loop-points + 啓用/禁用循環點 + + + + After stopping go back to begin + 停止後前往開頭 + + + + After stopping go back to position at which playing was started + 停止後前往播放開始的地方 + + + + After stopping keep position + 停止後保持位置不變 + + + + + Hint + 提示 + + + + Press <%1> to disable magnetic loop points. + 按住 <%1> 禁用磁性吸附。 + + + + Hold <Shift> to move the begin loop point; Press <%1> to disable magnetic loop points. + 按住 <Shift> 移動起始循環點;按住 <%1> 禁用磁性吸附。 + + + + Track + + + Mute + 靜音 + + + + Solo + 獨奏 + + TrackContainer + + Couldn't import file + 無法匯入檔案 + + + + Couldn't find a filter for importing file %1. +You should convert this file into a format supported by LMMS using another software. + 不支援 %1 的檔案類型。 +請使用其他軟體將此檔案轉換成 LMMS 支援的格式。 + + + + Couldn't open file + 無法開啟檔案 + + + + 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! + 無法開啟 %1。 +請確認您有權限讀取此檔案,以及包含此檔案的目錄後再試一次。 + + + + Loading project... + 正在加載工程... + + + + Cancel 取消 + + Please wait... 請稍等... + + Loading cancelled + + + + + Project loading was cancelled. + + + + + Loading Track %1 (%2/Total %3) + + + + Importing MIDI-file... - 正在導入 MIDI-文件... + 正在匯入 MIDI 檔案… + + + + TrackContentObject + + + Mute + 靜音 + + + + TrackContentObjectView + + + Current position + 當前位置 + + + + + Hint + 提示 + + + + Press <%1> and drag to make a copy. + 按住 <%1> 並拖動以創建副本。 + + + + Current length + 當前長度 + + + + Press <%1> for free resizing. + 按住 <%1> 自由調整大小。 + + + + + %1:%2 (%3:%4 to %5:%6) + %1:%2 (%3:%4 到 %5:%6) + + + + Delete (middle mousebutton) + 刪除 (鼠標中鍵) + + + + Cut + 剪切 + + + + Copy + 複製 + + + + Paste + 粘貼 + + + + Mute/unmute (<%1> + middle click) + 靜音/取消靜音 (<%1> + 鼠標中鍵) + + + + 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 + 效果 %1: %2 + + + + Assign to new FX Channel + + + + + Turn all recording on + + + + + Turn all recording off + 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 + + + + 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 + + + + Synchronize oscillator 2 with oscillator 3 - + + + Use frequency modulation for modulating oscillator 2 with oscillator 3 + + + + Osc %1 volume: - + + + 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: - + + + 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 - + + + 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 音分 cents + + 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 - + + + 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: - + - Modulate phase of oscillator 1 by oscillator 2 - + + 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. + - Modulate amplitude of oscillator 1 by oscillator 2 - + + Use a sine-wave for current oscillator. + 爲當前振盪器使用正弦波。 - Mix output of oscillators 1 & 2 - + + Use a triangle-wave for current oscillator. + 爲當前振盪器使用三角波。 - Modulate frequency of oscillator 1 by oscillator 2 - + + Use a saw-wave for current oscillator. + 爲當前振盪器使用鋸齒波。 - Modulate phase of oscillator 2 by oscillator 3 - + + Use a square-wave for current oscillator. + 爲當前振盪器使用方波。 - Modulate amplitude of oscillator 2 by oscillator 3 - + + Use a moog-like saw-wave for current oscillator. + - Mix output of oscillators 2 & 3 - + + Use an exponential wave for current oscillator. + - Modulate frequency of oscillator 2 by oscillator 3 - + + Use white-noise for current oscillator. + 爲當前振盪器使用白噪音。 - Sine wave - 正弦波 + + Use a user-defined waveform for current oscillator. + 爲當前振盪器使用用戶自定波形。 + + + + VersionedSaveDialog + + + Increment version number + 遞增版本號 - Triangle wave - 三角波 + + Decrement version number + 遞減版本號 - Saw wave - 鋸齒波 - - - Square wave - 方波 - - - Moog-like saw wave - - - - Exponential wave - - - - White noise - - - - User-defined wave - + + already exists. Do you want to replace it? + VestigeInstrumentView - Show/hide GUI - 顯示/隱藏界面 + + Open other VST-plugin + 打開其他的VST插件 - Turn off all notes - 全部靜音 + + 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. + - DLL-files (*.dll) - DLL-文件 (*.dll) + + Control VST-plugin from LMMS host + 從 LMMS 宿主控制 VST-插件 - EXE-files (*.exe) - EXE-文件 (*.exe) + + Click here, if you want to control VST-plugin from host. + + + Open VST-plugin preset + 打開 VST-插件預設 + + + + 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. + 點擊這裏, 如果你想保存當前 VST-插件預設。 + + + 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. + 點此顯示/隱藏VST插件的界面。 + + + + Turn off all notes + 全部靜音 + + + + Open VST-plugin + 打開VST插件 + + + + DLL-files (*.dll) + DLL 檔案 (*.dll) + + + + EXE-files (*.exe) + EXE 檔案 (*.exe) + + + + No VST-plugin loaded + 未載入VST插件 + + + Preset 預置 + by - + + - VST plugin control - VST插件控制 + + + VisualizationWidget - Open VST plugin - + + click to enable/disable visualization of master-output + 點擊啓用/禁用視覺化主輸出 - Control VST plugin from LMMS host - - - - Open VST plugin preset - - - - No VST plugin loaded - + + Click to enable + 點擊啓用 VstEffectControlDialog + Show/hide 顯示/隱藏 + + Control VST-plugin from LMMS host + 從 LMMS 宿主控制 VST-插件 + + + + Click here, if you want to control VST-plugin from host. + + + + + Open VST-plugin preset + 打開 VST-插件預設 + + + + 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. + 點擊這裏, 如果你想保存當前 VST-插件預設。 + + + + Effect by: - + + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /> - - - - Control VST plugin from LMMS host - - - - Open VST plugin preset - + VstPlugin - Loading plugin - 載入插件 + + + The VST plugin %1 could not be loaded. + 無法載入VST插件 %1。 + Open Preset 打開預置 + + Vst Plugin Preset (*.fxp *.fxb) VST插件預置文件(*.fxp *.fxb) + : default : 默認 + " " + ' ' + Save Preset 保存預置 + .fxp .fxp + .FXP .FXP + .FXB .FXB + .fxb .fxb - Please wait while loading VST plugin... - 正在載入VST插件,請稍候…… + + Loading plugin + 載入插件 - The VST plugin %1 could not be loaded. - 無法載入VST插件 %1。 + + Please wait while loading VST plugin... + 正在載入VST插件,請稍候…… WatsynInstrument + Volume A1 - + + Volume A2 - + + Volume B1 - + + Volume B2 - + + Panning A1 - + + Panning A2 - + + Panning B1 - + + Panning 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 - + + Right detune B1 - + + Right detune B2 - + + 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 - + + B2-B1 modulation - + + Selected graph - + WatsynView - Select oscillator A1 - - - - Select oscillator A2 - - - - Select oscillator B1 - - - - Select oscillator B2 - - - - Mix output of A2 to A1 - - - - Mix output of B2 to B1 - - - - Draw your own waveform here by dragging your mouse on this graph. - - - - Load waveform - 載入波形 - - - Phase left - - - - Phase right - - - - Normalize - 標準化 - - - Invert - 反轉 - - - Smooth - 平滑 - - - Sine wave - 正弦波 - - - Triangle wave - 三角波 - - - Square wave - 方波 - - + + + + Volume 音量 + + + + Panning 聲相 + + + + Freq. multiplier - + + + + + Left detune - + + + + + + + + + cents - + + + + + Right detune - + + A-B Mix - + + Mix envelope amount - + + Mix envelope attack - + + Mix envelope hold - + + Mix envelope decay - + + Crosstalk - + - Modulate amplitude of A1 by output of A2 - + + Select oscillator A1 + - Ring modulate A1 and A2 - + + Select oscillator A2 + - Modulate phase of A1 by output of A2 - + + Select oscillator B1 + - Modulate amplitude of B1 by output of B2 - + + Select oscillator B2 + - Ring modulate B1 and B2 - + + Mix output of A2 to A1 + - Modulate phase of B1 by output of B2 - + + Modulate amplitude of A1 with output of A2 + - Load a waveform from a sample file - + + Ring-modulate A1 and A2 + - Shift phase by -15 degrees - + + Modulate phase of A1 with output of A2 + - Shift phase by +15 degrees - + + Mix output of B2 to B1 + - Saw wave - 鋸齒波 - - - - Xpressive - - Selected graph - + + Modulate amplitude of B1 with output of B2 + - A1 - + + Ring-modulate B1 and B2 + - A2 - + + Modulate phase of B1 with output of B2 + - A3 - - - - W1 smoothing - - - - W2 smoothing - - - - W3 smoothing - - - - Panning 1 - - - - Panning 2 - - - - Rel trans - - - - - XpressiveView - + + + + Draw your own waveform here by dragging your mouse on this graph. - + - Select oscillator W1 - + + Load waveform + 載入波形 - Select oscillator W2 - + + Click to load a waveform from a sample file + - Select oscillator W3 - + + Phase left + - Select output O1 - + + Click to shift phase by -15 degrees + - Select output O2 - + + Phase right + - Open help window - + + Click to shift phase by +15 degrees + + + Normalize + 標準化 + + + + Click to normalize + + + + + Invert + 反轉 + + + + Click to invert + + + + + Smooth + 平滑 + + + + Click to smooth + + + + Sine wave - 正弦波 + 正弦波 - Moog-saw wave - - - - Exponential wave - - - - Saw wave - 鋸齒波 - - - User-defined wave - + + Click for sine wave + + + Triangle wave - 三角波 + 三角波 + + Click for triangle wave + + + + + Click for saw wave + + + + Square wave - 方波 + 方波 - White noise - - - - WaveInterpolate - - - - ExpressionValid - - - - General purpose 1: - - - - General purpose 2: - - - - General purpose 3: - - - - O1 panning: - - - - O2 panning: - - - - Release transition: - - - - Smoothness - + + Click for square wave + ZynAddSubFxInstrument + Portamento - + + + Filter Frequency + + + + + Filter Resonance + + + + Bandwidth 帶寬 - Filter frequency - + + FM Gain + FM 增益 - Filter resonance - + + Resonance Center Frequency + - FM gain - + + Resonance Bandwidth + - Resonance center frequency - - - - Resonance bandwidth - - - - Forward MIDI control change events - + + Forward MIDI Control Change Events + ZynAddSubFxView - Show GUI - 顯示圖形界面 - - + Portamento: - + + PORT - + + + Filter Frequency: + + + + FREQ 頻率 - RES - + + Filter Resonance: + + + RES + + + + Bandwidth: 帶寬: + BW - + + + FM Gain: + + + + FM GAIN - + + Resonance center frequency: - + + RES CF - + + Resonance bandwidth: - + + RES BW - + - Filter frequency: - + + Forward MIDI Control Changes + - Filter resonance: - + + Show GUI + 顯示圖形界面 - FM gain: - - - - Forward MIDI control changes - + + Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. + audioFileProcessor + Amplify 增益 + Start of sample 採樣起始 + End of sample 採樣結尾 - Reverse sample - 反轉採樣 - - - Stutter - - - + Loopback point 循環點 + + Reverse sample + 反轉採樣 + + + Loop mode 循環模式 + + Stutter + + + + Interpolation mode 補間方式 + None + Linear 線性插補 + Sinc 辛格(Sinc)插補 + Sample not found: %1 採樣未找到: %1 @@ -3428,430 +9939,294 @@ bitInvader - Sample length - + + Samplelength + 採樣長度 bitInvaderView + + Sample Length + 採樣長度 + + + + Draw your own waveform here by dragging your mouse on this graph. + + + + Sine wave 正弦波 + + Click for a sine-wave. + + + + Triangle wave 三角波 + + Click here for a triangle-wave. + 點擊這裡使用三角波。 + + + Saw wave 鋸齒波 + + Click here for a saw-wave. + + + + Square wave 方波 - Interpolation - + + Click here for a square-wave. + 點擊這裡使用方形波。 + + White noise wave + 白噪音 + + + + Click here for white-noise. + + + + + User defined wave + 用戶自定義波形 + + + + Click here for a user-defined shape. + + + + + Smooth + 平滑 + + + + Click here to smooth waveform. + 點擊這裏平滑波形。 + + + + Interpolation + + + + Normalize 標準化 - - Draw your own waveform here by dragging your mouse on this graph. - - - - Sample length - - - - White noise - - - - User-defined wave - - - - Smooth waveform - 平滑波形 - dynProcControlDialog + INPUT 輸入 + Input gain: 輸入增益: + OUTPUT 輸出 + Output gain: 輸出增益: + ATTACK - + + Peak attack time: - + + RELEASE - + + Peak release time: - + + + Reset waveform + 重置波形 + + + + Click here to reset the wavegraph back to default + + + + + Smooth waveform + 平滑波形 + + + + Click here to apply smoothing to wavegraph + 點擊這裏來使波形圖更爲平滑 + + + + Increase wavegraph amplitude by 1dB + + + + + Click here to increase wavegraph amplitude by 1dB + + + + + Decrease wavegraph amplitude by 1dB + + + + + Click here to decrease wavegraph amplitude by 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 - - - - Reset wavegraph - - - - Smooth wavegraph - - - - Increase wavegraph amplitude by 1 dB - - - - Decrease wavegraph amplitude by 1 dB - - - - Stereo mode: maximum - - - - Stereo mode: average - - - - Stereo mode: unlinked - + dynProcControls + Input gain 輸入增益 + Output gain 輸出增益 + Attack time - + + Release time - + + Stereo mode - + - kickerInstrument + expressiveView - Start frequency - 起始頻率 + Select oscillator W1 + - End frequency - 結束頻率 + Select oscillator W2 + - Gain - 增益 + Select oscillator W3 + - Length - 長度 + Select OUTPUT 1 + - Noise - 噪音 + Select OUTPUT 2 + - Click - 力度 + Open help window + - Start from note - 從哪個音符開始 + Sine wave + 正弦波 - End to note - 到哪個音符結束 + Click for a sine-wave. + - Start distortion - + Moog-Saw wave + - End distortion - + Click for a Moog-Saw-wave. + - Envelope slope - + Exponential wave + - Frequency slope - - - - - kickerInstrumentView - - Start frequency: - 起始頻率: - - - End frequency: - 結束頻率: - - - Gain: - 增益: - - - Click: - 力度: - - - Noise: - 噪音: - - - Frequency slope: - - - - Envelope length: - - - - Envelope slope: - - - - Start distortion: - - - - End distortion: - - - - - ladspaBrowserView - - Available Effects - 可用效果器 - - - Unavailable Effects - 不可用效果器 - - - Instruments - 樂器插件 - - - Analysis Tools - 分析工具 - - - Don't know - 未知 - - - Type: - 類型: - - - - ladspaDescription - - Plugins - 插件 - - - Description - 描述 - - - - ladspaPortDialog - - Ports - - - - Name - 名稱 - - - Rate - - - - Direction - 方向 - - - Type - 類型 - - - Min < Default < Max - 最小 < 默認 < 最大 - - - Logarithmic - 對數 - - - SR Dependent - - - - Audio - 音頻 - - - Control - 控制 - - - Input - 輸入 - - - Output - 輸出 - - - Toggled - - - - Integer - 整型 - - - Float - 浮點 - - - Yes - - - - - lb302Synth - - VCF Cutoff Frequency - - - - VCF Resonance - - - - VCF Envelope Mod - - - - VCF Envelope Decay - - - - Distortion - 失真 - - - Waveform - 波形 - - - Slide Decay - - - - Slide - - - - Accent - - - - Dead - - - - 24dB/oct Filter - - - - - lb302SynthView - - Cutoff Freq: - - - - Resonance: - 共鳴: - - - Env Mod: - - - - Decay: - 衰減: - - - 303-es-que, 24dB/octave, 3 pole filter - - - - Slide Decay: - - - - DIST: - + Click for an exponential wave. + Saw wave @@ -3859,7 +10234,15 @@ Click here for a saw-wave. - + + + + User defined wave + 用戶自定義波形 + + + Click here for a user-defined shape. + Triangle wave @@ -3877,358 +10260,1123 @@ Click here for a square-wave. 點擊這裡使用方形波。 - - Rounded square wave - - - - Click here for a square-wave with a rounded end. - - - - Moog wave - - - - Click here for a moog-like wave. - - - - Sine wave - 正弦波 - - - Click for a sine-wave. - - White noise wave 白噪音 - - Click here for an exponential wave. - - Click here for white-noise. - + + WaveInterpolate + + + + ExpressionValid + + + + General purpose 1: + + + + General purpose 2: + + + + General purpose 3: + + + + O1 panning: + + + + O2 panning: + + + + Release transition: + + + + Smoothness + + + + + fxLineLcdSpinBox + + + Assign to: + 分配給: + + + + New FX Channel + 新的效果通道 + + + + graphModel + + + Graph + 圖形 + + + + kickerInstrument + + + Start frequency + 起始頻率 + + + + End frequency + 結束頻率 + + + + Length + 長度 + + + + Distortion Start + 起始失真度 + + + + Distortion End + 結束失真度 + + + + Gain + 增益 + + + + Envelope Slope + 包絡線傾斜度 + + + + Noise + 噪音 + + + + Click + 力度 + + + + Frequency Slope + 頻率傾斜度 + + + + Start from note + 從哪個音符開始 + + + + End to note + 到哪個音符結束 + + + + kickerInstrumentView + + + Start frequency: + 起始頻率: + + + + End frequency: + 結束頻率: + + + + Frequency Slope: + 頻率傾斜度: + + + + Gain: + 增益: + + + + Envelope Length: + 包絡長度: + + + + Envelope Slope: + 包絡線傾斜度: + + + + Click: + 力度: + + + + Noise: + 噪音: + + + + Distortion Start: + 起始失真度: + + + + Distortion End: + 結束失真度: + + + + ladspaBrowserView + + + + Available Effects + 可用效果器 + + + + + Unavailable Effects + 不可用效果器 + + + + + Instruments + 樂器插件 + + + + + Analysis Tools + 分析工具 + + + + + Don't know + 未知 + + + + 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. + 這個對話框顯示 LMMS 找到的所有 LADSPA 插件信息。這些插件根據接口類型和名字被分爲五個類別。 + +"可用效果" 是指可以被 LMMS 使用的插件。爲了讓 LMMS 可以開啓效果, 首先, 這個插件需要是有效果的。也就是說, 這個插件需要有輸入和輸出通道。LMMS 會將音頻接口名稱中有 ‘in’ 的接口識別爲輸入接口, 將音頻接口名稱中有 ‘out’ 的接口識別爲輸出接口。並且, 效果插件需要有相同的輸入輸出通道, 還要能支持實時處理。 + +"不可用效果" 是指被識別爲效果插件的插件, 但是輸入輸出通道數不同或者不支持實時音頻處理。 + +"樂器" 是指只檢測到有輸出通道的插件。 + +"分析工具" 是指只檢測到有輸入通道的插件。 + +"未知" 是指沒有檢測到任何輸出或輸出通道的插件。 + +雙擊任意插件將會顯示接口信息。 + + + + Type: + 類型: + + + + ladspaDescription + + + Plugins + 插件 + + + + Description + 描述 + + + + ladspaPortDialog + + + Ports + + + + + Name + 名稱 + + + + Rate + + + + + Direction + 方向 + + + + Type + 類型 + + + + Min < Default < Max + 最小 < 默認 < 最大 + + + + Logarithmic + 對數 + + + + SR Dependent + + + + + Audio + 音頻 + + + + Control + 控制 + + + + Input + 輸入 + + + + Output + 輸出 + + + + Toggled + + + + + Integer + 整型 + + + + Float + 浮點 + + + + + Yes + + + + + lb302Synth + + + VCF Cutoff Frequency + + + + + VCF Resonance + + + + + VCF Envelope Mod + + + + + VCF Envelope Decay + + + + + Distortion + 失真 + + + + Waveform + 波形 + + + + Slide Decay + + + + + Slide + + + + + Accent + + + + + Dead + + + + + 24dB/oct Filter + + + + + lb302SynthView + + + Cutoff Freq: + + + + + Resonance: + 共鳴: + + + + Env Mod: + + + + + Decay: + 衰減: + + + + 303-es-que, 24dB/octave, 3 pole filter + + + + + Slide Decay: + + + + + DIST: + + + + + Saw wave + 鋸齒波 + + + + Click here for a saw-wave. + + + + + Triangle wave + 三角波 + + + + Click here for a triangle-wave. + 點擊這裡使用三角波。 + + + + Square wave + 方波 + + + + Click here for a square-wave. + 點擊這裡使用方形波。 + + + + Rounded square wave + + + + + Click here for a square-wave with a rounded end. + + + + + Moog wave + + + + + Click here for a moog-like wave. + + + + + Sine wave + 正弦波 + + + + Click for a sine-wave. + + + + + + White noise wave + 白噪音 + + + + Click here for an exponential wave. + + + + + Click here for white-noise. + + + + 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 - + + Position - + + + Vibrato Gain + + + + + Vibrato Freq + + + + + Stick Mix + + + + Modulator - + + Crossfade - + + + LFO Speed + + + + + LFO Depth + + + + ADSR - + + Pressure - + + Motion - + + Speed - + + Bowed - + + Spread - + + Marimba - + + Vibraphone - + + Agogo - + + + Wood1 + + + + Reso - + + + Wood2 + + + + Beats - + + + Two Fixed + + + + Clump - + + + Tubular Bells + + + + + Uniform Bar + + + + + Tuned Bar + + + + Glass - + - Vibrato gain - - - - Vibrato frequency - - - - Stick mix - - - - LFO speed - LFO 速度 - - - LFO depth - - - - Wood 1 - - - - Wood 2 - - - - Two fixed - - - - Tubular bells - - - - Uniform bar - - - - Tuned bar - - - - Tibetan bowl - + + Tibetan Bowl + malletsInstrumentView + Instrument - + + Spread - + + Spread: - - - - Hardness - - - - Hardness: - - - - Position - - - - Position: - - - - Modulator - - - - Modulator: - - - - Crossfade - - - - Crossfade: - - - - ADSR - - - - ADSR: - - - - Pressure - - - - Pressure: - - - - Speed - - - - Speed: - + + Missing files - + 檔案遺失 + Your Stk-installation seems to be incomplete. Please make sure the full Stk-package is installed! - + - Vibrato gain - + + Hardness + - Vibrato gain: - + + Hardness: + - Vibrato frequency - + + Position + - Vibrato frequency: - + + Position: + - Stick mix - + + Vib Gain + - Stick mix: - + + Vib Gain: + - LFO speed - LFO 速度 + + Vib Freq + - LFO speed: - + + Vib Freq: + - LFO depth - + + Stick Mix + - LFO depth: - + + Stick Mix: + + + + + Modulator + + + + + Modulator: + + + + + Crossfade + + + + + Crossfade: + + + + + LFO Speed + + + + + LFO Speed: + + + + + LFO Depth + + + + + LFO Depth: + + + + + ADSR + + + + + ADSR: + + + + + Pressure + + + + + Pressure: + + + + + Speed + + + + + Speed: + manageVSTEffectView + - VST parameter control - VST 參數控制 + + VST Sync + VST 同步 + + + + Click here if you want to synchronize all parameters with VST plugin. + 點擊這裏, 如果你想與 VST 插件同步所有參數。 + + + + Automated 自動 + + Click here if you want to display automated parameters only. + + + + Close 關閉 - VST sync - + + Close VST effect knob-controller window. + manageVestigeInstrumentView + + - VST plugin control - VST插件控制 + VST Sync VST 同步 + + Click here if you want to synchronize all parameters with VST plugin. + 點擊這裏, 如果你想與 VST 插件同步所有參數。 + + + + Automated 自動 + + Click here if you want to display automated parameters only. + + + + Close 關閉 + + + Close VST plugin knob-controller window. + + + + + opl2instrument + + + Patch + 音色 + + + + Op 1 Attack + + + + + Op 1 Decay + + + + + Op 1 Sustain + + + + + Op 1 Release + + + + + Op 1 Level + + + + + Op 1 Level Scaling + + + + + Op 1 Frequency Multiple + + + + + Op 1 Feedback + + + + + 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 + + + + + Vibrato Depth + + + + + Tremolo Depth + + + + + opl2instrumentView + + + + Attack + 打進聲 + + + + + Decay + 衰減 + + + + + Release + 釋放 + + + + + Frequency multiplier + + organicInstrument + Distortion 失真 + Volume 音量 @@ -4236,73 +11384,458 @@ organicInstrumentView + Distortion: 失真: + + The distortion knob adds distortion to the output of the instrument. + + + + 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: - + + Osc %1 volume: - + + Osc %1 panning: - + + + Osc %1 stereo detuning + + + + cents 音分 cents - Osc %1 stereo detuning - + + Osc %1 harmonic: + + + + + FreeBoyInstrument + + + Sweep time + - Osc %1 harmonic: - + + Sweep direction + + + + + Sweep RtShift amount + + + + + + Wave Pattern Duty + + + + + Channel 1 volume + + + + + + + Volume sweep direction + + + + + + + Length of each step in sweep + + + + + Channel 2 volume + + + + + Channel 3 volume + + + + + Channel 4 volume + + + + + Shift Register width + + + + + Right Output level + 右聲道輸出電平 + + + + Left Output level + + + + + Channel 1 to SO2 (Left) + + + + + Channel 2 to SO2 (Left) + + + + + Channel 3 to SO2 (Left) + + + + + Channel 4 to SO2 (Left) + + + + + Channel 1 to SO1 (Right) + + + + + Channel 2 to SO1 (Right) + + + + + Channel 3 to SO1 (Right) + + + + + Channel 4 to SO1 (Right) + + + + + Treble + + + + + Bass + 低音 + + + + FreeBoyInstrumentView + + + 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 + + + + + + + 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 + patchesDialog + Qsynth: Channel Preset Qsynth: 通道預設 + Bank selector 音色選擇器 + Bank + Program selector - + + Patch 音色 + Name 名稱 + OK 確定 + Cancel 取消 @@ -4310,449 +11843,634 @@ pluginBrowser - Incomplete monophonic imitation tb303 - + + no description + 沒有描述 - Plugin for freely manipulating stereo output - + + A native amplifier plugin + 原生增益插件 - Plugin for controlling knobs with sound peaks - + + Simple sampler with various settings for using samples (e.g. drums) in an instrument-track + 簡單地在樂器欄使用採樣(比如鼓音源), 同時也提供多種設置 - Plugin for enhancing stereo separation of a stereo input file - + + Boost your bass the fast and simple way + + + Customizable wavetable synthesizer + 可自定製的波表合成器 + + + + An oversampling bitcrusher + + + + + Carla Patchbay Instrument + Carla Patchbay 樂器 + + + + Carla Rack Instrument + Carla Rack 樂器 + + + + A 4-band Crossover Equalizer + + + + + A native delay plugin + 原生的衰減插件 + + + + A Dual filter plugin + + + + + plugin for processing dynamics in a flexible way + + + + + A native eq plugin + 原生的 EQ 插件 + + + + A native flanger plugin + 一個原生的 鑲邊 (Flanger) 插件 + + + + Player for GIG files + 播放 GIG 檔案的播放器 + + + + Filter for importing Hydrogen files into LMMS + 匯入 Hydrogen 專案檔至 LMMS 的解析器 + + + + Versatile drum synthesizer + 多功能鼓合成器 + + + List installed LADSPA plugins 列出已安裝的 LADSPA 插件 - GUS-compatible patch instrument - GUS 兼容音色的樂器 - - - Additive Synthesizer for organ-like sounds - - - - Tuneful things to bang on - - - - VST-host for using VST(i)-plugins within LMMS - LMMS的VST(i)插件宿主 - - - Vibrating string modeler - - - + plugin for using arbitrary LADSPA-effects inside LMMS. 在 LMMS 中使用任意 LADSPA 效果的插件。 - Filter for importing MIDI-files into LMMS - + + Incomplete monophonic imitation tb303 + + + Filter for exporting MIDI-files from LMMS + 從 LMMS 匯出 MIDI 檔的解析器 + + + + Filter for importing MIDI-files into LMMS + 匯入 MIDI 檔至 LMMS 的解析器 + + + + Monstrous 3-oscillator synth with modulation matrix + + + + + A multitap echo delay plugin + + + + + A NES-like synthesizer + 類似於 NES 的合成器 + + + + 2-operator FM Synth + + + + + Additive Synthesizer for organ-like sounds + + + + + Emulation of GameBoy (TM) APU + GameBoy (TM) APU 模擬器 + + + + GUS-compatible patch instrument + GUS 兼容音色的樂器 + + + + Plugin for controlling knobs with sound peaks + + + + + Reverb algorithm by Sean Costello + + + + + Player for SoundFont files + 播放 SoundFont 檔案的播放器 + + + + LMMS port of sfxr + sfxr 的 LMMS 移植版本 + + + Emulation of the MOS6581 and MOS8580 SID. This chip was used in the Commodore 64 computer. 模擬 MOS6581 和 MOS8580 SID 的模擬器 這些芯片曾在 Commodore 64 電腦上用過。 - Player for SoundFont files - 在工程中使用SoundFont - - - Emulation of GameBoy (TM) APU - GameBoy (TM) APU 模擬器 - - - Customizable wavetable synthesizer - 可自定製的波表合成器 - - - Embedded ZynAddSubFX - 內置的 ZynAddSubFX - - - 2-operator FM Synth - - - - Filter for importing Hydrogen files into LMMS - 導入 Hydrogen 工程文件到 LMMS 的解析器 - - - LMMS port of sfxr - sfxr 的 LMMS 移植版本 - - - Monstrous 3-oscillator synth with modulation matrix - - - - Three powerful oscillators you can modulate in several ways - - - - A native amplifier plugin - 原生增益插件 - - - Carla Rack Instrument - Carla Rack 樂器 - - - 4-oscillator modulatable wavetable synth - - - - plugin for waveshaping - - - - Boost your bass the fast and simple way - - - - Versatile drum synthesizer - 多功能鼓合成器 - - - Simple sampler with various settings for using samples (e.g. drums) in an instrument-track - 簡單地在樂器欄使用採樣(比如鼓音源), 同時也提供多種設置 - - - plugin for processing dynamics in a flexible way - - - - Carla Patchbay Instrument - Carla Patchbay 樂器 - - - plugin for using arbitrary VST effects inside LMMS. - - - + Graphical spectrum analyzer plugin 圖形頻譜分析器插件 - A NES-like synthesizer - 類似於 NES 的合成器 + + Plugin for enhancing stereo separation of a stereo input file + 用以增強雙聲道輸入檔的聲道分離插件 - A native delay plugin - 原生的衰減插件 + + Plugin for freely manipulating stereo output + - Player for GIG files - 播放 GIG 文件的播放器 + + Tuneful things to bang on + - A multitap echo delay plugin - + + Three powerful oscillators you can modulate in several ways + - A native flanger plugin - 一個原生的 鑲邊 (Flanger) 插件 + + VST-host for using VST(i)-plugins within LMMS + LMMS的VST(i)插件宿主 - An oversampling bitcrusher - + + Vibrating string modeler + - A native eq plugin - 原生的 EQ 插件 + + plugin for using arbitrary VST effects inside LMMS. + - A 4-band Crossover Equalizer - + + 4-oscillator modulatable wavetable synth + - A Dual filter plugin - + + plugin for waveshaping + - Filter for exporting MIDI-files from LMMS - - - - Reverb algorithm by Sean Costello - + + Embedded ZynAddSubFX + 內置的 ZynAddSubFX Mathematical expression parser - + sf2Instrument + Bank + Patch 音色 + 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。 - - Reverb room size - - - - Reverb damping - - - - Reverb width - - - - Reverb level - - - - Chorus voices - - - - Chorus level - - - - Chorus speed - - - - Chorus depth - - sf2InstrumentView + + Open other SoundFont file + 打開其他SoundFont文件 + + + + Click here to open another SF2 file + 點擊此處打開另一個SF2文件 + + + + 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 - 打開SoundFont文件 + 開啟 SoundFont 檔案 - Choose patch - - - - Gain: - 增益: - - - Room size: - - - - Damping: - - - - Width: - 寬度: - - - Level: - - - - Voices: - - - - Speed: - - - - Depth: - 位深: - - - SoundFont Files (*.sf2 *.sf3) - + + SoundFont2 Files (*.sf2) + SoundFont2 Files (*.sf2) sfxrInstrument - Wave - + + Wave Form + 波形 sidInstrument + + Cutoff + 切除 + + + Resonance 共鳴 + Filter type 過濾器類型 + Voice 3 off 聲音 3 關 + Volume 音量 + Chip model 芯片型號 - - Cutoff frequency - 切除頻率 - sidInstrumentView + Volume: 音量: + Resonance: 共鳴: + + Cutoff frequency: 頻譜刀頻率: + + High-Pass filter + 高通濾波器 + + + + Band-Pass filter + 帶通濾波器 + + + + Low-Pass filter + 低通濾波器 + + + + Voice3 Off + 聲音 3 關 + + + MOS6581 SID MOS6581 SID + MOS8580 SID MOS8580 SID + + Attack: 打進聲: + + Attack rate determines how rapidly the output of Voice %1 rises from zero to peak amplitude. + + + + + Decay: 衰減: + + Decay rate determines how rapidly the output falls from the peak amplitude to the selected Sustain level. + + + + Sustain: 振幅持平: + + Output of Voice %1 will remain at the selected Sustain amplitude as long as the note is held. + + + + + 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 噪音 + Sync 同步 - Filtered - + + 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 測試 - High-pass filter - - - - Band-pass filter - - - - Low-pass filter - - - - Voice 3 off - - - - Pulse wave - - - - Triangle wave - 三角波 - - - Saw wave - 鋸齒波 - - - Ring modulation - - - - Pulse width: - + + Test, when set, resets and locks Oscillator %1 at zero until Test is turned off. + stereoEnhancerControlDialog - Width: - 寬度: + + WIDE + - WIDTH - + + Width: + 寬度: stereoEnhancerControls + Width 寬度 @@ -4760,18 +12478,22 @@ This chip was used in the Commodore 64 computer. stereoMatrixControlDialog + Left to Left Vol: 從左到左音量: + Left to Right Vol: 從左到右音量: + Right to Left Vol: 從右到左音量: + Right to Right Vol: 從右到右音量: @@ -4779,18 +12501,22 @@ This chip was used in the Commodore 64 computer. stereoMatrixControls + Left to Left 從左到左 + Left to Right 從左到右 + Right to Left 從右到左 + Right to Right 從右到右 @@ -4798,191 +12524,357 @@ This chip was used in the Commodore 64 computer. vestigeInstrument + Loading plugin 載入插件 - Please wait while loading the VST plugin... - + + Please wait while loading VST-plugin... + 請等待VST插件加載完成... vibed + String %1 volume - + + String %1 stiffness - + + Pick %1 position - + + Pickup %1 position - + + + Pan %1 + 聲相 %1 + + + + Detune %1 + 去諧 %1 + + + + Fuzziness %1 + 模糊度 %1 + + + + Length %1 + 長度 %1 + + + Impulse %1 - + - String %1 panning - - - - String %1 detune - - - - String %1 fuzziness - - - - String %1 length - - - - String %1 - + + Octave %1 + 八度音 %1 vibedView + + Volume: + 音量: + + + + The 'V' knob sets the volume of the selected string. + + + + 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: - + + + 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: - + + + 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: + + + + + The Pan knob determines the location of the selected string in the stereo field. + + + + + 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: + + + + + 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: + 長度: + + + + 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 - + + + 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 - + + + 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 啓用波形 - String - + + Click here to enable/disable waveform. + 點擊這裏啓用/禁用波形。 + + String + + + + + 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 正弦波 + + Use a sine-wave for current oscillator. + 爲當前振盪器使用正弦波。 + + + Triangle wave 三角波 + + Use a triangle-wave for current oscillator. + 爲當前振盪器使用三角波。 + + + Saw wave 鋸齒波 + + Use a saw-wave for current oscillator. + 爲當前振盪器使用鋸齒波。 + + + Square wave 方波 - String volume: - + + Use a square-wave for current oscillator. + 爲當前振盪器使用方波。 - String panning: - + + White noise wave + 白噪音 - String detune: - + + Use white-noise for current oscillator. + 爲當前振盪器使用白噪音。 - String fuzziness: - + + User defined wave + 用戶自定義波形 - String length: - + + Use a user-defined waveform for current oscillator. + 爲當前振盪器使用用戶自定波形。 - Impulse - + + Smooth + 平滑 - Enable/disable string - + + Click here to smooth waveform. + 點擊這裏平滑波形。 - White noise - + + Normalize + 標準化 - User-defined wave - - - - Smooth waveform - 平滑波形 - - - Normalize waveform - + + Click here to normalize waveform. + 點擊這裏標準化波形。 voiceObject + Voice %1 pulse width - + + Voice %1 attack - + + Voice %1 decay - + + Voice %1 sustain - + + Voice %1 release - + + Voice %1 coarse detuning - + + Voice %1 wave shape 聲音 %1 波形形狀 + Voice %1 sync 聲音 %1 同步 + Voice %1 ring modulate - + + Voice %1 filtered - + + Voice %1 test 聲音 %1 測試 @@ -4990,53 +12882,85 @@ This chip was used in the Commodore 64 computer. waveShaperControlDialog + INPUT 輸入 + Input gain: 輸入增益: + OUTPUT 輸出 + Output gain: 輸出增益: + + Reset waveform + 重置波形 + + + + Click here to reset the wavegraph back to default + + + + + Smooth waveform + 平滑波形 + + + + Click here to apply smoothing to wavegraph + 點擊這裏來使波形圖更爲平滑 + + + + Increase graph amplitude by 1dB + + + + + Click here to increase wavegraph amplitude by 1dB + + + + + Decrease graph amplitude by 1dB + + + + + Click here to decrease wavegraph amplitude by 1dB + + + + Clip input 輸入壓限 - Reset wavegraph - - - - Smooth wavegraph - - - - Increase wavegraph amplitude by 1 dB - - - - Decrease wavegraph amplitude by 1 dB - - - - Clip input signal to 0 dB - + + Clip input signal to 0dB + 將輸入信號限制到 0dB waveShaperControls + Input gain 輸入增益 + Output gain 輸出增益 From bdbea87149ee98e3bbe6bead94c6d5102abdfc50 Mon Sep 17 00:00:00 2001 From: Steffen Baranowsky Date: Fri, 26 Jul 2019 10:04:16 +0200 Subject: [PATCH 355/445] show BBEditor on clicking the TrackLabelButton (#5060) --- src/tracks/BBTrack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracks/BBTrack.cpp b/src/tracks/BBTrack.cpp index a4217d23d..14b65f336 100644 --- a/src/tracks/BBTrack.cpp +++ b/src/tracks/BBTrack.cpp @@ -664,5 +664,5 @@ bool BBTrackView::close() void BBTrackView::clickedTrackLabel() { Engine::getBBTrackContainer()->setCurrentBB( m_bbTrack->index() ); - gui->getBBEditor()->show(); + gui->getBBEditor()->parentWidget()->show(); } From 1c715bc335b70d92b76bbb5d8c8c71dfba710be7 Mon Sep 17 00:00:00 2001 From: Spekular Date: Sat, 27 Jul 2019 11:14:49 +0200 Subject: [PATCH 356/445] Enhanced snapping in song editor (#4973) * New default behavior: Preserves offsets when moving clips, resizes in fixed increments. * Adds shift + drag: Snaps move start position (like current behavior) or end position (new), based on which is closest to the real position. When moving a selection, the grabbed clip snaps into position and the rest move relative to it. * Adds alt + drag: Allows fine adjustment of a clip's position or size, as an alternative to ctrl + drag. * Adds a Q dropdown in the song editor to allow finer or coarser snapping (8 bars to 1/16th bar) * Adds a proportional snap toggle. When enabled, snapping size/Q adjusts based on zoom, and a label appears showing the current snap size. This is disabled by default. --- data/themes/classic/proportional_snap.png | Bin 0 -> 263 bytes data/themes/default/proportional_snap.png | Bin 0 -> 263 bytes include/MidiTime.h | 3 +- include/SongEditor.h | 12 +- include/Track.h | 18 +- src/core/Track.cpp | 234 +++++++++++++++------- src/core/midi/MidiTime.cpp | 17 +- src/gui/TimeLineWidget.cpp | 6 +- src/gui/editors/SongEditor.cpp | 125 +++++++++++- src/tracks/SampleTrack.cpp | 5 +- 10 files changed, 328 insertions(+), 92 deletions(-) create mode 100644 data/themes/classic/proportional_snap.png create mode 100644 data/themes/default/proportional_snap.png diff --git a/data/themes/classic/proportional_snap.png b/data/themes/classic/proportional_snap.png new file mode 100644 index 0000000000000000000000000000000000000000..66a0bb0493411d97d9a3e3b22cd779afeb0d89f2 GIT binary patch literal 263 zcmV+i0r>ujP)w8hB+L*W8jWMdbMaYZ01ujP)w8hB+L*W8jWMdbMaYZ01 m_zoomLevels; @@ -141,7 +147,6 @@ private: EditMode m_ctrlMode; // mode they were in before they hit ctrl friend class SongEditorWindow; - } ; @@ -170,6 +175,8 @@ protected slots: void lostFocus(); void adjustUiAfterProjectLoad(); + void updateSnapLabel(); + signals: void playTriggered(); void resized(); @@ -181,6 +188,7 @@ private: QAction* m_addBBTrackAction; QAction* m_addSampleTrackAction; QAction* m_addAutomationTrackAction; + QAction* m_setProportionalSnapAction; ActionGroup * m_editModeGroup; QAction* m_drawModeAction; @@ -188,6 +196,8 @@ private: QAction* m_crtlAction; ComboBox * m_zoomingComboBox; + ComboBox * m_snappingComboBox; + QLabel* m_snapSizeLabel; }; #endif diff --git a/include/Track.h b/include/Track.h index 1267d2ef7..b00c50248 100644 --- a/include/Track.h +++ b/include/Track.h @@ -236,7 +236,7 @@ public: // access needsUpdate member variable bool needsUpdate(); void setNeedsUpdate( bool b ); - + public slots: virtual bool close(); void cut(); @@ -297,6 +297,9 @@ private: Actions m_action; QPoint m_initialMousePos; QPoint m_initialMouseGlobalPos; + MidiTime m_initialTCOPos; + MidiTime m_initialTCOEnd; + QVector m_initialOffsets; TextFloat * m_hint; @@ -311,14 +314,17 @@ private: bool m_gradient; bool m_needsUpdate; - inline void setInitialMousePos( QPoint pos ) + inline void setInitialPos( QPoint pos ) { m_initialMousePos = pos; m_initialMouseGlobalPos = mapToGlobal( pos ); + m_initialTCOPos = m_tco->startPosition(); + m_initialTCOEnd = m_initialTCOPos + m_tco->length(); } + void setInitialOffsets(); bool mouseMovedDistance( QMouseEvent * me, int distance ); - + MidiTime draggedTCOPos( QMouseEvent * me ); } ; @@ -564,13 +570,13 @@ public: using Model::dataChanged; - inline int getHeight() + inline int getHeight() { return m_height >= MINIMAL_TRACK_HEIGHT - ? m_height + ? m_height : DEFAULT_TRACK_HEIGHT; } - inline void setHeight( int height ) + inline void setHeight( int height ) { m_height = height; } diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 64c17c9e8..fe66ab4a5 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -267,6 +267,9 @@ TrackContentObjectView::TrackContentObjectView( TrackContentObject * tco, m_action( NoAction ), m_initialMousePos( QPoint( 0, 0 ) ), m_initialMouseGlobalPos( QPoint( 0, 0 ) ), + m_initialTCOPos( MidiTime(0) ), + m_initialTCOEnd( MidiTime(0) ), + m_initialOffsets( QVector() ), m_hint( NULL ), m_mutedColor( 0, 0, 0 ), m_mutedBackgroundColor( 0, 0, 0 ), @@ -524,7 +527,7 @@ void TrackContentObjectView::updatePosition() void TrackContentObjectView::dragEnterEvent( QDragEnterEvent * dee ) { TrackContentWidget * tcw = getTrackView()->getTrackContentWidget(); - MidiTime tcoPos = MidiTime( m_tco->startPosition().getTact(), 0 ); + MidiTime tcoPos = MidiTime( m_tco->startPosition() ); if( tcw->canPasteSelection( tcoPos, dee ) == false ) { dee->ignore(); @@ -563,7 +566,7 @@ void TrackContentObjectView::dropEvent( QDropEvent * de ) if( m_trackView->trackContainerView()->allowRubberband() == true ) { TrackContentWidget * tcw = getTrackView()->getTrackContentWidget(); - MidiTime tcoPos = MidiTime( m_tco->startPosition().getTact(), 0 ); + MidiTime tcoPos = MidiTime( m_tco->startPosition() ); if( tcw->pasteSelection( tcoPos, de ) == true ) { de->accept(); @@ -711,7 +714,8 @@ void TrackContentObjectView::paintTextLabel(QString const & text, QPainter & pai */ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) { - setInitialMousePos( me->pos() ); + setInitialPos( me->pos() ); + setInitialOffsets(); if( !fixedTCOs() && me->button() == Qt::LeftButton ) { if( me->modifiers() & Qt::ControlModifier ) @@ -725,7 +729,9 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) m_action = ToggleSelected; } } - else if( !me->modifiers() ) + else if( !me->modifiers() + || (me->modifiers() & Qt::AltModifier) + || (me->modifiers() & Qt::ShiftModifier) ) { if( isSelected() ) { @@ -739,7 +745,8 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) // move or resize m_tco->setJournalling( false ); - setInitialMousePos( me->pos() ); + setInitialPos( me->pos() ); + setInitialOffsets(); SampleTCO * sTco = dynamic_cast( m_tco ); if( me->x() < RESIZE_GRIP_WIDTH && sTco @@ -889,76 +896,86 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); if( m_action == Move ) { - const int x = mapToParent( me->pos() ).x() - m_initialMousePos.x(); - MidiTime t = qMax( 0, (int) - m_trackView->trackContainerView()->currentPosition()+ - static_cast( x * MidiTime::ticksPerTact() / - ppt ) ); - if( ! ( me->modifiers() & Qt::ControlModifier ) - && me->button() == Qt::NoButton ) - { - t = t.toNearestTact(); - } - m_tco->movePosition( t ); + MidiTime newPos = draggedTCOPos( me ); + + // Don't go left of bar zero + newPos = max( 0, newPos.getTicks() ); + m_tco->movePosition( newPos ); m_trackView->getTrackContentWidget()->changePosition(); s_textFloat->setText( QString( "%1:%2" ). - arg( m_tco->startPosition().getTact() + 1 ). - arg( m_tco->startPosition().getTicks() % + arg( newPos.getTact() + 1 ). + arg( newPos.getTicks() % MidiTime::ticksPerTact() ) ); s_textFloat->moveGlobal( this, QPoint( width() + 2, height() + 2 ) ); } else if( m_action == MoveSelection ) { - const int dx = me->x() - m_initialMousePos.x(); - const bool snap = !(me->modifiers() & Qt::ControlModifier) && - me->button() == Qt::NoButton; + // 1: Find the position we want to move the grabbed TCO to + MidiTime newPos = draggedTCOPos( me ); + + // 2: Handle moving the other selected TCOs the same distance QVector so = m_trackView->trackContainerView()->selectedObjects(); - QVector tcos; - 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 + QVector tcos; // List of selected clips + int leftmost = 0; // Leftmost clip's offset from grabbed clip + // Populate tcos, find leftmost for( QVector::iterator it = so.begin(); it != so.end(); ++it ) { TrackContentObjectView * tcov = dynamic_cast( *it ); - if( tcov == NULL ) - { - continue; - } - TrackContentObject * tco = tcov->m_tco; - tcos.push_back( tco ); - smallestPos = qMin( smallestPos, - (int)tco->startPosition() + dtick ); - } - dtick -= smallestPos; - if( snap ) - { - dtick = dtick.toAbsoluteTact(); // round toward 0 + if( tcov == NULL ) { continue; } + tcos.push_back( tcov->m_tco ); + int index = std::distance( so.begin(), it ); + leftmost = min (leftmost, m_initialOffsets[index].getTicks() ); } + // Make sure the leftmost clip doesn't get moved to a negative position + if ( newPos.getTicks() + leftmost < 0 ) { newPos = -leftmost; } + for( QVector::iterator it = tcos.begin(); it != tcos.end(); ++it ) { - ( *it )->movePosition( ( *it )->startPosition() + dtick ); + int index = std::distance( tcos.begin(), it ); + ( *it )->movePosition( newPos + m_initialOffsets[index] ); } } else if( m_action == Resize || m_action == ResizeLeft ) { + // If the user is holding alt, or pressed ctrl after beginning the drag, don't quantize + const bool unquantized = (me->modifiers() & Qt::ControlModifier) || (me->modifiers() & Qt::AltModifier); + const float snapSize = gui->songEditor()->m_editor->getSnapSize(); + // Length in ticks of one snap increment + const MidiTime snapLength = MidiTime( (int)(snapSize * MidiTime::ticksPerTact()) ); + if( m_action == Resize ) { - MidiTime t = qMax( MidiTime::ticksPerTact() / 16, static_cast( me->x() * MidiTime::ticksPerTact() / ppt ) ); - if( ! ( me->modifiers() & Qt::ControlModifier ) && me->button() == Qt::NoButton ) - { - t = qMax( MidiTime::ticksPerTact(), t.toNearestTact() ); + // The clip's new length + MidiTime l = static_cast( me->x() * MidiTime::ticksPerTact() / ppt ); + + if ( unquantized ) + { // We want to preserve this adjusted offset, + // even if the user switches to snapping later + setInitialPos( m_initialMousePos ); + // Don't resize to less than 1 tick + m_tco->changeLength( qMax( 1, l ) ); + } + else if ( me->modifiers() & Qt::ShiftModifier ) + { // If shift is held, quantize clip's end position + MidiTime end = MidiTime( m_initialTCOPos + l ).quantize( snapSize ); + // The end position has to be after the clip's start + MidiTime min = m_initialTCOPos.quantize( snapSize ); + if ( min <= m_initialTCOPos ) min += snapLength; + m_tco->changeLength( qMax(min - m_initialTCOPos, end - m_initialTCOPos) ); + } + else + { // Otherwise, resize in fixed increments + MidiTime initialLength = m_initialTCOEnd - m_initialTCOPos; + MidiTime offset = MidiTime( l - initialLength ).quantize( snapSize ); + // Don't resize to less than 1 tick + MidiTime min = MidiTime( initialLength % snapLength ); + if (min < 1) min += snapLength; + m_tco->changeLength( qMax( min, initialLength + offset) ); } - m_tco->changeLength( t ); } else { @@ -969,15 +986,34 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) MidiTime t = qMax( 0, (int) m_trackView->trackContainerView()->currentPosition()+ - static_cast( x * MidiTime::ticksPerTact() / - ppt ) ); - if( ! ( me->modifiers() & Qt::ControlModifier ) - && me->button() == Qt::NoButton ) - { - t = t.toNearestTact(); + static_cast( x * MidiTime::ticksPerTact() / ppt ) ); + + if( unquantized ) + { // We want to preserve this adjusted offset, + // even if the user switches to snapping later + setInitialPos( m_initialMousePos ); + //Don't resize to less than 1 tick + t = qMin( m_initialTCOEnd - 1, t); } + else if( me->modifiers() & Qt::ShiftModifier ) + { // If shift is held, quantize clip's start position + // Don't let the start position move past the end position + MidiTime max = m_initialTCOEnd.quantize( snapSize ); + if ( max >= m_initialTCOEnd ) max -= snapLength; + t = qMin( max, t.quantize( snapSize ) ); + } + else + { // Otherwise, resize in fixed increments + // Don't resize to less than 1 tick + MidiTime initialLength = m_initialTCOEnd - m_initialTCOPos; + MidiTime minLength = MidiTime( initialLength % snapLength ); + if (minLength < 1) minLength += snapLength; + MidiTime offset = MidiTime(t - m_initialTCOPos).quantize( snapSize ); + t = qMin( m_initialTCOEnd - minLength, m_initialTCOPos + offset ); + } + MidiTime oldPos = m_tco->startPosition(); - if( m_tco->length() + ( oldPos - t ) >= MidiTime::ticksPerTact() ) + if( m_tco->length() + ( oldPos - t ) >= 1 ) { m_tco->movePosition( t ); m_trackView->getTrackContentWidget()->changePosition(); @@ -1091,7 +1127,6 @@ void TrackContentObjectView::contextMenuEvent( QContextMenuEvent * cme ) - /*! \brief How many pixels a tact (bar) takes for this trackContentObjectView. * * \return the number of pixels per tact (bar). @@ -1102,6 +1137,27 @@ float TrackContentObjectView::pixelsPerTact() } +/*! \brief Save the offsets between all selected tracks and a clicked track */ +void TrackContentObjectView::setInitialOffsets() +{ + QVector so = m_trackView->trackContainerView()->selectedObjects(); + QVector offsets; + for( QVector::iterator it = so.begin(); + it != so.end(); ++it ) + { + TrackContentObjectView * tcov = + dynamic_cast( *it ); + if( tcov == NULL ) + { + continue; + } + offsets.push_back( tcov->m_tco->startPosition() - m_initialTCOPos ); + } + + m_initialOffsets = offsets; +} + + /*! \brief Detect whether the mouse moved more than n pixels on screen. @@ -1118,6 +1174,49 @@ bool TrackContentObjectView::mouseMovedDistance( QMouseEvent * me, int distance +/*! \brief Calculate the new position of a dragged TCO from a mouse event + * + * + * \param me The QMouseEvent + */ +MidiTime TrackContentObjectView::draggedTCOPos( QMouseEvent * me ) +{ + //Pixels per tact + const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); + // The pixel distance that the mouse has moved + const int mouseOff = mapToGlobal(me->pos()).x() - m_initialMouseGlobalPos.x(); + MidiTime newPos = m_initialTCOPos + mouseOff * MidiTime::ticksPerTact() / ppt; + MidiTime offset = newPos - m_initialTCOPos; + // If the user is holding alt, or pressed ctrl after beginning the drag, don't quantize + if ( me->button() != Qt::NoButton + || (me->modifiers() & Qt::ControlModifier) + || (me->modifiers() & Qt::AltModifier) ) + { + // We want to preserve this adjusted offset, + // even if the user switches to snapping + setInitialPos( m_initialMousePos ); + } + else if ( me->modifiers() & Qt::ShiftModifier ) + { // If shift is held, quantize position (Default in 1.2.0 and earlier) + // or end position, whichever is closest to the actual position + MidiTime startQ = newPos.quantize( gui->songEditor()->m_editor->getSnapSize() ); + // Find start position that gives snapped clip end position + MidiTime endQ = ( newPos + m_tco->length() ); + endQ = endQ.quantize( gui->songEditor()->m_editor->getSnapSize() ); + endQ = endQ - m_tco->length(); + // Select the position closest to actual position + if ( abs(newPos - startQ) < abs(newPos - endQ) ) newPos = startQ; + else newPos = endQ; + } + else + { // Otherwise, quantize moved distance (preserves user offsets) + newPos = m_initialTCOPos + offset.quantize( gui->songEditor()->m_editor->getSnapSize() ); + } + return newPos; +} + + + // =========================================================================== // trackContentWidget @@ -1496,7 +1595,6 @@ bool TrackContentWidget::pasteSelection( MidiTime tcoPos, QDropEvent * de ) int initialTrackIndex = tiAttr.value().toInt(); QDomAttr tcoPosAttr = metadata.attributeNode( "grabbedTCOPos" ); MidiTime grabbedTCOPos = tcoPosAttr.value().toInt(); - MidiTime grabbedTCOTact = MidiTime( grabbedTCOPos.getTact(), 0 ); // Snap the mouse position to the beginning of the dropped tact, in ticks const TrackContainer::TrackList tracks = getTrack()->trackContainer()->tracks(); @@ -1517,6 +1615,10 @@ bool TrackContentWidget::pasteSelection( MidiTime tcoPos, QDropEvent * de ) // TODO -- Need to draw the hovericon either way, or ghost the TCOs // onto their final position. + // All patterns should be offset the same amount as the grabbed pattern + // The offset is quantized (rather than the positions) to preserve fine adjustments + int offset = MidiTime(tcoPos - grabbedTCOPos).quantize(gui->songEditor()->m_editor->getSnapSize()); + for( int i = 0; isongEditor()->m_editor->getSnapSize(); + if (offset == 0) { pos += shift; } TrackContentObject * tco = t->createTCO( pos ); tco->restoreState( tcoElement ); @@ -1562,7 +1662,7 @@ bool TrackContentWidget::pasteSelection( MidiTime tcoPos, QDropEvent * de ) */ void TrackContentWidget::dropEvent( QDropEvent * de ) { - MidiTime tcoPos = MidiTime( getPosition( de->pos().x() ).getTact(), 0 ); + MidiTime tcoPos = MidiTime( getPosition( de->pos().x() ) ); if( pasteSelection( tcoPos, de ) == true ) { de->accept(); diff --git a/src/core/midi/MidiTime.cpp b/src/core/midi/MidiTime.cpp index b4607aee9..82ed642ba 100644 --- a/src/core/midi/MidiTime.cpp +++ b/src/core/midi/MidiTime.cpp @@ -63,13 +63,18 @@ MidiTime::MidiTime( const tick_t ticks ) : { } -MidiTime MidiTime::toNearestTact() const +MidiTime MidiTime::quantize(float bars) const { - if( m_ticks % s_ticksPerTact >= s_ticksPerTact/2 ) - { - return ( getTact() + 1 ) * s_ticksPerTact; - } - return getTact() * s_ticksPerTact; + //The intervals we should snap to, our new position should be a factor of this + int interval = s_ticksPerTact * bars; + //The lower position we could snap to + int lowPos = m_ticks / interval; + //Offset from the lower position + int offset = m_ticks % interval; + //1 if we should snap up, 0 if we shouldn't + int snapUp = offset / (interval / 2); + + return (lowPos + snapUp) * interval; } diff --git a/src/gui/TimeLineWidget.cpp b/src/gui/TimeLineWidget.cpp index 7c7f48c4e..87e513e72 100644 --- a/src/gui/TimeLineWidget.cpp +++ b/src/gui/TimeLineWidget.cpp @@ -2,7 +2,7 @@ * TimeLineWidget.cpp - class timeLine, representing a time-line with position marker * * 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 @@ -384,14 +384,14 @@ void TimeLineWidget::mouseMoveEvent( QMouseEvent* event ) } else { - m_loopPos[i] = t.toNearestTact(); + m_loopPos[i] = t.quantize(1.0); } // Catch begin == end if( m_loopPos[0] == m_loopPos[1] ) { // Note, swap 1 and 0 below and the behavior "skips" the other // marking instead of pushing it. - if( m_action == MoveLoopBegin ) + if( m_action == MoveLoopBegin ) m_loopPos[0] -= MidiTime::ticksPerTact(); else m_loopPos[1] += MidiTime::ticksPerTact(); diff --git a/src/gui/editors/SongEditor.cpp b/src/gui/editors/SongEditor.cpp index b397434b1..6e23fcdbe 100644 --- a/src/gui/editors/SongEditor.cpp +++ b/src/gui/editors/SongEditor.cpp @@ -76,11 +76,14 @@ SongEditor::SongEditor( Song * song ) : TrackContainerView( song ), m_song( song ), m_zoomingModel(new ComboBoxModel()), + m_snappingModel(new ComboBoxModel()), + m_proportionalSnap( false ), m_scrollBack( false ), m_smoothScroll( ConfigManager::inst()->value( "ui", "smoothscroll" ).toInt() ), m_mode(DrawMode) { m_zoomingModel->setParent(this); + m_snappingModel->setParent(this); // create time-line m_widgetWidthTotal = ConfigManager::inst()->value( "ui", "compacttrackbuttons" ).toInt()==1 ? @@ -230,7 +233,7 @@ SongEditor::SongEditor( Song * song ) : connect( m_song, SIGNAL( lengthChanged( int ) ), this, SLOT( updateScrollBar( int ) ) ); - // Set up zooming model + //Set up zooming model for( float const & zoomLevel : m_zoomLevels ) { m_zoomingModel->addItem( QString( "%1\%" ).arg( zoomLevel * 100 ) ); @@ -240,6 +243,24 @@ SongEditor::SongEditor( Song * song ) : connect( m_zoomingModel, SIGNAL( dataChanged() ), this, SLOT( zoomingChanged() ) ); + //Set up snapping model, 2^i + for ( int i = 3; i >= -4; i-- ) + { + if ( i > 0 ) + { + m_snappingModel->addItem( QString( "%1 Bars").arg( 1 << i ) ); + } + else if ( i == 0 ) + { + m_snappingModel->addItem( "1 Bar" ); + } + else + { + m_snappingModel->addItem( QString( "1/%1 Bar" ).arg( 1 << (-i) ) ); + } + } + m_snappingModel->setInitValue( m_snappingModel->findText( "1 Bar" ) ); + setFocusPolicy( Qt::StrongFocus ); setFocus(); } @@ -264,6 +285,48 @@ void SongEditor::loadSettings( const QDomElement& element ) +float SongEditor::getSnapSize() const +{ + // 1 Bar is the third value in the snapping dropdown + int val = -m_snappingModel->value() + 3; + // If proportional snap is on, we snap to finer values when zoomed in + if (m_proportionalSnap) + { + val = val - m_zoomingModel->value() + 3; + } + val = max(val, -6); // -6 gives 1/64th bar snapping. Lower values cause crashing. + + if ( val >= 0 ){ + return 1 << val; + } + else { + return 1.0 / ( 1 << -val ); + } +} + +QString SongEditor::getSnapSizeString() const +{ + int val = -m_snappingModel->value() + 3; + val = val - m_zoomingModel->value() + 3; + val = max(val, -6); // -6 gives 1/64th bar snapping. Lower values cause crashing. + + if ( val >= 0 ){ + int bars = 1 << val; + if ( bars == 1 ) { return QString("1 Bar"); } + else + { + return QString( "%1 Bars" ).arg(bars); + } + } + else { + int div = ( 1 << -val ); + return QString( "1/%1 Bar" ).arg(div); + } +} + + + + void SongEditor::setHighQuality( bool hq ) { Engine::mixer()->changeQuality( Mixer::qualitySettings( @@ -298,6 +361,11 @@ void SongEditor::setEditModeSelect() setEditMode(SelectMode); } +void SongEditor::toggleProportionalSnap() +{ + m_proportionalSnap = !m_proportionalSnap; +} + @@ -653,10 +721,19 @@ ComboBoxModel *SongEditor::zoomingModel() const +ComboBoxModel *SongEditor::snappingModel() const +{ + return m_snappingModel; +} + + + + SongEditorWindow::SongEditorWindow(Song* song) : Editor(Engine::mixer()->audioDev()->supportsCapture(), false), m_editor(new SongEditor(song)), - m_crtlAction( NULL ) + m_crtlAction( NULL ), + m_snapSizeLabel( new QLabel( m_toolBar ) ) { setWindowTitle( tr( "Song-Editor" ) ); setWindowIcon( embed::getIconPixmap( "songeditor" ) ); @@ -718,23 +795,63 @@ SongEditorWindow::SongEditorWindow(Song* song) : QLabel * zoom_lbl = new QLabel( m_toolBar ); zoom_lbl->setPixmap( embed::getIconPixmap( "zoom" ) ); - // setup zooming-stuff + //Set up zooming-stuff m_zoomingComboBox = new ComboBox( m_toolBar ); m_zoomingComboBox->setFixedSize( 80, 22 ); m_zoomingComboBox->move( 580, 4 ); m_zoomingComboBox->setModel(m_editor->m_zoomingModel); m_zoomingComboBox->setToolTip(tr("Horizontal zooming")); + connect(m_editor->zoomingModel(), SIGNAL(dataChanged()), this, SLOT(updateSnapLabel())); zoomToolBar->addWidget( zoom_lbl ); zoomToolBar->addWidget( m_zoomingComboBox ); + DropToolBar *snapToolBar = addDropToolBarToTop(tr("Snap controls")); + QLabel * snap_lbl = new QLabel( m_toolBar ); + snap_lbl->setPixmap( embed::getIconPixmap( "quantize" ) ); + + //Set up quantization/snapping selector + m_snappingComboBox = new ComboBox( m_toolBar ); + m_snappingComboBox->setFixedSize( 80, 22 ); + m_snappingComboBox->setModel(m_editor->m_snappingModel); + m_snappingComboBox->setToolTip(tr("Clip snapping size")); + connect(m_editor->snappingModel(), SIGNAL(dataChanged()), this, SLOT(updateSnapLabel())); + + m_setProportionalSnapAction = new QAction(embed::getIconPixmap("proportional_snap"), + tr("Toggle proportional snap on/off"), this); + m_setProportionalSnapAction->setCheckable(true); + m_setProportionalSnapAction->setChecked(false); + connect(m_setProportionalSnapAction, SIGNAL(triggered()), m_editor, SLOT(toggleProportionalSnap())); + connect(m_setProportionalSnapAction, SIGNAL(triggered()), this, SLOT(updateSnapLabel()) ); + + snapToolBar->addWidget( snap_lbl ); + snapToolBar->addWidget( m_snappingComboBox ); + snapToolBar->addSeparator(); + snapToolBar->addAction( m_setProportionalSnapAction ); + + snapToolBar->addSeparator(); + snapToolBar->addWidget( m_snapSizeLabel ); + connect(song, SIGNAL(projectLoaded()), this, SLOT(adjustUiAfterProjectLoad())); connect(this, SIGNAL(resized()), m_editor, SLOT(updatePositionLine())); } QSize SongEditorWindow::sizeHint() const { - return {600, 300}; + return {720, 300}; +} + +void SongEditorWindow::updateSnapLabel(){ + if (m_setProportionalSnapAction->isChecked()) + { + m_snapSizeLabel->setText(QString("Snap: ") + m_editor->getSnapSizeString()); + m_snappingComboBox->setToolTip(tr("Base snapping size")); + } + else + { + m_snappingComboBox->setToolTip(tr("Clip snapping size")); + m_snapSizeLabel->clear(); + } } diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index ea3c53602..4b51ef6ec 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -529,7 +529,7 @@ void SampleTCOView::paintEvent( QPaintEvent * pe ) float nom = Engine::getSong()->getTimeSigModel().getNumerator(); float den = Engine::getSong()->getTimeSigModel().getDenominator(); float ticksPerTact = DefaultTicksPerTact * nom / den; - + float offset = m_tco->startTimeOffset() / ticksPerTact * pixelsPerTact(); QRect r = QRect( TCO_BORDER_WIDTH + offset, spacing, qMax( static_cast( m_tco->sampleLength() * ppt / ticksPerTact ), 1 ), rect().bottom() - 2 * spacing ); @@ -931,7 +931,7 @@ void SampleTrackView::dropEvent(QDropEvent *de) ? MidiTime(0) : MidiTime(((xPos - trackHeadWidth) / trackContainerView()->pixelsPerTact() * MidiTime::ticksPerTact()) + trackContainerView()->currentPosition() - ).toNearestTact(); + ).quantize(1.0); SampleTCO * sTco = static_cast(getTrack()->createTCO(tcoPos)); if (sTco) { sTco->setSampleFile(value); } @@ -1192,4 +1192,3 @@ void SampleTrackWindow::loadSettings(const QDomElement& element) m_stv->m_tlb->setChecked(true); } } - From e206798c1e402846fbb72ed75a615fd2d94c0bfc Mon Sep 17 00:00:00 2001 From: Hussam al-Homsi Date: Mon, 29 Jul 2019 12:08:07 -0400 Subject: [PATCH 357/445] Use mean based logic for controlling loop points. (#4034) * Use median based logic for controlling loop points. * Limit controlling loop points to right mouse button. --- src/gui/TimeLineWidget.cpp | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/gui/TimeLineWidget.cpp b/src/gui/TimeLineWidget.cpp index 87e513e72..dfa7e388f 100644 --- a/src/gui/TimeLineWidget.cpp +++ b/src/gui/TimeLineWidget.cpp @@ -310,40 +310,36 @@ void TimeLineWidget::mousePressEvent( QMouseEvent* event ) m_action = SelectSongTCO; m_initalXSelect = event->x(); } - else if( event->button() == Qt::RightButton || event->button() == Qt::MiddleButton ) + else if( event->button() == Qt::RightButton ) { - m_moveXOff = s_posMarkerPixmap->width() / 2; - const MidiTime t = m_begin + static_cast( event->x() * MidiTime::ticksPerTact() / m_ppt ); + m_moveXOff = s_posMarkerPixmap->width() / 2; + const MidiTime t = m_begin + static_cast( qMax( event->x() - m_xOffset - m_moveXOff, 0 ) * MidiTime::ticksPerTact() / m_ppt ); + const MidiTime loopMid = ( m_loopPos[0] + m_loopPos[1] ) / 2; + + if( t < loopMid ) + { + m_action = MoveLoopBegin; + } + else if( t > loopMid ) + { + m_action = MoveLoopEnd; + } + if( m_loopPos[0] > m_loopPos[1] ) { qSwap( m_loopPos[0], m_loopPos[1] ); } - if( ( event->modifiers() & Qt::ShiftModifier ) || event->button() == Qt::MiddleButton ) - { - m_action = MoveLoopBegin; - } - else - { - m_action = MoveLoopEnd; - } + m_loopPos[( m_action == MoveLoopBegin ) ? 0 : 1] = t; } - if( m_action == MoveLoopBegin ) + if( m_action == MoveLoopBegin || m_action == MoveLoopEnd ) { delete m_hint; m_hint = TextFloat::displayMessage( tr( "Hint" ), tr( "Press <%1> to disable magnetic loop points." ).arg(UI_CTRL_KEY), embed::getIconPixmap( "hint" ), 0 ); } - else if( m_action == MoveLoopEnd ) - { - delete m_hint; - m_hint = TextFloat::displayMessage( tr( "Hint" ), - tr( "Hold to move the begin loop point; Press <%1> to disable magnetic loop points." ).arg(UI_CTRL_KEY), - embed::getIconPixmap( "hint" ), 0 ); - } - mouseMoveEvent( event ); } @@ -374,7 +370,7 @@ void TimeLineWidget::mouseMoveEvent( QMouseEvent* event ) case MoveLoopBegin: case MoveLoopEnd: { - const int i = m_action - MoveLoopBegin; + const int i = m_action - MoveLoopBegin; // i == 0 || i == 1 if( event->modifiers() & Qt::ControlModifier ) { // no ctrl-press-hint when having ctrl pressed From db200fb90c64e6e1354103c9317b949477f07cd4 Mon Sep 17 00:00:00 2001 From: Olivier Humbert Date: Tue, 30 Jul 2019 02:40:07 +0200 Subject: [PATCH 358/445] Create FUNDING.yml (#5057) --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..8a8b03635 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: https://lmms.io/get-involved/#donate From 0db83c55a0acef82d805abbbf6cd03bd96585797 Mon Sep 17 00:00:00 2001 From: Olivier Humbert Date: Wed, 31 Jul 2019 01:17:55 +0200 Subject: [PATCH 359/445] Better French translations in the menu item file (#4711) in order to stick with the original English meaning --- cmake/linux/lmms.desktop | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/linux/lmms.desktop b/cmake/linux/lmms.desktop index 2ef4c8148..94d171b5e 100644 --- a/cmake/linux/lmms.desktop +++ b/cmake/linux/lmms.desktop @@ -3,10 +3,10 @@ Name=LMMS GenericName=Music production suite GenericName[ca]=Programari de producció musical GenericName[de]=Software zur Musik-Produktion -GenericName[fr]=Ensemble pour la production musicale +GenericName[fr]=Suite de production musicale 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 ! +Comment[fr]=Séquenceur et synthétiseur de musique Icon=lmms Exec=lmms %f Terminal=false From 00d2cd304a26e04a4ec8619849298d239948b8bd Mon Sep 17 00:00:00 2001 From: Kun Deng Date: Tue, 13 Aug 2019 14:23:57 -0400 Subject: [PATCH 360/445] Fix for the SF2 with no "default" patch (#5084) Fixes #323 --- plugins/sf2_player/sf2_player.cpp | 44 ++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index 53d639f84..cc2575d2b 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -267,6 +267,43 @@ void sf2Instrument::loadFile( const QString & _file ) // soundfont for the first time fails updateSampleRate(); } + + // setting the first bank and patch number that is found + auto sSoundCount = ::fluid_synth_sfcount( m_synth ); + for ( int i = 0; i < sSoundCount; ++i ) { + int iBank = 0; + int iProg = 0; + fluid_sfont_t *pSoundFont = ::fluid_synth_get_sfont( m_synth, i ); + + if ( pSoundFont ) { +#ifdef CONFIG_FLUID_BANK_OFFSET + int iBankOff = ::fluid_synth_get_bank_offset( m_synth, fluid_sfont_get_id( pSoundFont ) ); +#endif + + fluid_sfont_iteration_start( pSoundFont ); +#if FLUIDSYNTH_VERSION_MAJOR < 2 + fluid_preset_t preset; + fluid_preset_t *pCurPreset = &preset; +#else + fluid_preset_t *pCurPreset; +#endif + + if ( ( pCurPreset = fluid_sfont_iteration_next_wrapper( pSoundFont, pCurPreset ) ) ) { + iBank = fluid_preset_get_banknum( pCurPreset ); + iProg = fluid_preset_get_num( pCurPreset ); + +#ifdef CONFIG_FLUID_BANK_OFFSET + iBank += iBankOff; +#endif + + ::fluid_synth_bank_select( m_synth, 1, iBank ); + ::fluid_synth_program_change( m_synth, 1, iProg ); + m_bankNum.setValue( iBank ); + m_patchNum.setValue ( iProg ); + break; + } + } + } } @@ -678,7 +715,6 @@ void sf2Instrument::noteOff( SF2PluginData * n ) fluid_synth_noteoff( m_synth, m_channel, n->midiNote ); m_synthMutex.unlock(); } - } @@ -694,7 +730,6 @@ void sf2Instrument::play( sampleFrame * _working_buffer ) m_synthMutex.lock(); fluid_synth_pitch_bend( m_synth, m_channel, m_lastMidiPitch ); m_synthMutex.unlock(); - } const int currentMidiPitchRange = instrumentTrack()->midiPitchRange(); @@ -1006,7 +1041,6 @@ sf2InstrumentView::sf2InstrumentView( Instrument * _instrument, QWidget * _paren setPalette( pal ); updateFilename(); - } @@ -1045,7 +1079,6 @@ void sf2InstrumentView::modelChanged() connect( k, SIGNAL( fileLoading() ), this, SLOT( invalidateFile() ) ); updateFilename(); - } @@ -1157,6 +1190,3 @@ PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) } - - - From e1ef5fad0d5d8ce9b74b0c970c128cb90d695783 Mon Sep 17 00:00:00 2001 From: Steffen Baranowsky Date: Sun, 18 Aug 2019 10:49:02 +0200 Subject: [PATCH 361/445] shows the vertical scrollbar of songeditor and bb-editor only if needed (#5102) --- src/gui/TrackContainerView.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/gui/TrackContainerView.cpp b/src/gui/TrackContainerView.cpp index 7c69d5eb8..649323c07 100644 --- a/src/gui/TrackContainerView.cpp +++ b/src/gui/TrackContainerView.cpp @@ -226,10 +226,9 @@ void TrackContainerView::scrollToTrackView( TrackView * _tv ) void TrackContainerView::realignTracks() { - QWidget * content = m_scrollArea->widget(); - content->setFixedWidth( width() - - m_scrollArea->verticalScrollBar()->width() ); - content->setFixedHeight( content->minimumSizeHint().height() ); + m_scrollArea->widget()->setFixedWidth(width()); + m_scrollArea->widget()->setFixedHeight( + m_scrollArea->widget()->minimumSizeHint().height()); for( trackViewList::iterator it = m_trackViews.begin(); it != m_trackViews.end(); ++it ) @@ -488,7 +487,6 @@ TrackContainerView::scrollArea::scrollArea( TrackContainerView * _parent ) : { setFrameStyle( QFrame::NoFrame ); setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); - setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn ); } From ce5c74432e83f0eaa617cc26332f4209bc4efc7f Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Tue, 20 Aug 2019 12:37:42 +0300 Subject: [PATCH 362/445] Update appveyor image to Visual Studio 2017 (#5130) --- .appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 3cb5d9a93..3b632d1f3 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,6 +1,6 @@ clone_depth: 1 version: "{build}" -image: Visual Studio 2015 +image: Visual Studio 2017 platform: - x86 - x64 @@ -16,7 +16,7 @@ build_script: - cd build - ps: $env:CMAKE_PLATFORM="$(if ($env:PLATFORM -eq 'x64') { 'x64' } else { '' })" - ps: $env:QT_SUFFIX="$(if ($env:PLATFORM -eq 'x64') { '_64' } else { '' })" - - cmake -DUSE_COMPILE_CACHE=ON -DCACHE_TOOL=%APPVEYOR_BUILD_FOLDER%/clcache.4.1.0/clcache-4.1.0/clcache.exe -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_PREFIX_PATH=c:/Qt/5.9/msvc2015%QT_SUFFIX%;c:/tools/vcpkg/installed/%PLATFORM%-windows -DCMAKE_GENERATOR_PLATFORM="%CMAKE_PLATFORM%" .. + - cmake -DUSE_COMPILE_CACHE=ON -DCACHE_TOOL=%APPVEYOR_BUILD_FOLDER%/clcache.4.1.0/clcache-4.1.0/clcache.exe -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_PREFIX_PATH=c:/Qt/5.12/msvc2017%QT_SUFFIX%;c:/tools/vcpkg/installed/%PLATFORM%-windows -DCMAKE_GENERATOR_PLATFORM="%CMAKE_PLATFORM%" .. - cmake --build . -- /maxcpucount:4 - cmake --build . --target tests cache: From c80519e65e84d06fa237921a6a128b2e1f55c6b3 Mon Sep 17 00:00:00 2001 From: Kevin Zander Date: Tue, 20 Aug 2019 23:41:33 -0500 Subject: [PATCH 363/445] Allow playing muted pattern in the piano roll (#5134) --- src/tracks/InstrumentTrack.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 931e3d327..730ab97bd 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -652,8 +652,11 @@ bool InstrumentTrack::play( const MidiTime & _start, const fpp_t _frames, for( tcoVector::Iterator it = tcos.begin(); it != tcos.end(); ++it ) { Pattern* p = dynamic_cast( *it ); - // everything which is not a pattern or muted won't be played - if( p == NULL || ( *it )->isMuted() ) + // everything which is not a pattern won't be played + // A pattern playing in the Piano Roll window will always play + if(p == NULL || + (Engine::getSong()->playMode() != Song::Mode_PlayPattern + && (*it)->isMuted())) { continue; } From 93f9134c453c5a17791f37b9fcdee828137c27b6 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Fri, 23 Aug 2019 18:38:46 +0100 Subject: [PATCH 364/445] Fix crash opening VST automation window (#5144) The VST automation window initially adds a subwindow with a null widget, so we have to check that w isn't nullptr before getting its size hint. Fixes #5132. --- src/gui/MainWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index cc5f48874..c516b6a78 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -625,7 +625,7 @@ SubWindow* MainWindow::addWindowedWidget(QWidget *w, Qt::WindowFlags windowFlags SubWindow *win = new SubWindow(m_workspace->viewport(), windowFlags); win->setAttribute(Qt::WA_DeleteOnClose); win->setWidget(w); - if (w->sizeHint().isValid()) {win->resize(w->sizeHint());} + if (w && w->sizeHint().isValid()) {win->resize(w->sizeHint());} m_workspace->addSubWindow(win); return win; } From a8638307953515f79f98cc53f4c5ae643213c6bb Mon Sep 17 00:00:00 2001 From: Winnie Date: Sat, 24 Aug 2019 09:33:52 +0200 Subject: [PATCH 365/445] Extract TemplatesMenu class from MainWindow (#5125) --- include/MainWindow.h | 4 -- include/TemplatesMenu.h | 23 +++++++++++ src/gui/CMakeLists.txt | 2 + src/gui/MainWindow.cpp | 64 ++--------------------------- src/gui/menus/TemplatesMenu.cpp | 73 +++++++++++++++++++++++++++++++++ 5 files changed, 102 insertions(+), 64 deletions(-) create mode 100644 include/TemplatesMenu.h create mode 100644 src/gui/menus/TemplatesMenu.cpp diff --git a/include/MainWindow.h b/include/MainWindow.h index 531cdfd52..22a29d0e2 100644 --- a/include/MainWindow.h +++ b/include/MainWindow.h @@ -148,7 +148,6 @@ public slots: void emptySlot(); void createNewProject(); - void createNewProjectFromTemplate( QAction * _idx ); void openProject(); bool saveProject(); bool saveProjectAs(); @@ -204,9 +203,7 @@ private: QWidget * m_toolBar; QGridLayout * m_toolBarLayout; - QMenu * m_templatesMenu; QMenu * m_recentlyOpenedProjectsMenu; - int m_custom_templates_count; struct keyModifiers { @@ -240,7 +237,6 @@ private: private slots: void browseHelp(); - void fillTemplatesMenu(); void openRecentlyOpenedProject( QAction * _action ); void showTool( QAction * _idx ); void updateRecentlyOpenedProjectsMenu(); diff --git a/include/TemplatesMenu.h b/include/TemplatesMenu.h new file mode 100644 index 000000000..b686ee60e --- /dev/null +++ b/include/TemplatesMenu.h @@ -0,0 +1,23 @@ +#ifndef TEMPLATESMENU_H +#define TEMPLATESMENU_H + +#include +#include + +class TemplatesMenu : public QMenu +{ + Q_OBJECT +public: + TemplatesMenu(QWidget *parent = nullptr); + virtual ~TemplatesMenu() = default; + +private slots: + void createNewProjectFromTemplate( QAction * _idx ); + void fillTemplatesMenu(); + int addTemplatesFromDir( const QDir& dir ); + +private: + int m_customTemplatesCount; +}; + +#endif // TEMPLATESMENU_H diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index f17ef105f..84dc19935 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -43,6 +43,8 @@ SET(LMMS_SRCS gui/editors/PianoRoll.cpp gui/editors/SongEditor.cpp + gui/menus/TemplatesMenu.cpp + gui/widgets/AutomatableButton.cpp gui/widgets/AutomatableSlider.cpp gui/widgets/CaptionMenu.cpp diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index c516b6a78..4021b68e0 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -61,6 +61,7 @@ #include "SetupDialog.h" #include "SideBar.h" #include "SongEditor.h" +#include "TemplatesMenu.h" #include "TextFloat.h" #include "TimeLineWidget.h" #include "ToolButton.h" @@ -88,7 +89,6 @@ void disableAutoKeyAccelerators(QWidget* mainWindow) MainWindow::MainWindow() : m_workspace( NULL ), - m_templatesMenu( NULL ), m_recentlyOpenedProjectsMenu( NULL ), m_toolsMenu( NULL ), m_autoSaveTimer( this ), @@ -277,12 +277,8 @@ void MainWindow::finalize() this, SLOT( createNewProject() ), QKeySequence::New ); - m_templatesMenu = new QMenu( tr("New from template"), this ); - connect( m_templatesMenu, SIGNAL( aboutToShow() ), SLOT( fillTemplatesMenu() ) ); - connect( m_templatesMenu, SIGNAL( triggered( QAction * ) ), - SLOT( createNewProjectFromTemplate( QAction * ) ) ); - - project_menu->addMenu(m_templatesMenu); + auto templates_menu = new TemplatesMenu( this ); + project_menu->addMenu(templates_menu); project_menu->addAction( embed::getIconPixmap( "project_open" ), tr( "&Open..." ), @@ -429,7 +425,7 @@ void MainWindow::finalize() tr( "Create new project from template" ), this, SLOT( emptySlot() ), m_toolBar ); - project_new_from_template->setMenu( m_templatesMenu ); + project_new_from_template->setMenu( templates_menu ); project_new_from_template->setPopupMode( ToolButton::InstantPopup ); ToolButton * project_open = new ToolButton( @@ -809,24 +805,6 @@ void MainWindow::createNewProject() -void MainWindow::createNewProjectFromTemplate( QAction * _idx ) -{ - if( m_templatesMenu && mayChangeProject(true) ) - { - int indexOfTemplate = m_templatesMenu->actions().indexOf( _idx ); - bool isFactoryTemplate = indexOfTemplate >= m_custom_templates_count; - QString dirBase = isFactoryTemplate ? - ConfigManager::inst()->factoryTemplatesDir() : - ConfigManager::inst()->userTemplateDir(); - - const QString f = dirBase + _idx->text().replace("&&", "&") + ".mpt"; - Engine::getSong()->createNewProjectFromTemplate(f); - } -} - - - - void MainWindow::openProject() { if( mayChangeProject(false) ) @@ -1448,40 +1426,6 @@ void MainWindow::timerEvent( QTimerEvent * _te) -void MainWindow::fillTemplatesMenu() -{ - m_templatesMenu->clear(); - - auto addTemplatesFromDir = [this]( QDir dir ) { - QStringList templates = dir.entryList( QStringList( "*.mpt" ), - QDir::Files | QDir::Readable ); - - if ( templates.size() && ! m_templatesMenu->actions().isEmpty() ) - { - m_templatesMenu->addSeparator(); - } - - for( QStringList::iterator it = templates.begin(); - it != templates.end(); ++it ) - { - m_templatesMenu->addAction( - embed::getIconPixmap( "project_file" ), - ( *it ).left( ( *it ).length() - 4 ).replace("&", "&&") ); -#ifdef LMMS_BUILD_APPLE - m_templatesMenu->actions().last()->setIconVisibleInMenu(false); // QTBUG-44565 workaround - m_templatesMenu->actions().last()->setIconVisibleInMenu(true); -#endif - } - - return templates.size(); - }; - - m_custom_templates_count = addTemplatesFromDir( ConfigManager::inst()->userTemplateDir() ); - addTemplatesFromDir( ConfigManager::inst()->factoryProjectsDir() + "templates" ); -} - - - void MainWindow::showTool( QAction * _idx ) { diff --git a/src/gui/menus/TemplatesMenu.cpp b/src/gui/menus/TemplatesMenu.cpp new file mode 100644 index 000000000..b1cca87ab --- /dev/null +++ b/src/gui/menus/TemplatesMenu.cpp @@ -0,0 +1,73 @@ +#include "TemplatesMenu.h" +#include "GuiApplication.h" +#include "ConfigManager.h" +#include "Engine.h" +#include "embed.h" +#include "MainWindow.h" +#include "Song.h" + +TemplatesMenu::TemplatesMenu(QWidget *parent) : + QMenu(tr("New from template"), parent), + m_customTemplatesCount(0) +{ + connect( this, SIGNAL( aboutToShow() ), SLOT( fillTemplatesMenu() ) ); + connect( this, SIGNAL( triggered( QAction * ) ), + SLOT( createNewProjectFromTemplate( QAction * ) ) ); +} + + + + +void TemplatesMenu::createNewProjectFromTemplate( QAction * _idx ) +{ + if( gui->mainWindow()->mayChangeProject(true) ) + { + int indexOfTemplate = actions().indexOf( _idx ); + bool isFactoryTemplate = indexOfTemplate >= m_customTemplatesCount; + QString dirBase = isFactoryTemplate ? + ConfigManager::inst()->factoryTemplatesDir() : + ConfigManager::inst()->userTemplateDir(); + + const QString f = dirBase + _idx->text().replace("&&", "&") + ".mpt"; + Engine::getSong()->createNewProjectFromTemplate(f); + } +} + + + + + +void TemplatesMenu::fillTemplatesMenu() +{ + clear(); + + m_customTemplatesCount = addTemplatesFromDir(ConfigManager::inst()->userTemplateDir() ); + addTemplatesFromDir( ConfigManager::inst()->factoryProjectsDir() + "templates" ); +} + + + + +int TemplatesMenu::addTemplatesFromDir( const QDir& dir ) { + QStringList templates = dir.entryList( QStringList( "*.mpt" ), + QDir::Files | QDir::Readable ); + + if ( templates.size() && ! actions().isEmpty() ) + { + addSeparator(); + } + + for( QStringList::iterator it = templates.begin(); + it != templates.end(); ++it ) + { + addAction( + embed::getIconPixmap( "project_file" ), + ( *it ).left( ( *it ).length() - 4 ).replace("&", "&&") ); +#ifdef LMMS_BUILD_APPLE + actions().last()->setIconVisibleInMenu(false); // QTBUG-44565 workaround + actions().last()->setIconVisibleInMenu(true); +#endif + } + + return templates.size(); +} From 2cdb9f2f38a0b20f67d024e292fe06ee4f868c77 Mon Sep 17 00:00:00 2001 From: Winnie Date: Sat, 24 Aug 2019 18:55:30 +0200 Subject: [PATCH 366/445] Extract RecentProjectsMenu class from MainWindow (#5148) * Extract RecentProjectsMenu class from MainWindow * Clean up updateRecentlyOpenedProjectsMenu * Remove m_recentlyOpenedProjectsMenu from MainWindow --- include/MainWindow.h | 4 -- include/RecentProjectsMenu.h | 17 ++++++ src/gui/CMakeLists.txt | 1 + src/gui/MainWindow.cpp | 62 ++-------------------- src/gui/menus/RecentProjectsMenu.cpp | 77 ++++++++++++++++++++++++++++ 5 files changed, 98 insertions(+), 63 deletions(-) create mode 100644 include/RecentProjectsMenu.h create mode 100644 src/gui/menus/RecentProjectsMenu.cpp diff --git a/include/MainWindow.h b/include/MainWindow.h index 22a29d0e2..74e569653 100644 --- a/include/MainWindow.h +++ b/include/MainWindow.h @@ -203,8 +203,6 @@ private: QWidget * m_toolBar; QGridLayout * m_toolBarLayout; - QMenu * m_recentlyOpenedProjectsMenu; - struct keyModifiers { keyModifiers() : @@ -237,9 +235,7 @@ private: private slots: void browseHelp(); - void openRecentlyOpenedProject( QAction * _action ); void showTool( QAction * _idx ); - void updateRecentlyOpenedProjectsMenu(); void updateViewMenu( void ); void updateConfig( QAction * _who ); void onToggleMetronome(); diff --git a/include/RecentProjectsMenu.h b/include/RecentProjectsMenu.h new file mode 100644 index 000000000..b3837ee2e --- /dev/null +++ b/include/RecentProjectsMenu.h @@ -0,0 +1,17 @@ +#ifndef RECENTPROJECTSMENU_H +#define RECENTPROJECTSMENU_H + +#include + +class RecentProjectsMenu : public QMenu +{ + Q_OBJECT +public: + RecentProjectsMenu(QWidget *parent = nullptr); + +private slots: + void fillMenu(); + void openProject(QAction * _action ); +}; + +#endif // RECENTPROJECTSMENU_H diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 84dc19935..af316fddb 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -43,6 +43,7 @@ SET(LMMS_SRCS gui/editors/PianoRoll.cpp gui/editors/SongEditor.cpp + gui/menus/RecentProjectsMenu.cpp gui/menus/TemplatesMenu.cpp gui/widgets/AutomatableButton.cpp diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 4021b68e0..0914d1685 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -57,6 +57,7 @@ #include "ProjectJournal.h" #include "ProjectNotes.h" #include "ProjectRenderer.h" +#include "RecentProjectsMenu.h" #include "RemotePlugin.h" #include "SetupDialog.h" #include "SideBar.h" @@ -89,7 +90,6 @@ void disableAutoKeyAccelerators(QWidget* mainWindow) MainWindow::MainWindow() : m_workspace( NULL ), - m_recentlyOpenedProjectsMenu( NULL ), m_toolsMenu( NULL ), m_autoSaveTimer( this ), m_viewMenu( NULL ), @@ -285,13 +285,7 @@ void MainWindow::finalize() this, SLOT( openProject() ), QKeySequence::Open ); - m_recentlyOpenedProjectsMenu = project_menu->addMenu( - embed::getIconPixmap( "project_open_recent" ), - tr( "&Recently Opened Projects" ) ); - connect( m_recentlyOpenedProjectsMenu, SIGNAL( aboutToShow() ), - this, SLOT( updateRecentlyOpenedProjectsMenu() ) ); - connect( m_recentlyOpenedProjectsMenu, SIGNAL( triggered( QAction * ) ), - this, SLOT( openRecentlyOpenedProject( QAction * ) ) ); + project_menu->addMenu(new RecentProjectsMenu(this)); project_menu->addAction( embed::getIconPixmap( "project_save" ), tr( "&Save" ), @@ -439,7 +433,7 @@ void MainWindow::finalize() embed::getIconPixmap( "project_open_recent" ), tr( "Recently opened projects" ), this, SLOT( emptySlot() ), m_toolBar ); - project_open_recent->setMenu( m_recentlyOpenedProjectsMenu ); + project_open_recent->setMenu( new RecentProjectsMenu(this) ); project_open_recent->setPopupMode( ToolButton::InstantPopup ); ToolButton * project_save = new ToolButton( @@ -829,56 +823,6 @@ void MainWindow::openProject() -void MainWindow::updateRecentlyOpenedProjectsMenu() -{ - m_recentlyOpenedProjectsMenu->clear(); - QStringList rup = ConfigManager::inst()->recentlyOpenedProjects(); - -// The file history goes 50 deep but we only show the 15 -// most recent ones that we can open and omit .mpt files. - int shownInMenu = 0; - for( QStringList::iterator it = rup.begin(); it != rup.end(); ++it ) - { - QFileInfo recentFile( *it ); - if ( recentFile.exists() && - *it != ConfigManager::inst()->recoveryFile() ) - { - if( recentFile.suffix().toLower() == "mpt" ) - { - continue; - } - - m_recentlyOpenedProjectsMenu->addAction( - embed::getIconPixmap( "project_file" ), it->replace("&", "&&") ); -#ifdef LMMS_BUILD_APPLE - m_recentlyOpenedProjectsMenu->actions().last()->setIconVisibleInMenu(false); // QTBUG-44565 workaround - m_recentlyOpenedProjectsMenu->actions().last()->setIconVisibleInMenu(true); -#endif - shownInMenu++; - if( shownInMenu >= 15 ) - { - return; - } - } - } -} - - - -void MainWindow::openRecentlyOpenedProject( QAction * _action ) -{ - if ( mayChangeProject(true) ) - { - const QString f = _action->text().replace("&&", "&"); - setCursor( Qt::WaitCursor ); - Engine::getSong()->loadProject( f ); - setCursor( Qt::ArrowCursor ); - } -} - - - - bool MainWindow::saveProject() { if( Engine::getSong()->projectFileName() == "" ) diff --git a/src/gui/menus/RecentProjectsMenu.cpp b/src/gui/menus/RecentProjectsMenu.cpp new file mode 100644 index 000000000..7c09c14aa --- /dev/null +++ b/src/gui/menus/RecentProjectsMenu.cpp @@ -0,0 +1,77 @@ +#include "RecentProjectsMenu.h" + +#include + +#include "ConfigManager.h" +#include "Engine.h" +#include "Song.h" + +#include "embed.h" +#include "GuiApplication.h" +#include "MainWindow.h" + +RecentProjectsMenu::RecentProjectsMenu(QWidget *parent) : + QMenu(tr( "&Recently Opened Projects" ), parent) +{ + setIcon(embed::getIconPixmap( "project_open_recent" )); + + connect( this, SIGNAL( aboutToShow() ), + this, SLOT(fillMenu() ) ); + connect( this, SIGNAL( triggered( QAction * ) ), + this, SLOT(openProject(QAction * ) ) ); +} + + + + +void RecentProjectsMenu::fillMenu() +{ + clear(); + QStringList rup = ConfigManager::inst()->recentlyOpenedProjects(); + + auto projectFileIcon = embed::getIconPixmap( "project_file" ); + + // The file history goes 50 deep but we only show the 15 + // most recent ones that we can open and omit .mpt files. + int shownInMenu = 0; + for(QString& fileName : rup) + { + QFileInfo recentFile(fileName); + if (!recentFile.exists() || + fileName == ConfigManager::inst()->recoveryFile() ) + { + continue; + } + + if( recentFile.suffix().toLower() == "mpt" ) + { + continue; + } + + addAction(projectFileIcon, fileName.replace("&", "&&") ); +#ifdef LMMS_BUILD_APPLE + actions().last()->setIconVisibleInMenu(false); // QTBUG-44565 workaround + actions().last()->setIconVisibleInMenu(true); +#endif + + shownInMenu++; + if( shownInMenu >= 15 ) + { + break; + } + } +} + + + + +void RecentProjectsMenu::openProject(QAction * _action ) +{ + if ( gui->mainWindow()->mayChangeProject(true) ) + { + const QString f = _action->text().replace("&&", "&"); + setCursor( Qt::WaitCursor ); + Engine::getSong()->loadProject( f ); + setCursor( Qt::ArrowCursor ); + } +} From a631c0c47e73f2e1ae0d91fd2ae1a8ba0428ab7f Mon Sep 17 00:00:00 2001 From: Artur Twardowski <32247490+artur-twardowski@users.noreply.github.com> Date: Mon, 26 Aug 2019 03:05:59 +0200 Subject: [PATCH 367/445] Fix invalid MIDI Program Change decoding (#5154) --- src/core/midi/MidiAlsaSeq.cpp | 10 +++++----- src/core/midi/MidiClient.cpp | 6 +++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/core/midi/MidiAlsaSeq.cpp b/src/core/midi/MidiAlsaSeq.cpp index e420ebc08..56fd956d4 100644 --- a/src/core/midi/MidiAlsaSeq.cpp +++ b/src/core/midi/MidiAlsaSeq.cpp @@ -563,7 +563,7 @@ void MidiAlsaSeq::run() case SND_SEQ_EVENT_CONTROLLER: dest->processInEvent( MidiEvent( - MidiControlChange, + MidiControlChange, ev->data.control.channel, ev->data.control.param, ev->data.control.value, source ), @@ -572,11 +572,11 @@ void MidiAlsaSeq::run() case SND_SEQ_EVENT_PGMCHANGE: dest->processInEvent( MidiEvent( - MidiProgramChange, + MidiProgramChange, ev->data.control.channel, - ev->data.control.param, - ev->data.control.value, source ), - MidiTime() ); + ev->data.control.value, 0, + source ), + MidiTime() ); break; case SND_SEQ_EVENT_CHANPRESS: diff --git a/src/core/midi/MidiClient.cpp b/src/core/midi/MidiClient.cpp index b88c64db1..e22daf235 100644 --- a/src/core/midi/MidiClient.cpp +++ b/src/core/midi/MidiClient.cpp @@ -222,12 +222,16 @@ void MidiClientRaw::parseData( const unsigned char c ) case MidiNoteOff: case MidiNoteOn: case MidiKeyPressure: - case MidiProgramChange: case MidiChannelPressure: m_midiParseData.m_midiEvent.setKey( m_midiParseData.m_buffer[0] - KeysPerOctave ); m_midiParseData.m_midiEvent.setVelocity( m_midiParseData.m_buffer[1] ); break; + case MidiProgramChange: + m_midiParseData.m_midiEvent.setKey( m_midiParseData.m_buffer[0] ); + m_midiParseData.m_midiEvent.setVelocity( m_midiParseData.m_buffer[1] ); + break; + case MidiControlChange: m_midiParseData.m_midiEvent.setControllerNumber( m_midiParseData.m_buffer[0] ); m_midiParseData.m_midiEvent.setControllerValue( m_midiParseData.m_buffer[1] ); From 4c2d8941dc6661f31e899f0079cc8c35cd992d9d Mon Sep 17 00:00:00 2001 From: RossGammon Date: Mon, 26 Aug 2019 03:09:05 +0200 Subject: [PATCH 368/445] Fix some spelling errors in lmms (#5151) --- plugins/monstro/Monstro.cpp | 2 +- plugins/sid/envelope.cc | 2 +- src/core/audio/AudioPulseAudio.cpp | 2 +- src/core/main.cpp | 2 +- src/gui/widgets/EnvelopeAndLfoView.cpp | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/monstro/Monstro.cpp b/plugins/monstro/Monstro.cpp index acfd59b29..efb351fc8 100644 --- a/plugins/monstro/Monstro.cpp +++ b/plugins/monstro/Monstro.cpp @@ -328,7 +328,7 @@ void MonstroSynth::renderOutput( fpp_t _frames, sampleFrame * _buf ) float o1l_f; float o1r_f; float o1l_p = m_osc1l_phase + o1lpo; // we add phase offset here so we don't have to do it every frame - float o1r_p = m_osc1r_phase + o1rpo; // then substract it again after loop... + float o1r_p = m_osc1r_phase + o1rpo; // then subtract it again after loop... float o1_pw; // osc2 vars diff --git a/plugins/sid/envelope.cc b/plugins/sid/envelope.cc index 7be289c53..e466bd67d 100644 --- a/plugins/sid/envelope.cc +++ b/plugins/sid/envelope.cc @@ -134,7 +134,7 @@ reg16 EnvelopeGenerator::rate_counter_period[] = { // of ENV3 with another timed loop to fully synchronize with ENV3. // // At the first period when an exponential counter period larger than one -// is used (decay or relase), one extra cycle is spent before the envelope is +// is used (decay or release), one extra cycle is spent before the envelope is // decremented. The envelope output is then delayed one cycle until the state // is changed to attack. Now one cycle less will be spent before the envelope // is incremented, and the situation is normalized. diff --git a/src/core/audio/AudioPulseAudio.cpp b/src/core/audio/AudioPulseAudio.cpp index 050086c60..857ef981b 100644 --- a/src/core/audio/AudioPulseAudio.cpp +++ b/src/core/audio/AudioPulseAudio.cpp @@ -139,7 +139,7 @@ static void stream_state_callback( pa_stream *s, void * userdata ) case PA_STREAM_FAILED: default: - qCritical( "Stream errror: %s\n", + qCritical( "Stream error: %s\n", pa_strerror(pa_context_errno( pa_stream_get_context( s ) ) ) ); } diff --git a/src/core/main.cpp b/src/core/main.cpp index f579ec8f6..1a1d61d8c 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -165,7 +165,7 @@ void printHelp() " rendertracks [options...] Render each track to a different file\n" " upgrade [out] Upgrade file and save as \n" " Standard out is used if no output file\n" - " is specifed\n" + " is specified\n" "\nGlobal options:\n" " --allowroot Bypass root user startup check (use with\n" " caution).\n" diff --git a/src/gui/widgets/EnvelopeAndLfoView.cpp b/src/gui/widgets/EnvelopeAndLfoView.cpp index cdad83d4f..4635dc831 100644 --- a/src/gui/widgets/EnvelopeAndLfoView.cpp +++ b/src/gui/widgets/EnvelopeAndLfoView.cpp @@ -419,8 +419,8 @@ void EnvelopeAndLfoView::paintEvent( QPaintEvent * ) p.fillRect( x5, y_base - 1, 2, 2, end_points_color ); - int LFO_GRAPH_W = s_lfoGraph->width() - 3; // substract border - int LFO_GRAPH_H = s_lfoGraph->height() - 6; // substract border + int LFO_GRAPH_W = s_lfoGraph->width() - 3; // subtract border + int LFO_GRAPH_H = s_lfoGraph->height() - 6; // subtract border int graph_x_base = LFO_GRAPH_X + 2; int graph_y_base = LFO_GRAPH_Y + 3 + LFO_GRAPH_H / 2; From 605aef7afc01a2355d6a56373177e9c60dcca451 Mon Sep 17 00:00:00 2001 From: Winnie Date: Mon, 26 Aug 2019 03:33:25 +0200 Subject: [PATCH 369/445] Fix loading state for recent projects menu (#5152) --- src/gui/menus/RecentProjectsMenu.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/menus/RecentProjectsMenu.cpp b/src/gui/menus/RecentProjectsMenu.cpp index 7c09c14aa..6f32b0df5 100644 --- a/src/gui/menus/RecentProjectsMenu.cpp +++ b/src/gui/menus/RecentProjectsMenu.cpp @@ -67,11 +67,12 @@ void RecentProjectsMenu::fillMenu() void RecentProjectsMenu::openProject(QAction * _action ) { - if ( gui->mainWindow()->mayChangeProject(true) ) + auto mainWindow = gui->mainWindow(); + if (mainWindow->mayChangeProject(true)) { const QString f = _action->text().replace("&&", "&"); - setCursor( Qt::WaitCursor ); + mainWindow->setCursor( Qt::WaitCursor ); Engine::getSong()->loadProject( f ); - setCursor( Qt::ArrowCursor ); + mainWindow->setCursor( Qt::ArrowCursor ); } } From 8568ae4eacdd3bbdae8e8eaeb1536bebce3cfeeb Mon Sep 17 00:00:00 2001 From: Spekular Date: Tue, 27 Aug 2019 15:24:13 +0200 Subject: [PATCH 370/445] Make splash screen text white (#5149) Make splash screen text white Closes #5023 --- data/themes/default/style.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/data/themes/default/style.css b/data/themes/default/style.css index cd74c349d..a9af1139f 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -81,6 +81,12 @@ TextFloat { } +/* splash screen text */ +QSplashScreen QLabel { + color: white; +} + + QMenu { border-top: 2px solid #08993E; background-color: #15191c; From e803a31a906d701a51724c211ca4aedee996452b Mon Sep 17 00:00:00 2001 From: Winnie Date: Wed, 28 Aug 2019 22:51:54 +0200 Subject: [PATCH 371/445] Simplify TemplatesMenu class (#5155) --- include/TemplatesMenu.h | 6 ++-- src/gui/menus/TemplatesMenu.cpp | 50 +++++++++++++++------------------ 2 files changed, 24 insertions(+), 32 deletions(-) diff --git a/include/TemplatesMenu.h b/include/TemplatesMenu.h index b686ee60e..049f1f47e 100644 --- a/include/TemplatesMenu.h +++ b/include/TemplatesMenu.h @@ -12,12 +12,10 @@ public: virtual ~TemplatesMenu() = default; private slots: - void createNewProjectFromTemplate( QAction * _idx ); + static void createNewProjectFromTemplate(QAction * _action); void fillTemplatesMenu(); - int addTemplatesFromDir( const QDir& dir ); + void addTemplatesFromDir( const QDir& dir ); -private: - int m_customTemplatesCount; }; #endif // TEMPLATESMENU_H diff --git a/src/gui/menus/TemplatesMenu.cpp b/src/gui/menus/TemplatesMenu.cpp index b1cca87ab..5fb740203 100644 --- a/src/gui/menus/TemplatesMenu.cpp +++ b/src/gui/menus/TemplatesMenu.cpp @@ -1,14 +1,15 @@ #include "TemplatesMenu.h" -#include "GuiApplication.h" + #include "ConfigManager.h" #include "Engine.h" -#include "embed.h" -#include "MainWindow.h" #include "Song.h" +#include "embed.h" +#include "GuiApplication.h" +#include "MainWindow.h" + TemplatesMenu::TemplatesMenu(QWidget *parent) : - QMenu(tr("New from template"), parent), - m_customTemplatesCount(0) + QMenu(tr("New from template"), parent) { connect( this, SIGNAL( aboutToShow() ), SLOT( fillTemplatesMenu() ) ); connect( this, SIGNAL( triggered( QAction * ) ), @@ -18,18 +19,12 @@ TemplatesMenu::TemplatesMenu(QWidget *parent) : -void TemplatesMenu::createNewProjectFromTemplate( QAction * _idx ) +void TemplatesMenu::createNewProjectFromTemplate(QAction * _action) { if( gui->mainWindow()->mayChangeProject(true) ) { - int indexOfTemplate = actions().indexOf( _idx ); - bool isFactoryTemplate = indexOfTemplate >= m_customTemplatesCount; - QString dirBase = isFactoryTemplate ? - ConfigManager::inst()->factoryTemplatesDir() : - ConfigManager::inst()->userTemplateDir(); - - const QString f = dirBase + _idx->text().replace("&&", "&") + ".mpt"; - Engine::getSong()->createNewProjectFromTemplate(f); + const QString& templateFilePath = _action->data().toString(); + Engine::getSong()->createNewProjectFromTemplate(templateFilePath); } } @@ -41,33 +36,32 @@ void TemplatesMenu::fillTemplatesMenu() { clear(); - m_customTemplatesCount = addTemplatesFromDir(ConfigManager::inst()->userTemplateDir() ); - addTemplatesFromDir( ConfigManager::inst()->factoryProjectsDir() + "templates" ); + addTemplatesFromDir(ConfigManager::inst()->userTemplateDir()); + addTemplatesFromDir(ConfigManager::inst()->factoryProjectsDir() + "templates"); } -int TemplatesMenu::addTemplatesFromDir( const QDir& dir ) { - QStringList templates = dir.entryList( QStringList( "*.mpt" ), +void TemplatesMenu::addTemplatesFromDir( const QDir& dir ) { + QFileInfoList templates = dir.entryInfoList( QStringList( "*.mpt" ), QDir::Files | QDir::Readable ); - if ( templates.size() && ! actions().isEmpty() ) + if (!templates.empty() && !actions().isEmpty()) { addSeparator(); } - for( QStringList::iterator it = templates.begin(); - it != templates.end(); ++it ) + auto projectFileIcon = embed::getIconPixmap( "project_file" ); + + for(const QFileInfo& templateFile : templates) { - addAction( - embed::getIconPixmap( "project_file" ), - ( *it ).left( ( *it ).length() - 4 ).replace("&", "&&") ); + auto action = addAction(projectFileIcon, + templateFile.completeBaseName().replace("&", "&&")); + action->setData(templateFile.absoluteFilePath()); #ifdef LMMS_BUILD_APPLE - actions().last()->setIconVisibleInMenu(false); // QTBUG-44565 workaround - actions().last()->setIconVisibleInMenu(true); + action->setIconVisibleInMenu(false); // QTBUG-44565 workaround + action->setIconVisibleInMenu(true); #endif } - - return templates.size(); } From c2eefe73d049ae92398da288acdc3d71c3592504 Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+DouglasDGI@users.noreply.github.com> Date: Fri, 30 Aug 2019 16:36:04 -0600 Subject: [PATCH 372/445] Prevent LMMS VisualizationWidget from showing clipping color at exactly 0 db (#5162) --- src/gui/widgets/VisualizationWidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/VisualizationWidget.cpp b/src/gui/widgets/VisualizationWidget.cpp index 7234331df..635f96896 100644 --- a/src/gui/widgets/VisualizationWidget.cpp +++ b/src/gui/widgets/VisualizationWidget.cpp @@ -210,7 +210,7 @@ QColor const & VisualizationWidget::determineLineColor(float level) const { return normalColor(); } - else if( level < 1.0f ) + else if( level <= 1.0f ) { return warningColor(); } From 4fd8e08f3bd02f173e97bb721a30565f17cd1dbc Mon Sep 17 00:00:00 2001 From: Lukas W Date: Wed, 13 Jun 2018 16:32:57 +0200 Subject: [PATCH 373/445] Rewrite CMake dependency installation Replaces the hard-coded library paths by a method based on CMake's GetPrerequisites module which recursively finds a binary file's linked libraries. Advantage: Potentially works on any system without adaption as long as CMake supports it, so it could be used to create portable Linux packages as well. Disadvantage: "Potentially". Co-Authored-By: Hyunjin Song --- CMakeLists.txt | 5 +- cmake/install/CMakeLists.txt | 125 ++++++++++++++ cmake/install/excludelist-win | 23 +++ cmake/modules/BuildPlugin.cmake | 8 +- cmake/modules/InstallDependencies.cmake | 184 ++++++++++++++++++++ cmake/postinstall/CMakeLists.txt | 4 - plugins/zynaddsubfx/CMakeLists.txt | 2 + src/CMakeLists.txt | 220 ++---------------------- 8 files changed, 359 insertions(+), 212 deletions(-) create mode 100644 cmake/install/CMakeLists.txt create mode 100644 cmake/install/excludelist-win create mode 100644 cmake/modules/InstallDependencies.cmake delete mode 100644 cmake/postinstall/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index bd9d376e2..590a20c98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ IF(COMMAND CMAKE_POLICY) CMAKE_POLICY(SET CMP0050 OLD) ENDIF() CMAKE_POLICY(SET CMP0020 NEW) + CMAKE_POLICY(SET CMP0057 NEW) ENDIF(COMMAND CMAKE_POLICY) INCLUDE(CheckSubmodules) @@ -565,8 +566,8 @@ ADD_SUBDIRECTORY(tests) ADD_SUBDIRECTORY(data) ADD_SUBDIRECTORY(doc) -# post-install tasks -ADD_SUBDIRECTORY(cmake/postinstall) +# install tasks +ADD_SUBDIRECTORY(cmake/install) ADD_CUSTOM_COMMAND(OUTPUT "${CMAKE_BINARY_DIR}/lmms.1.gz" COMMAND gzip -c ${CMAKE_SOURCE_DIR}/doc/lmms.1 > ${CMAKE_BINARY_DIR}/lmms.1.gz diff --git a/cmake/install/CMakeLists.txt b/cmake/install/CMakeLists.txt new file mode 100644 index 000000000..3e37fa00e --- /dev/null +++ b/cmake/install/CMakeLists.txt @@ -0,0 +1,125 @@ + +FUNCTION(GET_COMPILER_SEARCH_DIR VAR) + SET(results "") + IF(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang|AppleClang)") + EXECUTE_PROCESS( + COMMAND ${CMAKE_CXX_COMPILER} --print-search-dirs + OUTPUT_VARIABLE out + ) + STRING(REPLACE "\n" ";" out "${out}") + FOREACH(line ${out}) + IF(line MATCHES "^.+:") + STRING(REPLACE " " ";" line "${line}") + LIST(GET line 1 paths) + # Remove "=" prefix + STRING(REGEX REPLACE "^=" "" paths "${paths}") + STRING(REPLACE ":" ";" paths "${paths}") + FOREACH(path ${paths}) + LIST(APPEND results ${path}) + ENDFOREACH() + ENDIF() + ENDFOREACH() + ENDIF() + + SET(paths "") + FOREACH(result ${results}) + GET_FILENAME_COMPONENT(result ${result} REALPATH) + IF(IS_DIRECTORY "${result}") + LIST(APPEND paths ${result}) + ENDIF() + ENDFOREACH() + LIST(REMOVE_DUPLICATES paths) + + SET(${VAR} ${paths} PARENT_SCOPE) +ENDFUNCTION() + +SET(PLUGIN_FILES "") +IF(LMMS_BUILD_WIN32) + INSTALL(FILES $ DESTINATION platforms) +ENDIF() + +IF(LMMS_BUILD_WIN32 OR LMMS_INSTALL_DEPENDENCIES) + # Collect directories to search for DLLs + GET_FILENAME_COMPONENT(QTBIN_DIR "${QT_QMAKE_EXECUTABLE}" PATH) + set(LIB_DIRS "${QTBIN_DIR}") + + GET_PROPERTY(PLUGINS_BUILT GLOBAL PROPERTY PLUGINS_BUILT) + + foreach(target lmms ${PLUGINS_BUILT}) + get_target_property(target_libs ${target} LINK_LIBRARIES) + + foreach(lib ${target_libs}) + if(TARGET ${lib} OR NOT IS_ABSOLUTE ${lib}) + continue() + endif() + + get_filename_component(lib_dir ${lib} PATH) + list(APPEND LIB_DIRS ${lib_dir}) + if(lib MATCHES ".(lib|dll.a)$") + if(IS_DIRECTORY ${lib_dir}/../bin) + list(APPEND LIB_DIRS ${lib_dir}/../bin) + endif() + if(IS_DIRECTORY ${lib_dir}/bin) + list(APPEND LIB_DIRS ${lib_dir}/bin) + endif() + endif() + endforeach() + endforeach() + + GET_COMPILER_SEARCH_DIR(COMPILER_SEARCH_DIRS) + LIST(APPEND LIB_DIRS ${COMPILER_SEARCH_DIRS}) + + LIST(REMOVE_DUPLICATES LIB_DIRS) + + # Collect plugin files to inspect + FOREACH(PLUGIN ${PLUGINS_BUILT}) + LIST(APPEND DEPLOY_TARGETS "$") + ENDFOREACH() + # Create the list of files using file(GENERATE) + SET(DEPLOY_LIST_FILE "${CMAKE_CURRENT_BINARY_DIR}/filelist.txt") + FILE(GENERATE OUTPUT "${DEPLOY_LIST_FILE}" CONTENT "${DEPLOY_TARGETS}") + + IF(LMMS_BUILD_LINUX) + FILE(DOWNLOAD "https://raw.githubusercontent.com/AppImage/AppImages/master/excludelist" + "${CMAKE_BINARY_DIR}/excludelist") + SET(additional_args INCLUDE_SYSTEM IGNORE_LIBS_FILE ${CMAKE_BINARY_DIR}/excludelist) + ELSEIF(LMMS_BUILD_WIN32) + SET(additional_args IGNORE_CASE IGNORE_LIBS_FILE ${CMAKE_CURRENT_LIST_DIR}/excludelist-win) + IF(CMAKE_CROSSCOMPILING) + SET(additional_args "${additional_args}" GP_TOOL objdump) + ENDIF() + ENDIF() + + IF(LMMS_BUILD_WIN32) + SET(LMMS_DEP_DESTINATION ${BIN_DIR}) + SET(PLUGIN_DEP_DESTINATION ${BIN_DIR}) + ELSE() + SET(LMMS_DEP_DESTINATION ${LIB_DIR}) + SET(PLUGIN_DEP_DESTINATION ${LIB_DIR}) + ENDIF() + + INSTALL(CODE " + INCLUDE(\"${CMAKE_SOURCE_DIR}/cmake/modules/InstallDependencies.cmake\") + # Install dependencies of lmms + INSTALL_DEPENDENCIES( + FILES ${BIN_DIR}/lmms${CMAKE_EXECUTABLE_SUFFIX} + DESTINATION ${LMMS_DEP_DESTINATION} + LIB_DIRS ${LIB_DIRS} + ${additional_args} + ) + # Install dependencies of plugins + FILE(READ \"${DEPLOY_LIST_FILE}\" DEPLOY_FILES) + INSTALL_DEPENDENCIES( + FILES \"\${DEPLOY_FILES}\" + DESTINATION \"${PLUGIN_DEP_DESTINATION}\" + LIB_DIRS ${LIB_DIRS} \"${BIN_DIR}\" \"${PLUGIN_DIR}\" + SEARCH_PATHS \"${BIN_DIR}\" \"${PLUGIN_DIR}\" + ${additional_args} + ) + ") +ENDIF() + +IF(LMMS_BUILD_APPLE) + INSTALL(CODE "EXECUTE_PROCESS(COMMAND chmod u+x ${CMAKE_BINARY_DIR}/install_apple.sh)") + INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${CMAKE_BINARY_DIR}/install_apple.sh)") +ENDIF() diff --git a/cmake/install/excludelist-win b/cmake/install/excludelist-win new file mode 100644 index 000000000..17793a113 --- /dev/null +++ b/cmake/install/excludelist-win @@ -0,0 +1,23 @@ +# List of DLLs considered to be system libraries. +# This is needed when cross-compiling for Windows. +ADVAPI32.dll +COMCTL32.dll +comdlg32.dll +dwmapi.dll +GDI32.dll +IMM32.dll +KERNEL32.dll +MPR.DLL +msvcrt.dll +ole32.dll +OLEAUT32.dll +OPENGL32.DLL +SHELL32.dll +USER32.dll +UxTheme.dll +VERSION.dll +WINMM.DLL +WS2_32.dll +RPCRT4.dll +dsound.dll +SETUPAPI.dll diff --git a/cmake/modules/BuildPlugin.cmake b/cmake/modules/BuildPlugin.cmake index efa3e5b46..e285e05bb 100644 --- a/cmake/modules/BuildPlugin.cmake +++ b/cmake/modules/BuildPlugin.cmake @@ -62,7 +62,10 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) TARGET_LINK_LIBRARIES(${PLUGIN_NAME} lmms) ENDIF(LMMS_BUILD_WIN32) - INSTALL(TARGETS ${PLUGIN_NAME} DESTINATION "${PLUGIN_DIR}") + INSTALL(TARGETS ${PLUGIN_NAME} + LIBRARY DESTINATION "${PLUGIN_DIR}" + RUNTIME DESTINATION "${PLUGIN_DIR}" + ) IF(LMMS_BUILD_APPLE) IF ("${PLUGIN_LINK}" STREQUAL "SHARED") @@ -89,5 +92,8 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) TARGET_INCLUDE_DIRECTORIES(${PLUGIN_NAME} PUBLIC $ ) + + SET_PROPERTY(GLOBAL APPEND PROPERTY PLUGINS_BUILT ${PLUGIN_NAME}) + GET_PROPERTY(PLUGINS_BUILT GLOBAL PROPERTY PLUGINS_BUILT) ENDMACRO(BUILD_PLUGIN) diff --git a/cmake/modules/InstallDependencies.cmake b/cmake/modules/InstallDependencies.cmake new file mode 100644 index 000000000..791041bb2 --- /dev/null +++ b/cmake/modules/InstallDependencies.cmake @@ -0,0 +1,184 @@ +include(GetPrerequisites) +include(CMakeParseArguments) + +CMAKE_POLICY(SET CMP0011 NEW) +CMAKE_POLICY(SET CMP0057 NEW) + +function(make_absolute var) + get_filename_component(abs "${${var}}" ABSOLUTE BASE_DIR "${CMAKE_INSTALL_PREFIX}") + set(${var} ${abs} PARENT_SCOPE) +endfunction() + +# Reads lines of a file into a list, skipping '#' comment lines +function(READ_LIST_FILE FILE VAR) + file(STRINGS "${FILE}" list) + + set(result "") + foreach(item ${list}) + string(STRIP "${item}" item) + if(item STREQUAL "" OR item MATCHES "^\#") + continue() + endif() + list(APPEND result "${item}") + endforeach() + + set(${VAR} ${result} PARENT_SCOPE) +endfunction() + +function(make_all_absolute list_var) + set(result "") + foreach(file ${${list_var}}) + make_absolute(file) + list(APPEND result ${file}) + endforeach() + set(${list_var} ${result} PARENT_SCOPE) +endfunction() + +if(CMAKE_BINARY_DIR) + set(tmp_lib_dir "${CMAKE_BINARY_DIR}/bundled-libraries") +elseif(CMAKE_HOST_UNIX) + set(tmp_lib_dir "/tmp/bundled-libraries") +elseif(DEFINED ENV{TEMP}) + set(tmp_lib_dir "$ENV{TMP}/bundled-libraries") +else() + message(FATAL_ERROR "Can't find a temp dir for libraries") +endif() + +# Like file(INSTALL), but resolves symlinks +function(install_file_resolved file destination) + + get_filename_component(file_name "${file}" NAME) + if(IS_SYMLINK "${file}") + get_filename_component(real_path "${file}" REALPATH) + get_filename_component(real_name "${real_path}" NAME) + file(COPY "${real_path}" DESTINATION "${tmp_lib_dir}") + file(RENAME "${tmp_lib_dir}/${real_name}" "${tmp_lib_dir}/${file_name}") + set(file_path "${tmp_lib_dir}/${file_name}") + else() + set(file_path "${file}") + endif() + + file(INSTALL "${file_path}" DESTINATION "${destination}") +endfunction() + +function(install_resolved) + cmake_parse_arguments("" "" "DESTINATION" "FILES" ${ARGN}) + foreach(file ${_FILES}) + install_file_resolved("${file}" "${_DESTINATION}") + endforeach() +endfunction() + +if(CMAKE_CROSSCOMPILING) + # If we're cross-compiling, GetPrerequisites may not be able to find system libraries such as kernel32.dll because + # they're supplied by the toolchain. To suppress thousands of lines of warnings being printed to the console, we + # override gp_resolved_file_type to return "system" for any library in ${IGNORE_LIBS} without trying to resolve the + # file first. + # GetPrerequisites supports using an override function called gp_resolved_file_type_override, but it's not suited + # for our purpose because it's only called by gp_resolved_file_type *after* trying to resolve the file. + function(gp_resolved_file_type original_file file exepath dirs type_var) + set(file_find "${file}") + if(_IGNORE_CASE) + # On case-insensitive systems, convert to upper characters to respect it + string(TOUPPER "${file_find}" file_find) + endif() + SET(IGNORE_LIBS ${_IGNORE_LIBS} CACHE INTERNAL "Ignored library names" FORCE) + if(IGNORE_LIBS AND ${file_find} IN_LIST IGNORE_LIBS) + set(${type_var} system PARENT_SCOPE) + else() + #_gp_resolved_file_type(${ARGV}) + _gp_resolved_file_type("${original_file}" "${file}" "${exepath}" "${dirs}" "${type_var}" ${ARGN}) + endif() + endfunction() +endif() + +function(INSTALL_DEPENDENCIES) + cmake_parse_arguments("" "INCLUDE_SYSTEM;IGNORE_CASE" "GP_TOOL;DESTINATION;IGNORE_LIBS_FILE" "FILES;LIB_DIRS;SEARCH_PATHS;IGNORE_LIBS" ${ARGN}) + + # Make paths absolute + make_absolute(_DESTINATION) + make_all_absolute(_FILES) + make_all_absolute(_LIB_DIRS) + make_all_absolute(_SEARCH_PATHS) + + if(_INCLUDE_SYSTEM) + set(EXCLUDE_SYSTEM 0) + else() + set(EXCLUDE_SYSTEM 1) + endif() + + if(_IGNORE_LIBS_FILE) + READ_LIST_FILE("${_IGNORE_LIBS_FILE}" _IGNORE_LIBS) + if(_IGNORE_CASE) + # On case-insensitive systems, convert to upper characters to respect it + string(TOUPPER "${_IGNORE_LIBS}" _IGNORE_LIBS) + endif() + SET(IGNORE_LIBS ${_IGNORE_LIBS} CACHE INTERNAL "Ignored library names" FORCE) + endif() + + if(_GP_TOOL) + set(gp_tool "${_GP_TOOL}") + endif() + + set(prereqs "") + foreach(file ${_FILES}) + get_filename_component(file_name "${file}" NAME) + message("-- Finding prerequisites of ${file_name}") + find_prerequisites("${file}" _prereqs + ${EXCLUDE_SYSTEM} # exclude system files + 1 # recurse + "" + "${_LIB_DIRS}" + "${_SEARCH_PATHS}" + "${_IGNORE_LIBS}" + ) + + list(APPEND prereqs ${_prereqs}) + endforeach() + + list(REMOVE_DUPLICATES prereqs) + + foreach(prereq ${prereqs}) + get_filename_component(prereq_name "${prereq}" NAME) + + foreach(rpath ${_SEARCH_PATHS}) + if(EXISTS "${rpath}/${prereq_name}") + list(REMOVE_ITEM prereqs "${prereq}") + break() + endif() + endforeach() + endforeach() + + #file(INSTALL ${prereqs} DESTINATION ${_DESTINATION}) + install_resolved(FILES ${prereqs} DESTINATION "${_DESTINATION}") +endfunction() + +# Like get_prerequisites, but returns full paths +function(FIND_PREREQUISITES target RESULT_VAR exclude_system recurse + exepath dirs rpaths) + set(RESULTS) + + get_prerequisites("${target}" _prereqs ${exclude_system} ${recurse} + "" "${dirs}" "${rpaths}") + + foreach(prereq ${_prereqs}) + get_filename_component(prereq_name "${prereq}" NAME) + if(_IGNORE_CASE) + # Windows is case insensitive. + # Use upper characters to respect it. + string(TOUPPER "${prereq_name}" prereq_name) + endif() + if("${prereq_name}" IN_LIST IGNORE_LIBS) + continue() + endif() + + gp_resolve_item("${LIB_DLL}" "${prereq}" "" "${dirs}" RESOLVED_PREREQ "${rpaths}") + + if(RESOLVED_PREREQ AND IS_ABSOLUTE ${RESOLVED_PREREQ} AND EXISTS ${RESOLVED_PREREQ}) + list(APPEND RESULTS ${RESOLVED_PREREQ}) + else() + message(FATAL_ERROR "Can't resolve dependency ${prereq}.") + endif() + endforeach() + + set(${RESULT_VAR} ${RESULTS} PARENT_SCOPE) +endfunction() diff --git a/cmake/postinstall/CMakeLists.txt b/cmake/postinstall/CMakeLists.txt deleted file mode 100644 index 434d1c54e..000000000 --- a/cmake/postinstall/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -IF(LMMS_BUILD_APPLE) - INSTALL(CODE "EXECUTE_PROCESS(COMMAND chmod u+x ${CMAKE_BINARY_DIR}/install_apple.sh)") - INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${CMAKE_BINARY_DIR}/install_apple.sh)") -ENDIF() \ No newline at end of file diff --git a/plugins/zynaddsubfx/CMakeLists.txt b/plugins/zynaddsubfx/CMakeLists.txt index f1d37fa3e..d6fa9c727 100644 --- a/plugins/zynaddsubfx/CMakeLists.txt +++ b/plugins/zynaddsubfx/CMakeLists.txt @@ -162,6 +162,8 @@ SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) ADD_EXECUTABLE(RemoteZynAddSubFx RemoteZynAddSubFx.cpp "${WINRC}") INSTALL(TARGETS RemoteZynAddSubFx RUNTIME DESTINATION "${PLUGIN_DIR}") +# Needed to deploy dependencies of RemoteZynAddSubFx +SET_PROPERTY(GLOBAL APPEND PROPERTY PLUGINS_BUILT "RemoteZynAddSubFx") IF(LMMS_BUILD_WIN32) SET_TARGET_PROPERTIES(RemoteZynAddSubFx PROPERTIES LINK_FLAGS "${LINK_FLAGS} -mwindows") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4ac6bf133..10ce72ae6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -186,210 +186,20 @@ FOREACH(LIB ${LMMS_REQUIRED_LIBS}) ENDIF() ENDFOREACH() - -# Install -IF(NOT MSVC) - IF(LMMS_BUILD_WIN32) - SET_TARGET_PROPERTIES(lmms PROPERTIES - LINK_FLAGS "${LINK_FLAGS} -mwindows" - ENABLE_EXPORTS ON +IF(LMMS_BUILD_WIN32) + SET_TARGET_PROPERTIES(lmms PROPERTIES + ENABLE_EXPORTS ON + ) + IF(LMMS_BUILD_MSYS) + # ENABLE_EXPORTS property has no effect in some MSYS2 configurations. + # Add the linker flag manually to create liblmms.dll.a import library + SET_PROPERTY(TARGET lmms + APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--out-implib,liblmms.dll.a" ) + ENDIF() +ELSE() + INSTALL(FILES "${CMAKE_BINARY_DIR}/lmms.1.gz" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/man/man1/" + PERMISSIONS OWNER_READ GROUP_READ WORLD_READ) +ENDIF() - IF(LMMS_BUILD_MSYS) - # ENABLE_EXPORTS property has no effect in some MSYS2 configurations. - # Add the linker flag manually to create liblmms.dll.a import library - SET_PROPERTY(TARGET lmms - APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--out-implib,liblmms.dll.a" - ) - ENDIF() - - IF(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") - ADD_CUSTOM_COMMAND(TARGET lmms POST_BUILD COMMAND "${STRIP}" "$") - ENDIF() - - INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") - INSTALL(FILES - "${MINGW_PREFIX}/bin/Qt5Core.dll" - "${MINGW_PREFIX}/bin/Qt5Gui.dll" - "${MINGW_PREFIX}/bin/Qt5Widgets.dll" - "${MINGW_PREFIX}/bin/Qt5Xml.dll" - DESTINATION .) - INSTALL(FILES - "${MINGW_PREFIX}/lib/qt5/plugins/platforms/qwindows.dll" - DESTINATION ./platforms) - INSTALL(FILES - "${MINGW_PREFIX}/bin/libsamplerate-0.dll" - "${MINGW_PREFIX}/bin/libsndfile-1.dll" - "${MINGW_PREFIX}/bin/libvorbis-0.dll" - "${MINGW_PREFIX}/bin/libvorbisenc-2.dll" - "${MINGW_PREFIX}/bin/libvorbisfile-3.dll" - "${MINGW_PREFIX}/bin/libjpeg-9.dll" - "${MINGW_PREFIX}/bin/libogg-0.dll" - "${MINGW_PREFIX}/bin/libmp3lame-0.dll" - "${MINGW_PREFIX}/bin/libfftw3f-3.dll" - "${MINGW_PREFIX}/bin/libFLAC-8.dll" - "${MINGW_PREFIX}/bin/libpng16-16.dll" - "${MINGW_PREFIX}/bin/SDL.dll" - "${MINGW_PREFIX}/bin/libglib-2.0-0.dll" - "${MINGW_PREFIX}/bin/libgthread-2.0-0.dll" - "${MINGW_PREFIX}/bin/zlib1.dll" - "${MINGW_PREFIX}/${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32/bin/libwinpthread-1.dll" - DESTINATION .) - IF(LMMS_BUILD_MSYS) - INSTALL(FILES - "${MINGW_PREFIX}/bin/libwinpthread-1.dll" - "${MINGW_PREFIX}/bin/libgcc_s_seh-1.dll" - "${MINGW_PREFIX}/bin/libstdc++-6.dll" - DESTINATION .) - ELSE() - INSTALL(FILES - "${MINGW_PREFIX}/${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32/bin/libwinpthread-1.dll" - DESTINATION .) - ENDIF() - IF(FLTK_FOUND) - INSTALL(FILES - "${MINGW_PREFIX}/bin/libfltk.dll" - DESTINATION .) - ENDIF() - IF(FLUIDSYNTH_FOUND) - INSTALL(FILES - "${MINGW_PREFIX}/bin/libfluidsynth.dll" - DESTINATION .) - ENDIF() - IF(GIG_FOUND) - # Handle libgig-*.dll - FILE(GLOB GIG_LIBRARY "${MINGW_PREFIX}/bin/libgig-*.dll") - INSTALL(FILES - ${GIG_LIBRARY} - DESTINATION .) - ENDIF() - IF(PORTAUDIO_FOUND) - INSTALL(FILES - "${MINGW_PREFIX}/bin/libportaudio-2.dll" - DESTINATION .) - ENDIF() - IF(SOUNDIO_FOUND) - INSTALL(FILES - "${MINGW_PREFIX}/lib/libsoundio.dll" - DESTINATION .) - ENDIF() - - ELSE(LMMS_BUILD_WIN32) - IF(NOT LMMS_BUILD_APPLE) - SET_TARGET_PROPERTIES(lmms PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Wl,-E") - ENDIF(NOT LMMS_BUILD_APPLE) - - INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") - INSTALL(FILES "${CMAKE_BINARY_DIR}/lmms.1.gz" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/man/man1/" PERMISSIONS OWNER_READ GROUP_READ WORLD_READ) - - ENDIF(LMMS_BUILD_WIN32) -ELSE(NOT MSVC) - SET_TARGET_PROPERTIES(lmms PROPERTIES - ENABLE_EXPORTS ON - ) - INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") - - SET_TARGET_PROPERTIES(lmms PROPERTIES - LINK_FLAGS "${LINK_FLAGS} -mwindows" - ENABLE_EXPORTS ON - ) - - #CMAKE_FIND_ROOT_PATH - SET(VCPKG_ROOT ${CMAKE_FIND_ROOT_PATH}) - - INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") - - INSTALL(FILES - "${VCPKG_ROOT}/bin/Qt5Core.dll" - "${VCPKG_ROOT}/bin/Qt5Gui.dll" - "${VCPKG_ROOT}/bin/Qt5Widgets.dll" - "${VCPKG_ROOT}/bin/Qt5Xml.dll" - - "${VCPKG_ROOT}/bin/zlib1.dll" - "${VCPKG_ROOT}/bin/jpeg62.dll" - "${VCPKG_ROOT}/bin/libpng16.dll" - "${VCPKG_ROOT}/bin/gthread-2.dll" - "${VCPKG_ROOT}/bin/glib-2.dll" - "${VCPKG_ROOT}/bin/harfbuzz.dll" - "${VCPKG_ROOT}/bin/pcre2-16.dll" - "${VCPKG_ROOT}/bin/double-conversion.dll" - "${VCPKG_ROOT}/bin/freetype.dll" - "${VCPKG_ROOT}/bin/libbz2.dll" - "${VCPKG_ROOT}/bin/pcre.dll" - "${VCPKG_ROOT}/bin/libiconv.dll" - "${VCPKG_ROOT}/bin/libcharset.dll" - "${VCPKG_ROOT}/bin/libintl.dll" - DESTINATION .) - - INSTALL(FILES - "${VCPKG_ROOT}/plugins/platforms/qwindows.dll" - DESTINATION ./platforms) - - INSTALL(FILES - "${VCPKG_ROOT}/bin/libsndfile-1.dll" - "${VCPKG_ROOT}/bin/ogg.dll" - "${VCPKG_ROOT}/bin/vorbis.dll" - "${VCPKG_ROOT}/bin/vorbisenc.dll" - "${VCPKG_ROOT}/bin/FLAC.dll" - "${VCPKG_ROOT}/bin/vorbisfile.dll" - - "${VCPKG_ROOT}/bin/libsamplerate-0.dll" - "${VCPKG_ROOT}/bin/SDL2.dll" - "${VCPKG_ROOT}/bin/fftw3f.dll" - DESTINATION .) - - #not yet in vcpkg - #IF(LAME_FOUND) - # INSTALL(FILES - # "${VCPKG_ROOT}/bin/libmp3lame-0.dll" - # DESTINATION .) - #ENDIF(LAME_FOUND) - - IF(FLTK_FOUND) - INSTALL(FILES - "${VCPKG_ROOT}/bin/libfltk_SHARED.dll" - - "${VCPKG_ROOT}/bin/zlib1.dll" - "${VCPKG_ROOT}/bin/jpeg62.dll" - DESTINATION .) - ENDIF() - - IF(FLUIDSYNTH_FOUND) - INSTALL(FILES - "${VCPKG_ROOT}/bin/libfluidsynth-1.dll" - "${VCPKG_ROOT}/bin/glib-2.dll" - "${VCPKG_ROOT}/bin/pcre.dll" - "${VCPKG_ROOT}/bin/libiconv.dll" - "${VCPKG_ROOT}/bin/libcharset.dll" - "${VCPKG_ROOT}/bin/libintl.dll" - DESTINATION .) - ENDIF() - - #not yet included in vcpkg - #IF(GIG_FOUND) - # # Handle libgig-*.dll - # FILE(GLOB GIG_LIBRARY "${VCPKG_ROOT}/bin/libgig-*.dll") - # INSTALL(FILES - # ${GIG_LIBRARY} - # DESTINATION .) - #ENDIF() - - IF(PORTAUDIO_FOUND) - IF(LMMS_BUILD_WIN64) - INSTALL(FILES - "${VCPKG_ROOT}/bin/portaudio-x64.dll" - DESTINATION .) - ELSE(LMMS_BUILD_WIN64) - INSTALL(FILES - "${VCPKG_ROOT}/bin/portaudio-x86.dll" - DESTINATION .) - ENDIF(LMMS_BUILD_WIN64) - ENDIF() - - #not yet in vcpkg - #IF(SOUNDIO_FOUND) - # INSTALL(FILES - # "${VCPKG_ROOT}/bin/libsoundio.dll" - # DESTINATION .) - #ENDIF() -ENDIF(NOT MSVC) +INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") \ No newline at end of file From 8d169fa5290c1b8a8c3e0894060337083a7080ee Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 26 Nov 2018 12:50:37 +0900 Subject: [PATCH 374/445] CircleCI: create Windows installers --- .circleci/config.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4174ba1ef..99b987f86 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -59,6 +59,15 @@ jobs: - run: name: Build tests command: cd build && make tests + - run: + name: Build installer + command: | + cd build + make package + cp ./lmms-*.exe /tmp/artifacts/ + - store_artifacts: + path: /tmp/artifacts/ + destination: / - *ccache_stats - *save_cache mingw64: @@ -79,6 +88,15 @@ jobs: - run: name: Build tests command: cd build && make tests + - run: + name: Build installer + command: | + cd build + make package + cp ./lmms-*.exe /tmp/artifacts/ + - store_artifacts: + path: /tmp/artifacts/ + destination: / - *ccache_stats - *save_cache linux.gcc: From 7a23ee8ad1b194bc218f3be921ce16b12dcf461a Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 26 Nov 2018 12:53:34 +0900 Subject: [PATCH 375/445] AppVeyor: create Windows installers --- .appveyor.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.appveyor.yml b/.appveyor.yml index 3b632d1f3..7ca7d58c4 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -19,5 +19,9 @@ build_script: - cmake -DUSE_COMPILE_CACHE=ON -DCACHE_TOOL=%APPVEYOR_BUILD_FOLDER%/clcache.4.1.0/clcache-4.1.0/clcache.exe -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_PREFIX_PATH=c:/Qt/5.12/msvc2017%QT_SUFFIX%;c:/tools/vcpkg/installed/%PLATFORM%-windows -DCMAKE_GENERATOR_PLATFORM="%CMAKE_PLATFORM%" .. - cmake --build . -- /maxcpucount:4 - cmake --build . --target tests + - cmake --build . --target package +artifacts: + - path: 'build\lmms-*.exe' + name: Installer cache: - c:/tools/vcpkg/installed From 72bdb23531c22d0f8c6fc22813ece640f3df03e4 Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Wed, 21 Aug 2019 23:27:58 +0300 Subject: [PATCH 376/445] CMake: Provide API for install-time variables with generator expression --- cmake/modules/CreateTempFile.cmake | 18 +++++++++++++++++ cmake/modules/DefineInstallVar.cmake | 30 ++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 cmake/modules/CreateTempFile.cmake create mode 100644 cmake/modules/DefineInstallVar.cmake diff --git a/cmake/modules/CreateTempFile.cmake b/cmake/modules/CreateTempFile.cmake new file mode 100644 index 000000000..ceefa4928 --- /dev/null +++ b/cmake/modules/CreateTempFile.cmake @@ -0,0 +1,18 @@ +function(CreateTempFilePath) + set(options) + set(oneValueArgs OUTPUT_VAR TAG) + set(multiValueArgs CONTENT) + cmake_parse_arguments(TEMP "${options}" "${oneValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + # Use hash to create a unique identifier + # for this file. + string(SHA1 hashed_content "${TEMP_CONTENT}") + + set(file_name "${CMAKE_BINARY_DIR}/${TEMP_TAG}_${hashed_content}") + + file(GENERATE OUTPUT "${file_name}" + CONTENT "${TEMP_CONTENT}") + + set(${TEMP_OUTPUT_VAR} "${file_name}" PARENT_SCOPE) +endfunction() diff --git a/cmake/modules/DefineInstallVar.cmake b/cmake/modules/DefineInstallVar.cmake new file mode 100644 index 000000000..36f221410 --- /dev/null +++ b/cmake/modules/DefineInstallVar.cmake @@ -0,0 +1,30 @@ +# This functions forwards a variable to +# the install stage. +# Parameters: +# CONTENT: Variable content. +# NAME: Variable name. +# Options: +# GENERATOR_EXPRESSION: Support generator expression for CONTENT. +function(DEFINE_INSTALL_VAR) + set(options GENERATOR_EXPRESSION) + set(oneValueArgs NAME ) + set(multiValueArgs CONTENT) + cmake_parse_arguments(VAR "${options}" "${oneValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + # install(CODE) does not support generator expression in ver<3.14 + if(VAR_GENERATOR_EXPRESSION AND ${CMAKE_VERSION} VERSION_LESS "3.14.0") + if(MSVC) + message(FATAL_ERROR "Installing is not supported with msvc and cmake<3.14") + endif() + + include(CreateTempFile) + CreateTempFilePath(OUTPUT_VAR file_path TAG "${VAR_NAME}" CONTENT "${VAR_CONTENT}") + install(CODE "file(READ \"${file_path}\" \"${VAR_NAME}\")") + else() + if(VAR_GENERATOR_EXPRESSION) + cmake_policy(SET CMP0087 NEW) + endif() + install(CODE "set(\"${VAR_NAME}\" \"${VAR_CONTENT}\")") + endif() +endfunction() From 13da2b957608fd1ae38d59c38280127ddfd007cd Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Mon, 12 Aug 2019 12:17:12 +0300 Subject: [PATCH 377/445] CMake: extract dll installation code into a portable function --- CMakeLists.txt | 2 + cmake/install/CMakeLists.txt | 114 +++--------------- cmake/modules/InstallTargetDependencies.cmake | 89 ++++++++++++++ 3 files changed, 106 insertions(+), 99 deletions(-) create mode 100644 cmake/modules/InstallTargetDependencies.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 590a20c98..36e35bf4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.3) PROJECT(lmms) SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules" ${CMAKE_MODULE_PATH}) +SET(LMMS_BINARY_DIR ${CMAKE_BINARY_DIR}) +SET(LMMS_SOURCE_DIR ${CMAKE_SOURCE_DIR}) IF(COMMAND CMAKE_POLICY) CMAKE_POLICY(SET CMP0005 NEW) diff --git a/cmake/install/CMakeLists.txt b/cmake/install/CMakeLists.txt index 3e37fa00e..a3a81beeb 100644 --- a/cmake/install/CMakeLists.txt +++ b/cmake/install/CMakeLists.txt @@ -1,95 +1,17 @@ - -FUNCTION(GET_COMPILER_SEARCH_DIR VAR) - SET(results "") - IF(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang|AppleClang)") - EXECUTE_PROCESS( - COMMAND ${CMAKE_CXX_COMPILER} --print-search-dirs - OUTPUT_VARIABLE out - ) - STRING(REPLACE "\n" ";" out "${out}") - FOREACH(line ${out}) - IF(line MATCHES "^.+:") - STRING(REPLACE " " ";" line "${line}") - LIST(GET line 1 paths) - # Remove "=" prefix - STRING(REGEX REPLACE "^=" "" paths "${paths}") - STRING(REPLACE ":" ";" paths "${paths}") - FOREACH(path ${paths}) - LIST(APPEND results ${path}) - ENDFOREACH() - ENDIF() - ENDFOREACH() - ENDIF() - - SET(paths "") - FOREACH(result ${results}) - GET_FILENAME_COMPONENT(result ${result} REALPATH) - IF(IS_DIRECTORY "${result}") - LIST(APPEND paths ${result}) - ENDIF() - ENDFOREACH() - LIST(REMOVE_DUPLICATES paths) - - SET(${VAR} ${paths} PARENT_SCOPE) -ENDFUNCTION() - SET(PLUGIN_FILES "") IF(LMMS_BUILD_WIN32) INSTALL(FILES $ DESTINATION platforms) ENDIF() IF(LMMS_BUILD_WIN32 OR LMMS_INSTALL_DEPENDENCIES) + include(InstallTargetDependencies) + # Collect directories to search for DLLs GET_FILENAME_COMPONENT(QTBIN_DIR "${QT_QMAKE_EXECUTABLE}" PATH) set(LIB_DIRS "${QTBIN_DIR}") GET_PROPERTY(PLUGINS_BUILT GLOBAL PROPERTY PLUGINS_BUILT) - foreach(target lmms ${PLUGINS_BUILT}) - get_target_property(target_libs ${target} LINK_LIBRARIES) - - foreach(lib ${target_libs}) - if(TARGET ${lib} OR NOT IS_ABSOLUTE ${lib}) - continue() - endif() - - get_filename_component(lib_dir ${lib} PATH) - list(APPEND LIB_DIRS ${lib_dir}) - if(lib MATCHES ".(lib|dll.a)$") - if(IS_DIRECTORY ${lib_dir}/../bin) - list(APPEND LIB_DIRS ${lib_dir}/../bin) - endif() - if(IS_DIRECTORY ${lib_dir}/bin) - list(APPEND LIB_DIRS ${lib_dir}/bin) - endif() - endif() - endforeach() - endforeach() - - GET_COMPILER_SEARCH_DIR(COMPILER_SEARCH_DIRS) - LIST(APPEND LIB_DIRS ${COMPILER_SEARCH_DIRS}) - - LIST(REMOVE_DUPLICATES LIB_DIRS) - - # Collect plugin files to inspect - FOREACH(PLUGIN ${PLUGINS_BUILT}) - LIST(APPEND DEPLOY_TARGETS "$") - ENDFOREACH() - # Create the list of files using file(GENERATE) - SET(DEPLOY_LIST_FILE "${CMAKE_CURRENT_BINARY_DIR}/filelist.txt") - FILE(GENERATE OUTPUT "${DEPLOY_LIST_FILE}" CONTENT "${DEPLOY_TARGETS}") - - IF(LMMS_BUILD_LINUX) - FILE(DOWNLOAD "https://raw.githubusercontent.com/AppImage/AppImages/master/excludelist" - "${CMAKE_BINARY_DIR}/excludelist") - SET(additional_args INCLUDE_SYSTEM IGNORE_LIBS_FILE ${CMAKE_BINARY_DIR}/excludelist) - ELSEIF(LMMS_BUILD_WIN32) - SET(additional_args IGNORE_CASE IGNORE_LIBS_FILE ${CMAKE_CURRENT_LIST_DIR}/excludelist-win) - IF(CMAKE_CROSSCOMPILING) - SET(additional_args "${additional_args}" GP_TOOL objdump) - ENDIF() - ENDIF() - IF(LMMS_BUILD_WIN32) SET(LMMS_DEP_DESTINATION ${BIN_DIR}) SET(PLUGIN_DEP_DESTINATION ${BIN_DIR}) @@ -98,25 +20,19 @@ IF(LMMS_BUILD_WIN32 OR LMMS_INSTALL_DEPENDENCIES) SET(PLUGIN_DEP_DESTINATION ${LIB_DIR}) ENDIF() - INSTALL(CODE " - INCLUDE(\"${CMAKE_SOURCE_DIR}/cmake/modules/InstallDependencies.cmake\") - # Install dependencies of lmms - INSTALL_DEPENDENCIES( - FILES ${BIN_DIR}/lmms${CMAKE_EXECUTABLE_SUFFIX} - DESTINATION ${LMMS_DEP_DESTINATION} - LIB_DIRS ${LIB_DIRS} - ${additional_args} - ) - # Install dependencies of plugins - FILE(READ \"${DEPLOY_LIST_FILE}\" DEPLOY_FILES) - INSTALL_DEPENDENCIES( - FILES \"\${DEPLOY_FILES}\" - DESTINATION \"${PLUGIN_DEP_DESTINATION}\" - LIB_DIRS ${LIB_DIRS} \"${BIN_DIR}\" \"${PLUGIN_DIR}\" - SEARCH_PATHS \"${BIN_DIR}\" \"${PLUGIN_DIR}\" - ${additional_args} - ) - ") + INSTALL_TARGET_DEPENDENCIES( + NAME "main_binary" + TARGETS lmms + DESTINATION "${LMMS_DEP_DESTINATION}" + LIB_DIRS ${LIB_DIRS} + ) + + INSTALL_TARGET_DEPENDENCIES( + NAME "plugins" + TARGETS ${PLUGINS_BUILT} + DESTINATION ${PLUGIN_DEP_DESTINATION} + LIB_DIRS ${LIB_DIRS} "${PLUGIN_DIR}" + ) ENDIF() IF(LMMS_BUILD_APPLE) diff --git a/cmake/modules/InstallTargetDependencies.cmake b/cmake/modules/InstallTargetDependencies.cmake new file mode 100644 index 000000000..9665a0b87 --- /dev/null +++ b/cmake/modules/InstallTargetDependencies.cmake @@ -0,0 +1,89 @@ +include(DefineInstallVar) + +SET(DEFAULT_SEARCH_DIRECTORIES "${BIN_DIR}" "${LIB_DIR}" "${CMAKE_FIND_ROOT_PATH}" "${CMAKE_PREFIX_PATH}") +SET(DEFAULT_SEARCH_SUFFIXES "bin" "lib" "../bin") + +# Like INSTALL_DEPENDENCIES but can be called from regular cmake code +# (instead of install(CODE)), takes targets instead of files, +# takes care of configuring search paths, and other platform-specific tweaks. +# Arguments: +# TARGETS: list of cmake targets to install. +# NAME: unique string for this install. +# DESTINATION: directory path to install the binaries to. +# LIB_DIRS: list of paths for looking up dependencies. +# LIB_DIRS_SUFFIXES: list of possible suffixes for LIB_DIRS entries. +# NO_DEFAULT_PATHS: supply this value to avoid adding DEFAULT_SEARCH_DIRECTORIES +# to LIB_DIRS and DEFAULT_SEARCH_SUFFIXES to LIB_DIRS_SUFFIXES. +FUNCTION(INSTALL_TARGET_DEPENDENCIES) + set(options NO_DEFAULT_PATHS) + set(oneValueArgs NAME) + set(multiValueArgs TARGETS DESTINATION LIB_DIRS_SUFFIXES LIB_DIRS) + cmake_parse_arguments(DEPS "${options}" "${oneValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + if(NOT DEPS_LIB_DIRS) + set(DEPS_LIB_DIRS "") + endif() + + # Set default values. + if(NOT DEPS_NO_DEFAULT_PATHS) + list(APPEND DEPS_LIB_DIRS ${DEFAULT_SEARCH_DIRECTORIES}) + set(DEPS_LIB_DIRS_SUFFIXES "${DEPS_LIB_DIRS_SUFFIXES}" ${DEFAULT_SEARCH_SUFFIXES}) + endif() + + FOREACH(TARGET ${DEPS_TARGETS}) + IF(NOT TARGET ${TARGET}) + message(FATAL_ERROR "Not a target: ${TARGET}") + ENDIF() + + # Collect target output files. + LIST(APPEND DEPLOY_TARGETS "$") + + # Collect target link directories + get_target_property(target_libs ${TARGET} LINK_LIBRARIES) + + foreach(lib ${target_libs}) + if(TARGET ${lib} OR NOT IS_ABSOLUTE ${lib}) + continue() + endif() + + get_filename_component(lib_dir ${lib} PATH) + list(APPEND DEPS_LIB_DIRS ${lib_dir}) + endforeach() + ENDFOREACH() + + LIST(APPEND DEPS_LIB_DIRS ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES}) + + FOREACH(LIB_PATH ${DEPS_LIB_DIRS}) + FOREACH(suffix ${DEPS_LIB_DIRS_SUFFIXES}) + list(APPEND DEPS_LIB_DIRS "${LIB_PATH}/${suffix}") + ENDFOREACH() + ENDFOREACH() + + DEFINE_INSTALL_VAR(NAME "DEPLOY_FILES" CONTENT "${DEPLOY_TARGETS}" GENERATOR_EXPRESSION) + + LIST(REMOVE_DUPLICATES DEPS_LIB_DIRS) + + IF(LMMS_BUILD_LINUX) + FILE(DOWNLOAD "https://raw.githubusercontent.com/AppImage/AppImages/master/excludelist" + "${CMAKE_BINARY_DIR}/excludelist") + SET(additional_args INCLUDE_SYSTEM IGNORE_LIBS_FILE ${CMAKE_BINARY_DIR}/excludelist) + ELSEIF(LMMS_BUILD_WIN32) + SET(additional_args IGNORE_CASE IGNORE_LIBS_FILE "${LMMS_SOURCE_DIR}/cmake/install/excludelist-win") + IF(CMAKE_CROSSCOMPILING) + SET(additional_args "${additional_args}" GP_TOOL objdump) + ENDIF() + ENDIF() + + INSTALL(CODE " + INCLUDE(\"${LMMS_SOURCE_DIR}/cmake/modules/InstallDependencies.cmake\") + + INSTALL_DEPENDENCIES( + FILES \"\${DEPLOY_FILES}\" + DESTINATION \"${DEPS_DESTINATION}\" + LIB_DIRS \"${DEPS_LIB_DIRS}\" + SEARCH_PATHS \"${DEPS_SEARCH_PATHS}\" + ${additional_args} + ) + ") +ENDFUNCTION() From 84d1091100d60708ba4d3def92c0b9fd17112d74 Mon Sep 17 00:00:00 2001 From: Hussam al-Homsi Date: Thu, 5 Sep 2019 20:32:17 -0400 Subject: [PATCH 378/445] Rewrite the setup dialog (#3820) --- include/ConfigManager.h | 215 +-- include/SetupDialog.h | 218 ++- plugins/MidiImport/MidiImport.cpp | 4 +- plugins/sf2_player/sf2_player.cpp | 2 +- src/core/ConfigManager.cpp | 354 ++--- src/core/audio/AudioJack.cpp | 4 +- src/core/audio/AudioOss.cpp | 4 +- src/core/audio/AudioPortAudio.cpp | 6 +- src/core/audio/AudioPulseAudio.cpp | 4 +- src/core/audio/AudioSdl.cpp | 2 +- src/core/audio/AudioSndio.cpp | 4 +- src/core/audio/AudioSoundIo.cpp | 4 +- src/gui/AudioDeviceSetupWidget.cpp | 6 +- src/gui/GuiApplication.cpp | 4 +- src/gui/MainWindow.cpp | 14 +- src/gui/MidiSetupWidget.cpp | 24 +- src/gui/SetupDialog.cpp | 2180 ++++++++++++++-------------- 17 files changed, 1506 insertions(+), 1543 deletions(-) diff --git a/include/ConfigManager.h b/include/ConfigManager.h index dc5b9f485..556c455a0 100644 --- a/include/ConfigManager.h +++ b/include/ConfigManager.h @@ -36,6 +36,7 @@ #include "lmms_export.h" + class LmmsCore; @@ -57,61 +58,22 @@ class LMMS_EXPORT ConfigManager : public QObject public: static inline ConfigManager * inst() { - if( s_instanceOfMe == NULL ) + if(s_instanceOfMe == NULL ) { s_instanceOfMe = new ConfigManager(); } return s_instanceOfMe; } - const QString & dataDir() const - { - return m_dataDir; - } const QString & workingDir() const { return m_workingDir; } - QString userProjectsDir() const + const QString & dataDir() const { - return workingDir() + PROJECTS_PATH; - } - - QString userTemplateDir() const - { - return workingDir() + TEMPLATE_PATH; - } - - QString userPresetsDir() const - { - return workingDir() + PRESETS_PATH; - } - - QString userSamplesDir() const - { - return workingDir() + SAMPLES_PATH; - } - - QString userGigDir() const - { - return workingDir() + GIG_PATH; - } - - QString userSf2Dir() const - { - return workingDir() + SF2_PATH; - } - - QString userLadspaDir() const - { - return workingDir() + LADSPA_PATH; - } - - QString userVstDir() const - { - return m_vstDir; + return m_dataDir; } QString factoryProjectsDir() const @@ -134,37 +96,27 @@ public: return dataDir() + SAMPLES_PATH; } - QString defaultVersion() const; - QString defaultArtworkDir() const + QString userProjectsDir() const { - return m_dataDir + DEFAULT_THEME_PATH; + return workingDir() + PROJECTS_PATH; } - QString artworkDir() const + QString userTemplateDir() const { - return m_artworkDir; + return workingDir() + TEMPLATE_PATH; } - QString trackIconsDir() const + QString userPresetsDir() const { - return m_dataDir + TRACK_ICON_PATH; + return workingDir() + PRESETS_PATH; } - QString localeDir() const + QString userSamplesDir() const { - return m_dataDir + LOCALE_PATH; + return workingDir() + SAMPLES_PATH; } - const QString & gigDir() const - { - return m_gigDir; - } - - const QString & sf2Dir() const - { - return m_sf2Dir; - } const QString & vstDir() const { @@ -173,18 +125,20 @@ public: const QString & ladspaDir() const { - return m_ladDir; + return m_ladspaDir; } - const QString recoveryFile() const + const QString & sf2Dir() const { - return m_workingDir + "recover.mmp"; + return m_sf2Dir; } - - const QString & version() const + +#ifdef LMMS_HAVE_FLUIDSYNTH + const QString & sf2File() const { - return m_version; + return m_sf2File; } +#endif #ifdef LMMS_HAVE_STK const QString & stkDir() const @@ -193,16 +147,55 @@ public: } #endif -#ifdef LMMS_HAVE_FLUIDSYNTH - const QString & defaultSoundfont() const + const QString & gigDir() const { - return m_defaultSoundfont; + return m_gigDir; } -#endif - const QString & backgroundArtwork() const + + QString userVstDir() const { - return m_backgroundArtwork; + return m_vstDir; + } + + QString userLadspaDir() const + { + return workingDir() + LADSPA_PATH; + } + + QString userSf2Dir() const + { + return workingDir() + SF2_PATH; + } + + QString userGigDir() const + { + return workingDir() + GIG_PATH; + } + + QString defaultThemeDir() const + { + return m_dataDir + DEFAULT_THEME_PATH; + } + + QString themeDir() const + { + return m_themeDir; + } + + const QString & backgroundPicFile() const + { + return m_backgroundPicFile; + } + + QString trackIconsDir() const + { + return m_dataDir + TRACK_ICON_PATH; + } + + const QString recoveryFile() const + { + return m_workingDir + "recover.mmp"; } inline const QStringList & recentlyOpenedProjects() const @@ -210,39 +203,51 @@ public: return m_recentlyOpenedProjects; } + QString localeDir() const + { + return m_dataDir + LOCALE_PATH; + } + + const QString & version() const + { + return m_version; + } + + QString defaultVersion() const; + + static QStringList availabeVstEmbedMethods(); QString vstEmbedMethod() const; - // returns true if the working dir (e.g. ~/lmms) exists on disk + // Returns true if the working dir (e.g. ~/lmms) exists on disk. bool hasWorkingDir() const; - void addRecentlyOpenedProject( const QString & _file ); + void addRecentlyOpenedProject(const QString & _file); - const QString & value( const QString & cls, - const QString & attribute ) const; - const QString & value( const QString & cls, + const QString & value(const QString & cls, + const QString & attribute) const; + const QString & value(const QString & cls, const QString & attribute, - const QString & defaultVal ) const; - void setValue( const QString & cls, const QString & attribute, - const QString & value ); - void deleteValue( const QString & cls, const QString & attribute); + const QString & defaultVal) const; + void setValue(const QString & cls, const QString & attribute, + const QString & value); + void deleteValue(const QString & cls, const QString & attribute); - void loadConfigFile( const QString & configFile = "" ); + void loadConfigFile(const QString & configFile = ""); void saveConfigFile(); - void setWorkingDir( const QString & _wd ); - void setVSTDir( const QString & _vd ); - void setArtworkDir( const QString & _ad ); - void setLADSPADir( const QString & _fd ); - void setVersion( const QString & _cv ); - void setSTKDir( const QString & _fd ); - void setDefaultSoundfont( const QString & _sf ); - void setBackgroundArtwork( const QString & _ba ); - void setGIGDir( const QString & gd ); - void setSF2Dir( const QString & sfd ); + void setWorkingDir(const QString & workingDir); + void setVSTDir(const QString & vstDir); + void setLADSPADir(const QString & ladspaDir); + void setSF2Dir(const QString & sf2Dir); + void setSF2File(const QString & sf2File); + void setSTKDir(const QString & stkDir); + void setGIGDir(const QString & gigDir); + void setThemeDir(const QString & themeDir); + void setBackgroundPicFile(const QString & backgroundPicFile); - // creates the working directory & subdirectories on disk. + // Creates the working directory & subdirectories on disk. void createWorkingDir(); signals: @@ -252,29 +257,29 @@ private: static ConfigManager * s_instanceOfMe; ConfigManager(); - ConfigManager( const ConfigManager & _c ); + ConfigManager(const ConfigManager & _c); ~ConfigManager(); void upgrade_1_1_90(); void upgrade_1_1_91(); void upgrade(); - QString m_lmmsRcFile; QString m_workingDir; QString m_dataDir; - QString m_artworkDir; QString m_vstDir; - QString m_ladDir; - QString m_gigDir; + QString m_ladspaDir; QString m_sf2Dir; - QString m_version; +#ifdef LMMS_HAVE_FLUIDSYNTH + QString m_sf2File; +#endif #ifdef LMMS_HAVE_STK QString m_stkDir; #endif -#ifdef LMMS_HAVE_FLUIDSYNTH - QString m_defaultSoundfont; -#endif - QString m_backgroundArtwork; + QString m_gigDir; + QString m_themeDir; + QString m_backgroundPicFile; + QString m_lmmsRcFile; + QString m_version; QStringList m_recentlyOpenedProjects; typedef QVector > stringPairVector; @@ -283,7 +288,5 @@ private: friend class LmmsCore; - -} ; - +}; #endif diff --git a/include/SetupDialog.h b/include/SetupDialog.h index 272ba7b09..4a2e5c025 100644 --- a/include/SetupDialog.h +++ b/include/SetupDialog.h @@ -1,4 +1,3 @@ - /* * SetupDialog.h - dialog for setting up LMMS * @@ -23,20 +22,20 @@ * */ + #ifndef SETUP_DIALOG_H #define SETUP_DIALOG_H #include #include +#include "AudioDevice.h" +#include "AudioDeviceSetupWidget.h" #include "LedCheckbox.h" #include "lmmsconfig.h" -#include "AudioDevice.h" #include "MidiClient.h" #include "MidiSetupWidget.h" -#include "AudioDeviceSetupWidget.h" - class QComboBox; class QLabel; @@ -48,17 +47,18 @@ class TabBar; class SetupDialog : public QDialog { Q_OBJECT + public: enum ConfigTabs { GeneralSettings, - PathSettings, PerformanceSettings, AudioSettings, - MidiSettings - } ; + MidiSettings, + PathsSettings + }; - SetupDialog( ConfigTabs _tab_to_open = GeneralSettings ); + SetupDialog(ConfigTabs tab_to_open = GeneralSettings); virtual ~SetupDialog(); @@ -67,148 +67,136 @@ protected slots: private slots: - // general settings widget - void setBufferSize( int _value ); - void resetBufSize(); + // General settings widget. + void toggleDisplaydBFS(bool enabled); + void toggleTooltips(bool enabled); + void toggleDisplayWaveform(bool enabled); + void toggleNoteLabels(bool enabled); + void toggleCompactTrackButtons(bool enabled); + void toggleOneInstrumentTrackWindow(bool enabled); + void toggleMMPZ(bool enabled); + void toggleDisableBackup(bool enabled); + void toggleOpenLastProject(bool enabled); + void setLanguage(int lang); - // path settings widget - void setWorkingDir( const QString & _wd ); - void setVSTDir( const QString & _vd ); - void setGIGDir( const QString & _gd ); - void setSF2Dir( const QString & _sfd ); - void setArtworkDir( const QString & _ad ); - void setLADSPADir( const QString & _ld ); - void setSTKDir( const QString & _sd ); - void setDefaultSoundfont( const QString & _sf ); - void setBackgroundArtwork( const QString & _ba ); - - // performance settings widget - void setAutoSaveInterval( int time ); + // Performance settings widget. + void setAutoSaveInterval(int time); void resetAutoSave(); - - // audio settings widget - void audioInterfaceChanged( const QString & _driver ); - - // MIDI settings widget - void midiInterfaceChanged( const QString & _driver ); - - - void toggleToolTips( bool _enabled ); - void toggleWarnAfterSetup( bool _enabled ); - void toggleDisplaydBFS( bool _enabled ); - void toggleMMPZ( bool _enabled ); - void toggleDisableBackup( bool _enabled ); - void toggleOpenLastProject( bool _enabled ); - void toggleHQAudioDev( bool _enabled ); - - void openWorkingDir(); - void openVSTDir(); - void openGIGDir(); - void openSF2Dir(); - void openArtworkDir(); - void openLADSPADir(); - void openSTKDir(); - void openDefaultSoundfont(); - void openBackgroundArtwork(); - - void toggleSmoothScroll( bool _enabled ); - void toggleAutoSave( bool _enabled ); - void toggleRunningAutoSave( bool _enabled ); - void toggleOneInstrumentTrackWindow( bool _enabled ); - void toggleCompactTrackButtons( bool _enabled ); - void toggleSyncVSTPlugins( bool _enabled ); - void toggleAnimateAFP( bool _enabled ); - void toggleNoteLabels( bool en ); - void toggleDisplayWaveform( bool en ); - void toggleDisableAutoquit( bool en ); - + void toggleAutoSave(bool enabled); + void toggleRunningAutoSave(bool enabled); + void toggleSmoothScroll(bool enabled); + void toggleAnimateAFP(bool enabled); + void toggleSyncVSTPlugins(bool enabled); void vstEmbedMethodChanged(); - void toggleVSTAlwaysOnTop( bool en ); + void toggleVSTAlwaysOnTop(bool en); + void toggleDisableAutoQuit(bool enabled); - void setLanguage( int lang ); + // Audio settings widget. + void audioInterfaceChanged(const QString & driver); + void toggleHQAudioDev(bool enabled); + void setBufferSize(int value); + void resetBufferSize(); + // MIDI settings widget. + void midiInterfaceChanged(const QString & driver); + + // Paths settings widget. + void openWorkingDir(); + void setWorkingDir(const QString & workingDir); + void openVSTDir(); + void setVSTDir(const QString & vstDir); + void openLADSPADir(); + void setLADSPADir(const QString & ladspaDir); + void openSF2Dir(); + void setSF2Dir(const QString & sf2Dir); + void openSF2File(); + void setSF2File(const QString & sf2File); + void openGIGDir(); + void setGIGDir(const QString & gigDir); + void openThemeDir(); + void setThemeDir(const QString & themeDir); + void openBackgroundPicFile(); + void setBackgroundPicFile(const QString & backgroundPicFile); + + void showRestartWarning(); private: TabBar * m_tabBar; - QSlider * m_bufSizeSlider; - QLabel * m_bufSizeLbl; - int m_bufferSize; - - bool m_toolTips; - bool m_warnAfterSetup; + // General settings widgets. bool m_displaydBFS; + bool m_tooltips; + bool m_displayWaveform; + bool m_printNoteLabels; + bool m_compactTrackButtons; + bool m_oneInstrumentTrackWindow; bool m_MMPZ; bool m_disableBackup; bool m_openLastProject; - bool m_NaNHandler; - bool m_hqAudioDev; QString m_lang; QStringList m_languages; - - QLineEdit * m_wdLineEdit; - QLineEdit * m_vdLineEdit; - QLineEdit * m_adLineEdit; - QLineEdit * m_ladLineEdit; - QLineEdit * m_gigLineEdit; - QLineEdit * m_sf2LineEdit; -#ifdef LMMS_HAVE_FLUIDSYNTH - QLineEdit * m_sfLineEdit; -#endif -#ifdef LMMS_HAVE_STK - QLineEdit * m_stkLineEdit; -#endif - QLineEdit * m_baLineEdit; - - QString m_workingDir; - QString m_vstDir; - QString m_artworkDir; - QString m_ladDir; - QString m_gigDir; - QString m_sf2Dir; -#ifdef LMMS_HAVE_FLUIDSYNTH - QString m_defaultSoundfont; -#endif -#ifdef LMMS_HAVE_STK - QString m_stkDir; -#endif - QString m_backgroundArtwork; - - bool m_smoothScroll; + // Performance settings widgets. + int m_saveInterval; bool m_enableAutoSave; bool m_enableRunningAutoSave; - int m_saveInterval; QSlider * m_saveIntervalSlider; QLabel * m_saveIntervalLbl; LedCheckBox * m_autoSave; LedCheckBox * m_runningAutoSave; - - bool m_oneInstrumentTrackWindow; - bool m_compactTrackButtons; - bool m_syncVSTPlugins; + bool m_smoothScroll; bool m_animateAFP; - bool m_printNoteLabels; - bool m_displayWaveform; + QLabel * m_vstEmbedLbl; + QComboBox* m_vstEmbedComboBox; + QString m_vstEmbedMethod; + LedCheckBox * m_vstAlwaysOnTopCheckBox; + bool m_vstAlwaysOnTop; + bool m_syncVSTPlugins; bool m_disableAutoQuit; + typedef QMap AswMap; typedef QMap MswMap; typedef QMap trMap; + // Audio settings widgets. QComboBox * m_audioInterfaces; AswMap m_audioIfaceSetupWidgets; trMap m_audioIfaceNames; + bool m_NaNHandler; + bool m_hqAudioDev; + int m_bufferSize; + QSlider * m_bufferSizeSlider; + QLabel * m_bufferSizeLbl; + // MIDI settings widgets. QComboBox * m_midiInterfaces; MswMap m_midiIfaceSetupWidgets; trMap m_midiIfaceNames; - QComboBox* m_vstEmbedComboBox; - QString m_vstEmbedMethod; - LedCheckBox * m_vstAlwaysOnTopCheckBox; - bool m_vstAlwaysOnTop; -} ; - - + // Paths settings widgets. + QString m_workingDir; + QString m_vstDir; + QString m_ladspaDir; + QString m_gigDir; + QString m_sf2Dir; +#ifdef LMMS_HAVE_FLUIDSYNTH + QString m_sf2File; +#endif + QString m_themeDir; + QString m_backgroundPicFile; + + QLineEdit * m_workingDirLineEdit; + QLineEdit * m_vstDirLineEdit; + QLineEdit * m_themeDirLineEdit; + QLineEdit * m_ladspaDirLineEdit; + QLineEdit * m_gigDirLineEdit; + QLineEdit * m_sf2DirLineEdit; +#ifdef LMMS_HAVE_FLUIDSYNTH + QLineEdit * m_sf2FileLineEdit; +#endif + QLineEdit * m_backgroundPicFileLineEdit; + + QLabel * restartWarningLbl; +}; #endif diff --git a/plugins/MidiImport/MidiImport.cpp b/plugins/MidiImport/MidiImport.cpp index e31c24508..1f2ab1f57 100644 --- a/plugins/MidiImport/MidiImport.cpp +++ b/plugins/MidiImport/MidiImport.cpp @@ -103,7 +103,7 @@ bool MidiImport::tryImport( TrackContainer* tc ) #ifdef LMMS_HAVE_FLUIDSYNTH if( gui != NULL && - ConfigManager::inst()->defaultSoundfont().isEmpty() ) + ConfigManager::inst()->sf2File().isEmpty() ) { QMessageBox::information( gui->mainWindow(), tr( "Setup incomplete" ), @@ -242,7 +242,7 @@ public: if( it_inst ) { isSF2 = true; - it_inst->loadFile( ConfigManager::inst()->defaultSoundfont() ); + it_inst->loadFile( ConfigManager::inst()->sf2File() ); it_inst->childModel( "bank" )->setValue( 0 ); it_inst->childModel( "patch" )->setValue( 0 ); } diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index cc2575d2b..99af22781 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -151,7 +151,7 @@ sf2Instrument::sf2Instrument( InstrumentTrack * _instrument_track ) : m_chorusDepth.setInitValue(settingVal); #endif - loadFile( ConfigManager::inst()->defaultSoundfont() ); + loadFile( ConfigManager::inst()->sf2File() ); updateSampleRate(); updateReverbOn(); diff --git a/src/core/ConfigManager.cpp b/src/core/ConfigManager.cpp index d8c783dd2..b8e8cd4ae 100644 --- a/src/core/ConfigManager.cpp +++ b/src/core/ConfigManager.cpp @@ -22,6 +22,7 @@ * */ + #include #include #include @@ -36,9 +37,10 @@ #include "lmmsversion.h" -static inline QString ensureTrailingSlash( const QString & s ) + +static inline QString ensureTrailingSlash(const QString & s ) { - if( ! s.isEmpty() && !s.endsWith('/') && !s.endsWith('\\') ) + if(! s.isEmpty() && !s.endsWith('/') && !s.endsWith('\\')) { return s + '/'; } @@ -50,14 +52,14 @@ ConfigManager * ConfigManager::s_instanceOfMe = NULL; ConfigManager::ConfigManager() : - m_lmmsRcFile( QDir::home().absolutePath() +"/.lmmsrc.xml" ), - m_workingDir( QStandardPaths::writableLocation( QStandardPaths::DocumentsLocation ) + "/lmms/"), - m_dataDir( "data:/" ), - m_artworkDir( defaultArtworkDir() ), - m_vstDir( m_workingDir + "vst/" ), - m_gigDir( m_workingDir + GIG_PATH ), - m_sf2Dir( m_workingDir + SF2_PATH ), - m_version( defaultVersion() ) + m_workingDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/lmms/"), + m_dataDir("data:/"), + m_vstDir(m_workingDir + "vst/"), + m_sf2Dir(m_workingDir + SF2_PATH), + m_gigDir(m_workingDir + GIG_PATH), + m_themeDir(defaultThemeDir()), + m_lmmsRcFile(QDir::home().absolutePath() +"/.lmmsrc.xml"), + m_version(defaultVersion()) { // Detect < 1.2.0 working directory as a courtesy if ( QFileInfo( QDir::home().absolutePath() + "/lmms/projects/" ).exists() ) @@ -125,19 +127,19 @@ ConfigManager::~ConfigManager() void ConfigManager::upgrade_1_1_90() { // Remove trailing " (bad latency!)" string which was once saved with PulseAudio - if( value( "mixer", "audiodev" ).startsWith( "PulseAudio (" ) ) + if(value("mixer", "audiodev").startsWith("PulseAudio (")) { setValue("mixer", "audiodev", "PulseAudio"); } // MidiAlsaRaw used to store the device info as "Device" instead of "device" - if ( value( "MidiAlsaRaw", "device" ).isNull() ) + if (value("MidiAlsaRaw", "device").isNull()) { // copy "device" = "Device" and then delete the old "Device" (further down) - QString oldDevice = value( "MidiAlsaRaw", "Device" ); + QString oldDevice = value("MidiAlsaRaw", "Device"); setValue("MidiAlsaRaw", "device", oldDevice); } - if ( !value( "MidiAlsaRaw", "device" ).isNull() ) + if (!value("MidiAlsaRaw", "device").isNull()) { // delete the old "Device" in the case that we just copied it to "device" // or if the user somehow set both the "Device" and "device" fields @@ -149,9 +151,9 @@ void ConfigManager::upgrade_1_1_90() void ConfigManager::upgrade_1_1_91() { // rename displaydbv to displaydbfs - if ( !value( "app", "displaydbv" ).isNull() ) { - setValue( "app", "displaydbfs", value( "app", "displaydbv" ) ); - deleteValue( "app", "displaydbv" ); + if (!value("app", "displaydbv").isNull()) { + setValue("app", "displaydbfs", value("app", "displaydbv")); + deleteValue("app", "displaydbv"); } } @@ -159,27 +161,27 @@ void ConfigManager::upgrade_1_1_91() void ConfigManager::upgrade() { // Skip the upgrade if versions match - if ( m_version == LMMS_VERSION ) + if (m_version == LMMS_VERSION) { return; } ProjectVersion createdWith = m_version; - if ( createdWith.setCompareType(ProjectVersion::Build) < "1.1.90" ) + if (createdWith.setCompareType(ProjectVersion::Build) < "1.1.90") { upgrade_1_1_90(); } - if ( createdWith.setCompareType(ProjectVersion::Build) < "1.1.91" ) + if (createdWith.setCompareType(ProjectVersion::Build) < "1.1.91") { upgrade_1_1_91(); } // Don't use old themes as they break the UI (i.e. 0.4 != 1.0, etc) - if ( createdWith.setCompareType(ProjectVersion::Minor) != LMMS_VERSION ) + if (createdWith.setCompareType(ProjectVersion::Minor) != LMMS_VERSION) { - m_artworkDir = defaultArtworkDir(); + m_themeDir = defaultThemeDir(); } // Bump the version, now that we are upgraded @@ -221,107 +223,115 @@ QString ConfigManager::vstEmbedMethod() const bool ConfigManager::hasWorkingDir() const { - return QDir( m_workingDir ).exists(); + return QDir(m_workingDir).exists(); } -void ConfigManager::setWorkingDir( const QString & wd ) +void ConfigManager::setWorkingDir(const QString & workingDir) { - m_workingDir = ensureTrailingSlash( QDir::cleanPath( wd ) ); + m_workingDir = ensureTrailingSlash(QDir::cleanPath(workingDir)); } -void ConfigManager::setVSTDir( const QString & _vd ) +void ConfigManager::setVSTDir(const QString & vstDir) { - m_vstDir = ensureTrailingSlash( _vd ); + m_vstDir = ensureTrailingSlash(vstDir); } -void ConfigManager::setArtworkDir( const QString & _ad ) +void ConfigManager::setLADSPADir(const QString & ladspaDir) { - m_artworkDir = ensureTrailingSlash( _ad ); + m_ladspaDir = ladspaDir; } -void ConfigManager::setLADSPADir( const QString & _fd ) -{ - m_ladDir = _fd; -} - - - - -void ConfigManager::setSTKDir( const QString & _fd ) +void ConfigManager::setSTKDir(const QString & stkDir) { #ifdef LMMS_HAVE_STK - m_stkDir = ensureTrailingSlash( _fd ); + m_stkDir = ensureTrailingSlash(stkDir); #endif } -void ConfigManager::setDefaultSoundfont( const QString & _sf ) +void ConfigManager::setSF2Dir(const QString & sf2Dir) +{ + m_sf2Dir = sf2Dir; +} + + + + +void ConfigManager::setSF2File(const QString & sf2File) { #ifdef LMMS_HAVE_FLUIDSYNTH - m_defaultSoundfont = _sf; + m_sf2File = sf2File; #endif } -void ConfigManager::setBackgroundArtwork( const QString & _ba ) +void ConfigManager::setGIGDir(const QString & gigDir) { - m_backgroundArtwork = _ba; + m_gigDir = gigDir; } -void ConfigManager::setGIGDir(const QString &gd) + + + +void ConfigManager::setThemeDir(const QString & themeDir) { - m_gigDir = gd; + m_themeDir = ensureTrailingSlash(themeDir); } -void ConfigManager::setSF2Dir(const QString &sfd) + + + +void ConfigManager::setBackgroundPicFile(const QString & backgroundPicFile) { - m_sf2Dir = sfd; + m_backgroundPicFile = backgroundPicFile; } + + void ConfigManager::createWorkingDir() { - QDir().mkpath( m_workingDir ); + QDir().mkpath(m_workingDir); - QDir().mkpath( userProjectsDir() ); - QDir().mkpath( userTemplateDir() ); - QDir().mkpath( userSamplesDir() ); - QDir().mkpath( userPresetsDir() ); - QDir().mkpath( userGigDir() ); - QDir().mkpath( userSf2Dir() ); - QDir().mkpath( userVstDir() ); - QDir().mkpath( userLadspaDir() ); + QDir().mkpath(userProjectsDir()); + QDir().mkpath(userTemplateDir()); + QDir().mkpath(userSamplesDir()); + QDir().mkpath(userPresetsDir()); + QDir().mkpath(userGigDir()); + QDir().mkpath(userSf2Dir()); + QDir().mkpath(userVstDir()); + QDir().mkpath(userLadspaDir()); } -void ConfigManager::addRecentlyOpenedProject( const QString & file ) +void ConfigManager::addRecentlyOpenedProject(const QString & file) { - QFileInfo recentFile( file ); - if( recentFile.suffix().toLower() == "mmp" || + QFileInfo recentFile(file); + if(recentFile.suffix().toLower() == "mmp" || recentFile.suffix().toLower() == "mmpz" || - recentFile.suffix().toLower() == "mpt" ) + recentFile.suffix().toLower() == "mpt") { - m_recentlyOpenedProjects.removeAll( file ); - if( m_recentlyOpenedProjects.size() > 50 ) + m_recentlyOpenedProjects.removeAll(file); + if(m_recentlyOpenedProjects.size() > 50) { m_recentlyOpenedProjects.removeLast(); } - m_recentlyOpenedProjects.push_front( file ); + m_recentlyOpenedProjects.push_front(file); ConfigManager::inst()->saveConfigFile(); } } @@ -329,18 +339,18 @@ void ConfigManager::addRecentlyOpenedProject( const QString & file ) -const QString & ConfigManager::value( const QString & cls, - const QString & attribute ) const +const QString & ConfigManager::value(const QString & cls, + const QString & attribute) const { - if( m_settings.contains( cls ) ) + if(m_settings.contains(cls)) { - for( stringPairVector::const_iterator it = + for(stringPairVector::const_iterator it = m_settings[cls].begin(); - it != m_settings[cls].end(); ++it ) + it != m_settings[cls].end(); ++it) { - if( ( *it ).first == attribute ) + if((*it).first == attribute) { - return ( *it ).second ; + return (*it).second ; } } } @@ -350,49 +360,49 @@ const QString & ConfigManager::value( const QString & cls, -const QString & ConfigManager::value( const QString & cls, +const QString & ConfigManager::value(const QString & cls, const QString & attribute, - const QString & defaultVal ) const + const QString & defaultVal) const { - const QString & val = value( cls, attribute ); + const QString & val = value(cls, attribute); return val.isEmpty() ? defaultVal : val; } -void ConfigManager::setValue( const QString & cls, +void ConfigManager::setValue(const QString & cls, const QString & attribute, - const QString & value ) + const QString & value) { - if( m_settings.contains( cls ) ) + if(m_settings.contains(cls)) { - for( QPair& pair : m_settings[cls]) + for(QPair& pair : m_settings[cls]) { - if( pair.first == attribute ) + if(pair.first == attribute) { - if ( pair.second != value ) + if (pair.second != value) { pair.second = value; - emit valueChanged( cls, attribute, value ); + emit valueChanged(cls, attribute, value); } return; } } } // not in map yet, so we have to add it... - m_settings[cls].push_back( qMakePair( attribute, value ) ); + m_settings[cls].push_back(qMakePair(attribute, value)); } -void ConfigManager::deleteValue( const QString & cls, const QString & attribute) +void ConfigManager::deleteValue(const QString & cls, const QString & attribute) { - if( m_settings.contains( cls ) ) + if(m_settings.contains(cls)) { - for( stringPairVector::iterator it = m_settings[cls].begin(); - it != m_settings[cls].end(); ++it ) + for(stringPairVector::iterator it = m_settings[cls].begin(); + it != m_settings[cls].end(); ++it) { - if( ( *it ).first == attribute ) + if((*it).first == attribute) { m_settings[cls].erase(it); return; @@ -402,23 +412,23 @@ void ConfigManager::deleteValue( const QString & cls, const QString & attribute) } -void ConfigManager::loadConfigFile( const QString & configFile ) +void ConfigManager::loadConfigFile(const QString & configFile) { // read the XML file and create DOM tree // Allow configuration file override through --config commandline option - if ( !configFile.isEmpty() ) + if (!configFile.isEmpty()) { m_lmmsRcFile = configFile; } - QFile cfg_file( m_lmmsRcFile ); + QFile cfg_file(m_lmmsRcFile); QDomDocument dom_tree; - if( cfg_file.open( QIODevice::ReadOnly ) ) + if(cfg_file.open(QIODevice::ReadOnly)) { QString errorString; int errorLine, errorCol; - if( dom_tree.setContent( &cfg_file, false, &errorString, &errorLine, &errorCol ) ) + if(dom_tree.setContent(&cfg_file, false, &errorString, &errorLine, &errorCol)) { // get the head information from the DOM QDomElement root = dom_tree.documentElement(); @@ -426,41 +436,41 @@ void ConfigManager::loadConfigFile( const QString & configFile ) QDomNode node = root.firstChild(); // Cache the config version for upgrade() - if ( !root.attribute( "version" ).isNull() ) { - m_version = root.attribute( "version" ); + if (!root.attribute("version").isNull()) { + m_version = root.attribute("version"); } // create the settings-map out of the DOM - while( !node.isNull() ) + while(!node.isNull()) { - if( node.isElement() && - node.toElement().hasAttributes () ) + if(node.isElement() && + node.toElement().hasAttributes ()) { stringPairVector attr; QDomNamedNodeMap node_attr = node.toElement().attributes(); - for( int i = 0; i < node_attr.count(); - ++i ) + for(int i = 0; i < node_attr.count(); + ++i) { - QDomNode n = node_attr.item( i ); - if( n.isAttr() ) + QDomNode n = node_attr.item(i); + if(n.isAttr()) { - attr.push_back( qMakePair( n.toAttr().name(), - n.toAttr().value() ) ); + attr.push_back(qMakePair(n.toAttr().name(), + n.toAttr().value())); } } m_settings[node.nodeName()] = attr; } - else if( node.nodeName() == "recentfiles" ) + else if(node.nodeName() == "recentfiles") { m_recentlyOpenedProjects.clear(); QDomNode n = node.firstChild(); - while( !n.isNull() ) + while(!n.isNull()) { - if( n.isElement() && n.toElement().hasAttributes() ) + if(n.isElement() && n.toElement().hasAttributes()) { m_recentlyOpenedProjects << - n.toElement().attribute( "path" ); + n.toElement().attribute("path"); } n = n.nextSibling(); } @@ -468,45 +478,45 @@ void ConfigManager::loadConfigFile( const QString & configFile ) node = node.nextSibling(); } - if( value( "paths", "artwork" ) != "" ) + if(value("paths", "theme") != "") { - m_artworkDir = value( "paths", "artwork" ); + m_themeDir = value("paths", "theme"); #ifdef LMMS_BUILD_WIN32 // Detect a QDir/QFile hang on Windows // see issue #3417 on github - bool badPath = ( m_artworkDir == "/" || m_artworkDir == "\\" ); + bool badPath = (m_themeDir == "/" || m_themeDir == "\\"); #else bool badPath = false; #endif - if( badPath || !QDir( m_artworkDir ).exists() || - !QFile( m_artworkDir + "/style.css" ).exists() ) + if(badPath || !QDir(m_themeDir).exists() || + !QFile(m_themeDir + "/style.css").exists()) { - m_artworkDir = defaultArtworkDir(); + m_themeDir = defaultThemeDir(); } - m_artworkDir = ensureTrailingSlash(m_artworkDir); + m_themeDir = ensureTrailingSlash(m_themeDir); } - setWorkingDir( value( "paths", "workingdir" ) ); + setWorkingDir(value("paths", "workingdir")); - setGIGDir( value( "paths", "gigdir" ) == "" ? gigDir() : value( "paths", "gigdir" ) ); - setSF2Dir( value( "paths", "sf2dir" ) == "" ? sf2Dir() : value( "paths", "sf2dir" ) ); - setVSTDir( value( "paths", "vstdir" ) ); - setLADSPADir( value( "paths", "laddir" ) ); + setGIGDir(value("paths", "gigdir") == "" ? gigDir() : value("paths", "gigdir")); + setSF2Dir(value("paths", "sf2dir") == "" ? sf2Dir() : value("paths", "sf2dir")); + setVSTDir(value("paths", "vstdir")); + setLADSPADir(value("paths", "ladspadir")); #ifdef LMMS_HAVE_STK - setSTKDir( value( "paths", "stkdir" ) ); + setSTKDir(value("paths", "stkdir")); #endif #ifdef LMMS_HAVE_FLUIDSYNTH - setDefaultSoundfont( value( "paths", "defaultsf2" ) ); + setSF2File(value("paths", "defaultsf2")); #endif - setBackgroundArtwork( value( "paths", "backgroundartwork" ) ); + setBackgroundPicFile(value("paths", "backgroundtheme")); } - else if( gui ) + else if(gui) { - QMessageBox::warning( NULL, MainWindow::tr( "Configuration file" ), - MainWindow::tr( "Error while parsing configuration file at line %1:%2: %3" ). - arg( errorLine ). - arg( errorCol ). - arg( errorString ) ); + QMessageBox::warning(NULL, MainWindow::tr("Configuration file"), + MainWindow::tr("Error while parsing configuration file at line %1:%2: %3"). + arg(errorLine). + arg(errorCol). + arg(errorString)); } cfg_file.close(); } @@ -517,21 +527,21 @@ void ConfigManager::loadConfigFile( const QString & configFile ) !QDir( m_vstDir ).exists() ) { #ifdef LMMS_BUILD_WIN32 - QString programFiles = QString::fromLocal8Bit( getenv( "ProgramFiles" ) ); + QString programFiles = QString::fromLocal8Bit(getenv("ProgramFiles")); m_vstDir = programFiles + "/VstPlugins/"; #else m_vstDir = m_workingDir + "plugins/vst/"; #endif } - if( m_ladDir.isEmpty() ) + if(m_ladspaDir.isEmpty() ) { - m_ladDir = userLadspaDir(); + m_ladspaDir = userLadspaDir(); } #ifdef LMMS_HAVE_STK - if( m_stkDir.isEmpty() || m_stkDir == QDir::separator() || m_stkDir == "/" || - !QDir( m_stkDir ).exists() ) + if(m_stkDir.isEmpty() || m_stkDir == QDir::separator() || m_stkDir == "/" || + !QDir(m_stkDir).exists()) { #if defined(LMMS_BUILD_WIN32) m_stkDir = m_dataDir + "stk/rawwaves/"; @@ -557,11 +567,11 @@ void ConfigManager::loadConfigFile( const QString & configFile ) QStringList searchPaths; if(! qgetenv("LMMS_THEME_PATH").isNull()) searchPaths << qgetenv("LMMS_THEME_PATH"); - searchPaths << artworkDir() << defaultArtworkDir(); - QDir::setSearchPaths( "resources", searchPaths); + searchPaths << themeDir() << defaultThemeDir(); + QDir::setSearchPaths("resources", searchPaths); // Create any missing subdirectories in the working dir, but only if the working dir exists - if( hasWorkingDir() ) + if(hasWorkingDir()) { createWorkingDir(); } @@ -572,72 +582,72 @@ void ConfigManager::loadConfigFile( const QString & configFile ) void ConfigManager::saveConfigFile() { - setValue( "paths", "artwork", m_artworkDir ); - setValue( "paths", "workingdir", m_workingDir ); - setValue( "paths", "vstdir", m_vstDir ); - setValue( "paths", "gigdir", m_gigDir ); - setValue( "paths", "sf2dir", m_sf2Dir ); - setValue( "paths", "laddir", m_ladDir ); + setValue("paths", "theme", m_themeDir); + setValue("paths", "workingdir", m_workingDir); + setValue("paths", "vstdir", m_vstDir); + setValue("paths", "gigdir", m_gigDir); + setValue("paths", "sf2dir", m_sf2Dir); + setValue("paths", "ladspadir", m_ladspaDir); #ifdef LMMS_HAVE_STK - setValue( "paths", "stkdir", m_stkDir ); + setValue("paths", "stkdir", m_stkDir); #endif #ifdef LMMS_HAVE_FLUIDSYNTH - setValue( "paths", "defaultsf2", m_defaultSoundfont ); + setValue("paths", "defaultsf2", m_sf2File); #endif - setValue( "paths", "backgroundartwork", m_backgroundArtwork ); + setValue("paths", "backgroundtheme", m_backgroundPicFile); - QDomDocument doc( "lmms-config-file" ); + QDomDocument doc("lmms-config-file"); - QDomElement lmms_config = doc.createElement( "lmms" ); - lmms_config.setAttribute( "version", m_version ); - doc.appendChild( lmms_config ); + QDomElement lmms_config = doc.createElement("lmms"); + lmms_config.setAttribute("version", m_version); + doc.appendChild(lmms_config); - for( settingsMap::iterator it = m_settings.begin(); - it != m_settings.end(); ++it ) + for(settingsMap::iterator it = m_settings.begin(); + it != m_settings.end(); ++it) { - QDomElement n = doc.createElement( it.key() ); - for( stringPairVector::iterator it2 = ( *it ).begin(); - it2 != ( *it ).end(); ++it2 ) + QDomElement n = doc.createElement(it.key()); + for(stringPairVector::iterator it2 = (*it).begin(); + it2 != (*it).end(); ++it2) { - n.setAttribute( ( *it2 ).first, ( *it2 ).second ); + n.setAttribute((*it2).first, (*it2).second); } - lmms_config.appendChild( n ); + lmms_config.appendChild(n); } - QDomElement recent_files = doc.createElement( "recentfiles" ); + QDomElement recent_files = doc.createElement("recentfiles"); - for( QStringList::iterator it = m_recentlyOpenedProjects.begin(); - it != m_recentlyOpenedProjects.end(); ++it ) + for(QStringList::iterator it = m_recentlyOpenedProjects.begin(); + it != m_recentlyOpenedProjects.end(); ++it) { - QDomElement n = doc.createElement( "file" ); - n.setAttribute( "path", *it ); - recent_files.appendChild( n ); + QDomElement n = doc.createElement("file"); + n.setAttribute("path", *it); + recent_files.appendChild(n); } - lmms_config.appendChild( recent_files ); + lmms_config.appendChild(recent_files); - QString xml = "\n" + doc.toString( 2 ); + QString xml = "\n" + doc.toString(2); - QFile outfile( m_lmmsRcFile ); - if( !outfile.open( QIODevice::WriteOnly | QIODevice::Truncate ) ) + QFile outfile(m_lmmsRcFile); + if(!outfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { QString title, message; - title = MainWindow::tr( "Could not open file" ); - message = MainWindow::tr( "Could not open file %1 " + title = MainWindow::tr("Could not open file"); + message = MainWindow::tr("Could not open file %1 " "for writing.\nPlease make " "sure you have write " "permission to the file and " "the directory containing the " "file and try again!" - ).arg( m_lmmsRcFile ); - if( gui ) + ).arg(m_lmmsRcFile); + if(gui) { - QMessageBox::critical( NULL, title, message, + QMessageBox::critical(NULL, title, message, QMessageBox::Ok, - QMessageBox::NoButton ); + QMessageBox::NoButton); } return; } - outfile.write( xml.toUtf8() ); + outfile.write(xml.toUtf8()); outfile.close(); } diff --git a/src/core/audio/AudioJack.cpp b/src/core/audio/AudioJack.cpp index e149f5cbd..aebfe5e1c 100644 --- a/src/core/audio/AudioJack.cpp +++ b/src/core/audio/AudioJack.cpp @@ -454,7 +454,7 @@ AudioJack::setupWidget::setupWidget( QWidget * _parent ) : m_clientName = new QLineEdit( cn, this ); m_clientName->setGeometry( 10, 20, 160, 20 ); - QLabel * cn_lbl = new QLabel( tr( "CLIENT-NAME" ), this ); + QLabel * cn_lbl = new QLabel( tr( "Client name" ), this ); cn_lbl->setFont( pointSize<7>( cn_lbl->font() ) ); cn_lbl->setGeometry( 10, 40, 160, 10 ); @@ -466,7 +466,7 @@ AudioJack::setupWidget::setupWidget( QWidget * _parent ) : m_channels = new LcdSpinBox( 1, this ); m_channels->setModel( m ); - m_channels->setLabel( tr( "CHANNELS" ) ); + m_channels->setLabel( tr( "Channels" ) ); m_channels->move( 180, 20 ); } diff --git a/src/core/audio/AudioOss.cpp b/src/core/audio/AudioOss.cpp index c9ad01801..bbd9a9507 100644 --- a/src/core/audio/AudioOss.cpp +++ b/src/core/audio/AudioOss.cpp @@ -327,7 +327,7 @@ AudioOss::setupWidget::setupWidget( QWidget * _parent ) : m_device = new QLineEdit( probeDevice(), this ); m_device->setGeometry( 10, 20, 160, 20 ); - QLabel * dev_lbl = new QLabel( tr( "DEVICE" ), this ); + QLabel * dev_lbl = new QLabel( tr( "Device" ), this ); dev_lbl->setFont( pointSize<7>( dev_lbl->font() ) ); dev_lbl->setGeometry( 10, 40, 160, 10 ); @@ -339,7 +339,7 @@ AudioOss::setupWidget::setupWidget( QWidget * _parent ) : m_channels = new LcdSpinBox( 1, this ); m_channels->setModel( m ); - m_channels->setLabel( tr( "CHANNELS" ) ); + m_channels->setLabel( tr( "Channels" ) ); m_channels->move( 180, 20 ); } diff --git a/src/core/audio/AudioPortAudio.cpp b/src/core/audio/AudioPortAudio.cpp index 61dca4a22..ad67277ab 100644 --- a/src/core/audio/AudioPortAudio.cpp +++ b/src/core/audio/AudioPortAudio.cpp @@ -412,14 +412,14 @@ AudioPortAudio::setupWidget::setupWidget( QWidget * _parent ) : m_backend = new ComboBox( this, "BACKEND" ); m_backend->setGeometry( 64, 15, 260, 20 ); - QLabel * backend_lbl = new QLabel( tr( "BACKEND" ), this ); + QLabel * backend_lbl = new QLabel( tr( "Backend" ), this ); backend_lbl->setFont( pointSize<7>( backend_lbl->font() ) ); backend_lbl->move( 8, 18 ); m_device = new ComboBox( this, "DEVICE" ); m_device->setGeometry( 64, 35, 260, 20 ); - QLabel * dev_lbl = new QLabel( tr( "DEVICE" ), this ); + QLabel * dev_lbl = new QLabel( tr( "Device" ), this ); dev_lbl->setFont( pointSize<7>( dev_lbl->font() ) ); dev_lbl->move( 8, 38 ); @@ -431,7 +431,7 @@ AudioPortAudio::setupWidget::setupWidget( QWidget * _parent ) : m_channels = new LcdSpinBox( 1, this ); m_channels->setModel( m ); - m_channels->setLabel( tr( "CHANNELS" ) ); + m_channels->setLabel( tr( "Channels" ) ); m_channels->move( 308, 20 );*/ connect( &m_setupUtil.m_backendModel, SIGNAL( dataChanged() ), diff --git a/src/core/audio/AudioPulseAudio.cpp b/src/core/audio/AudioPulseAudio.cpp index 857ef981b..af14960a7 100644 --- a/src/core/audio/AudioPulseAudio.cpp +++ b/src/core/audio/AudioPulseAudio.cpp @@ -314,7 +314,7 @@ AudioPulseAudio::setupWidget::setupWidget( QWidget * _parent ) : m_device = new QLineEdit( AudioPulseAudio::probeDevice(), this ); m_device->setGeometry( 10, 20, 160, 20 ); - QLabel * dev_lbl = new QLabel( tr( "DEVICE" ), this ); + QLabel * dev_lbl = new QLabel( tr( "Device" ), this ); dev_lbl->setFont( pointSize<7>( dev_lbl->font() ) ); dev_lbl->setGeometry( 10, 40, 160, 10 ); @@ -326,7 +326,7 @@ AudioPulseAudio::setupWidget::setupWidget( QWidget * _parent ) : m_channels = new LcdSpinBox( 1, this ); m_channels->setModel( m ); - m_channels->setLabel( tr( "CHANNELS" ) ); + m_channels->setLabel( tr( "Channels" ) ); m_channels->move( 180, 20 ); } diff --git a/src/core/audio/AudioSdl.cpp b/src/core/audio/AudioSdl.cpp index 42adb9b33..b970ba630 100644 --- a/src/core/audio/AudioSdl.cpp +++ b/src/core/audio/AudioSdl.cpp @@ -325,7 +325,7 @@ AudioSdl::setupWidget::setupWidget( QWidget * _parent ) : m_device = new QLineEdit( dev, this ); m_device->setGeometry( 10, 20, 160, 20 ); - QLabel * dev_lbl = new QLabel( tr( "DEVICE" ), this ); + QLabel * dev_lbl = new QLabel( tr( "Device" ), this ); dev_lbl->setFont( pointSize<7>( dev_lbl->font() ) ); dev_lbl->setGeometry( 10, 40, 160, 10 ); diff --git a/src/core/audio/AudioSndio.cpp b/src/core/audio/AudioSndio.cpp index 853d734d5..24bef9246 100644 --- a/src/core/audio/AudioSndio.cpp +++ b/src/core/audio/AudioSndio.cpp @@ -193,7 +193,7 @@ AudioSndio::setupWidget::setupWidget( QWidget * _parent ) : m_device = new QLineEdit( "", this ); m_device->setGeometry( 10, 20, 160, 20 ); - QLabel * dev_lbl = new QLabel( tr( "DEVICE" ), this ); + QLabel * dev_lbl = new QLabel( tr( "Device" ), this ); dev_lbl->setFont( pointSize<6>( dev_lbl->font() ) ); dev_lbl->setGeometry( 10, 40, 160, 10 ); @@ -205,7 +205,7 @@ AudioSndio::setupWidget::setupWidget( QWidget * _parent ) : m_channels = new LcdSpinBox( 1, this ); m_channels->setModel( m ); - m_channels->setLabel( tr( "CHANNELS" ) ); + m_channels->setLabel( tr( "Channels" ) ); m_channels->move( 180, 20 ); } diff --git a/src/core/audio/AudioSoundIo.cpp b/src/core/audio/AudioSoundIo.cpp index cde14a1c5..2c3d493a6 100644 --- a/src/core/audio/AudioSoundIo.cpp +++ b/src/core/audio/AudioSoundIo.cpp @@ -426,14 +426,14 @@ AudioSoundIo::setupWidget::setupWidget( QWidget * _parent ) : m_backend = new ComboBox( this, "BACKEND" ); m_backend->setGeometry( 64, 15, 260, 20 ); - QLabel * backend_lbl = new QLabel( tr( "BACKEND" ), this ); + QLabel * backend_lbl = new QLabel( tr( "Backend" ), this ); backend_lbl->setFont( pointSize<7>( backend_lbl->font() ) ); backend_lbl->move( 8, 18 ); m_device = new ComboBox( this, "DEVICE" ); m_device->setGeometry( 64, 35, 260, 20 ); - QLabel * dev_lbl = new QLabel( tr( "DEVICE" ), this ); + QLabel * dev_lbl = new QLabel( tr( "Device" ), this ); dev_lbl->setFont( pointSize<7>( dev_lbl->font() ) ); dev_lbl->move( 8, 38 ); diff --git a/src/gui/AudioDeviceSetupWidget.cpp b/src/gui/AudioDeviceSetupWidget.cpp index 86800643e..fbec38c76 100644 --- a/src/gui/AudioDeviceSetupWidget.cpp +++ b/src/gui/AudioDeviceSetupWidget.cpp @@ -24,9 +24,9 @@ #include "AudioDeviceSetupWidget.h" -AudioDeviceSetupWidget::AudioDeviceSetupWidget( const QString & _caption, QWidget * _parent ) : - TabWidget( TabWidget::tr( "Settings for %1" ).arg(TabWidget::tr( _caption.toLatin1() ) ).toUpper(), - _parent ) + +AudioDeviceSetupWidget::AudioDeviceSetupWidget(const QString & caption, QWidget * parent) : + TabWidget(TabWidget::tr("Settings for %1").arg(TabWidget::tr(caption.toLatin1())), parent) { } diff --git a/src/gui/GuiApplication.cpp b/src/gui/GuiApplication.cpp index a7a3d1baa..fb2e3eae3 100644 --- a/src/gui/GuiApplication.cpp +++ b/src/gui/GuiApplication.cpp @@ -67,8 +67,8 @@ GuiApplication::GuiApplication() ConfigManager::inst()->createWorkingDir(); } // Init style and palette - QDir::addSearchPath("artwork", ConfigManager::inst()->artworkDir()); - QDir::addSearchPath("artwork", ConfigManager::inst()->defaultArtworkDir()); + QDir::addSearchPath("artwork", ConfigManager::inst()->themeDir()); + QDir::addSearchPath("artwork", ConfigManager::inst()->defaultThemeDir()); QDir::addSearchPath("artwork", ":/artwork"); LmmsStyle* lmmsstyle = new LmmsStyle(); diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 0914d1685..bdb3a7472 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -174,16 +174,16 @@ MainWindow::MainWindow() : m_workspace = new QMdiArea( splitter ); // Load background - emit initProgress(tr("Loading background artwork")); - QString bgArtwork = ConfigManager::inst()->backgroundArtwork(); - QImage bgImage; - if( !bgArtwork.isEmpty() ) + emit initProgress(tr("Loading background picture")); + QString backgroundPicFile = ConfigManager::inst()->backgroundPicFile(); + QImage backgroundPic; + if( !backgroundPicFile.isEmpty() ) { - bgImage = QImage( bgArtwork ); + backgroundPic = QImage( backgroundPicFile ); } - if( !bgImage.isNull() ) + if( !backgroundPicFile.isNull() ) { - m_workspace->setBackground( bgImage ); + m_workspace->setBackground( backgroundPic ); } else { diff --git a/src/gui/MidiSetupWidget.cpp b/src/gui/MidiSetupWidget.cpp index f3001b3af..0c34544d6 100644 --- a/src/gui/MidiSetupWidget.cpp +++ b/src/gui/MidiSetupWidget.cpp @@ -29,23 +29,22 @@ #include "ConfigManager.h" #include "gui_templates.h" -MidiSetupWidget::MidiSetupWidget( const QString & caption, const QString & configSection, - const QString & devName, QWidget * parent ) : - TabWidget( TabWidget::tr( "Settings for %1" ).arg( - tr( caption.toLatin1() ) ).toUpper(), parent ), +MidiSetupWidget::MidiSetupWidget(const QString & caption, const QString & configSection, + const QString & devName, QWidget * parent) : + TabWidget(TabWidget::tr("Settings for %1").arg(tr(caption.toLatin1())), parent), m_configSection(configSection), m_device(nullptr) { // supply devName=QString() (distinct from QString("")) - // to indicate that there is no editable DEVICE field + // to indicate that there is no editable device field if (!devName.isNull()) { - m_device = new QLineEdit( devName, this ); - m_device->setGeometry( 10, 20, 160, 20 ); + m_device = new QLineEdit(devName, this); + m_device->setGeometry(10, 20, 160, 20); - QLabel * dev_lbl = new QLabel( tr( "DEVICE" ), this ); - dev_lbl->setFont( pointSize<7>( dev_lbl->font() ) ); - dev_lbl->setGeometry( 10, 40, 160, 10 ); + QLabel * dev_lbl = new QLabel(tr("Device"), this); + dev_lbl->setFont(pointSize<7>(dev_lbl->font())); + dev_lbl->setGeometry(10, 40, 160, 10); } } @@ -53,8 +52,8 @@ void MidiSetupWidget::saveSettings() { if (!m_configSection.isEmpty() && m_device) { - ConfigManager::inst()->setValue( m_configSection, "device", - m_device->text() ); + ConfigManager::inst()->setValue(m_configSection, "device", + m_device->text()); } } @@ -65,4 +64,3 @@ void MidiSetupWidget::show() parentWidget()->setVisible(visible); QWidget::setVisible(visible); } - diff --git a/src/gui/SetupDialog.cpp b/src/gui/SetupDialog.cpp index 5ab9630b2..f23b5b271 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -22,6 +22,7 @@ * */ + #include #include #include @@ -30,291 +31,247 @@ #include #include +#include "debug.h" +#include "embed.h" +#include "Engine.h" +#include "FileDialog.h" +#include "gui_templates.h" +#include "MainWindow.h" +#include "Mixer.h" +#include "ProjectJournal.h" #include "SetupDialog.h" #include "TabBar.h" #include "TabButton.h" -#include "gui_templates.h" -#include "Mixer.h" -#include "MainWindow.h" -#include "ProjectJournal.h" -#include "embed.h" -#include "Engine.h" -#include "debug.h" #include "ToolTip.h" -#include "FileDialog.h" -// platform-specific audio-interface-classes +// Platform-specific audio-interface classes. #include "AudioAlsa.h" #include "AudioAlsaSetupWidget.h" +#include "AudioDummy.h" #include "AudioJack.h" #include "AudioOss.h" -#include "AudioSndio.h" #include "AudioPortAudio.h" -#include "AudioSoundIo.h" #include "AudioPulseAudio.h" #include "AudioSdl.h" -#include "AudioDummy.h" +#include "AudioSndio.h" +#include "AudioSoundIo.h" -// platform-specific midi-interface-classes +// Platform-specific midi-interface classes. #include "MidiAlsaRaw.h" #include "MidiAlsaSeq.h" +#include "MidiApple.h" +#include "MidiDummy.h" #include "MidiJack.h" #include "MidiOss.h" #include "MidiSndio.h" #include "MidiWinMM.h" -#include "MidiApple.h" -#include "MidiDummy.h" + constexpr int BUFFERSIZE_RESOLUTION = 32; -inline void labelWidget( QWidget * _w, const QString & _txt ) +inline void labelWidget(QWidget * w, const QString & txt) { - QLabel * title = new QLabel( _txt, _w ); + QLabel * title = new QLabel(txt, w); QFont f = title->font(); - f.setBold( true ); - title->setFont( pointSize<12>( f ) ); + f.setBold(true); + title->setFont(pointSize<12>(f)); - assert( dynamic_cast( _w->layout() ) != NULL ); + assert(dynamic_cast(w->layout()) != NULL); - dynamic_cast( _w->layout() )->addSpacing( 5 ); - dynamic_cast( _w->layout() )->addWidget( title ); - dynamic_cast( _w->layout() )->addSpacing( 10 ); + dynamic_cast(w->layout())->addSpacing(5); + dynamic_cast(w->layout())->addWidget(title); } -SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : - m_bufferSize( ConfigManager::inst()->value( "mixer", - "framesperaudiobuffer" ).toInt() ), - m_toolTips( !ConfigManager::inst()->value( "tooltips", - "disabled" ).toInt() ), - m_warnAfterSetup( !ConfigManager::inst()->value( "app", - "nomsgaftersetup" ).toInt() ), - m_displaydBFS( ConfigManager::inst()->value( "app", - "displaydbfs" ).toInt() ), - m_MMPZ( !ConfigManager::inst()->value( "app", "nommpz" ).toInt() ), - m_disableBackup( !ConfigManager::inst()->value( "app", - "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", - "language" ) ), - m_workingDir( QDir::toNativeSeparators( ConfigManager::inst()->workingDir() ) ), - m_vstDir( QDir::toNativeSeparators( ConfigManager::inst()->vstDir() ) ), - m_artworkDir( QDir::toNativeSeparators( ConfigManager::inst()->artworkDir() ) ), - m_ladDir( QDir::toNativeSeparators( ConfigManager::inst()->ladspaDir() ) ), - m_gigDir( QDir::toNativeSeparators( ConfigManager::inst()->gigDir() ) ), - m_sf2Dir( QDir::toNativeSeparators( ConfigManager::inst()->sf2Dir() ) ), +SetupDialog::SetupDialog(ConfigTabs tab_to_open) : + m_displaydBFS(ConfigManager::inst()->value( + "app", "displaydbfs").toInt()), + m_tooltips(!ConfigManager::inst()->value( + "tooltips", "disabled").toInt()), + m_displayWaveform(ConfigManager::inst()->value( + "ui", "displaywaveform").toInt()), + m_printNoteLabels(ConfigManager::inst()->value( + "ui", "printnotelabels").toInt()), + m_compactTrackButtons(ConfigManager::inst()->value( + "ui", "compacttrackbuttons").toInt()), + m_oneInstrumentTrackWindow(ConfigManager::inst()->value( + "ui", "oneinstrumenttrackwindow").toInt()), + m_MMPZ(!ConfigManager::inst()->value( + "app", "nommpz").toInt()), + m_disableBackup(!ConfigManager::inst()->value( + "app", "disablebackup").toInt()), + m_openLastProject(ConfigManager::inst()->value( + "app", "openlastproject").toInt()), + m_lang(ConfigManager::inst()->value( + "app", "language")), + m_saveInterval( ConfigManager::inst()->value( + "ui", "saveinterval").toInt() < 1 ? + MainWindow::DEFAULT_SAVE_INTERVAL_MINUTES : + ConfigManager::inst()->value( + "ui", "saveinterval").toInt()), + m_enableAutoSave(ConfigManager::inst()->value( + "ui", "enableautosave", "1").toInt()), + m_enableRunningAutoSave(ConfigManager::inst()->value( + "ui", "enablerunningautosave", "0").toInt()), + m_smoothScroll(ConfigManager::inst()->value( + "ui", "smoothscroll").toInt()), + m_animateAFP(ConfigManager::inst()->value( + "ui", "animateafp", "1").toInt()), + m_vstEmbedMethod(ConfigManager::inst()->vstEmbedMethod()), + m_vstAlwaysOnTop(ConfigManager::inst()->value( + "ui", "vstalwaysontop").toInt()), + m_syncVSTPlugins(ConfigManager::inst()->value( + "ui", "syncvstplugins").toInt()), + m_disableAutoQuit(ConfigManager::inst()->value( + "ui", "disableautoquit").toInt()), + m_NaNHandler(ConfigManager::inst()->value( + "app", "nanhandler", "1").toInt()), + m_hqAudioDev(ConfigManager::inst()->value( + "mixer", "hqaudio").toInt()), + m_bufferSize(ConfigManager::inst()->value( + "mixer", "framesperaudiobuffer").toInt()), + m_workingDir(QDir::toNativeSeparators(ConfigManager::inst()->workingDir())), + m_vstDir(QDir::toNativeSeparators(ConfigManager::inst()->vstDir())), + m_ladspaDir(QDir::toNativeSeparators(ConfigManager::inst()->ladspaDir())), + m_gigDir(QDir::toNativeSeparators(ConfigManager::inst()->gigDir())), + m_sf2Dir(QDir::toNativeSeparators(ConfigManager::inst()->sf2Dir())), #ifdef LMMS_HAVE_FLUIDSYNTH - m_defaultSoundfont( QDir::toNativeSeparators( ConfigManager::inst()->defaultSoundfont() ) ), + m_sf2File(QDir::toNativeSeparators(ConfigManager::inst()->sf2File())), #endif -#ifdef LMMS_HAVE_STK - m_stkDir( QDir::toNativeSeparators( ConfigManager::inst()->stkDir() ) ), -#endif - m_backgroundArtwork( QDir::toNativeSeparators( ConfigManager::inst()->backgroundArtwork() ) ), - m_smoothScroll( ConfigManager::inst()->value( "ui", "smoothscroll" ).toInt() ), - m_enableAutoSave( ConfigManager::inst()->value( "ui", "enableautosave", "1" ).toInt() ), - m_enableRunningAutoSave( ConfigManager::inst()->value( "ui", "enablerunningautosave", "0" ).toInt() ), - m_saveInterval( ConfigManager::inst()->value( "ui", "saveinterval" ).toInt() < 1 ? - MainWindow::DEFAULT_SAVE_INTERVAL_MINUTES : - ConfigManager::inst()->value( "ui", "saveinterval" ).toInt() ), - m_oneInstrumentTrackWindow( ConfigManager::inst()->value( "ui", - "oneinstrumenttrackwindow" ).toInt() ), - m_compactTrackButtons( ConfigManager::inst()->value( "ui", - "compacttrackbuttons" ).toInt() ), - m_syncVSTPlugins( ConfigManager::inst()->value( "ui", - "syncvstplugins", "1" ).toInt() ), - m_animateAFP(ConfigManager::inst()->value( "ui", - "animateafp", "1" ).toInt() ), - m_printNoteLabels(ConfigManager::inst()->value( "ui", - "printnotelabels").toInt() ), - m_displayWaveform(ConfigManager::inst()->value( "ui", - "displaywaveform").toInt() ), - m_disableAutoQuit(ConfigManager::inst()->value( "ui", - "disableautoquit", "1" ).toInt() ), - m_vstEmbedMethod( ConfigManager::inst()->vstEmbedMethod() ), - m_vstAlwaysOnTop( ConfigManager::inst()->value( "ui", - "vstalwaysontop" ).toInt() ) + m_themeDir(QDir::toNativeSeparators(ConfigManager::inst()->themeDir())), + m_backgroundPicFile(QDir::toNativeSeparators(ConfigManager::inst()->backgroundPicFile())) { - setWindowIcon( embed::getIconPixmap( "setup_general" ) ); - setWindowTitle( tr( "Setup LMMS" ) ); - setModal( true ); - setFixedSize( 452, 570 ); + setWindowIcon(embed::getIconPixmap("setup_general")); + setWindowTitle(tr("Settings")); + // TODO: Equivalent to the new setWindowFlag(Qt::WindowContextHelpButtonHint, false) + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + setModal(true); + setFixedSize(454, 400); - Engine::projectJournal()->setJournalling( false ); + Engine::projectJournal()->setJournalling(false); - QVBoxLayout * vlayout = new QVBoxLayout( this ); - vlayout->setSpacing( 0 ); - vlayout->setMargin( 0 ); - QWidget * settings = new QWidget( this ); - QHBoxLayout * hlayout = new QHBoxLayout( settings ); - hlayout->setSpacing( 0 ); - hlayout->setMargin( 0 ); - m_tabBar = new TabBar( settings, QBoxLayout::TopToBottom ); - m_tabBar->setExclusive( true ); - m_tabBar->setFixedWidth( 72 ); - - QWidget * ws = new QWidget( settings ); - int wsHeight = 420; -#ifdef LMMS_HAVE_STK - wsHeight += 50; -#endif -#ifdef LMMS_HAVE_FLUIDSYNTH - wsHeight += 50; -#endif - ws->setFixedSize( 360, wsHeight ); - QWidget * general = new QWidget( ws ); - general->setFixedSize( 360, 290 ); - QVBoxLayout * gen_layout = new QVBoxLayout( general ); - gen_layout->setSpacing( 0 ); - gen_layout->setMargin( 0 ); - labelWidget( general, tr( "General settings" ) ); - - TabWidget * bufsize_tw = new TabWidget( tr( "BUFFER SIZE" ), general ); - bufsize_tw->setFixedHeight( 80 ); - - m_bufSizeSlider = new QSlider( Qt::Horizontal, bufsize_tw ); - 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 / BUFFERSIZE_RESOLUTION ); - - connect( m_bufSizeSlider, SIGNAL( valueChanged( int ) ), this, - SLOT( setBufferSize( int ) ) ); - - m_bufSizeLbl = new QLabel( bufsize_tw ); - m_bufSizeLbl->setGeometry( 10, 40, 200, 32 ); - setBufferSize( m_bufSizeSlider->value() ); - - QPushButton * bufsize_reset_btn = new QPushButton( - embed::getIconPixmap( "reload" ), "", bufsize_tw ); - bufsize_reset_btn->setGeometry( 320, 40, 28, 28 ); - connect( bufsize_reset_btn, SIGNAL( clicked() ), this, - SLOT( resetBufSize() ) ); - ToolTip::add( bufsize_reset_btn, tr( "Reset to default value" ) ); - - TabWidget * misc_tw = new TabWidget( tr( "MISC" ), general ); + // Constants for positioning LED check boxes. const int XDelta = 10; const int YDelta = 18; - const int HeaderSize = 30; - int labelNumber = 0; - auto addLedCheckBox = [&XDelta, &YDelta, &misc_tw, &labelNumber, this]( + // Main widget. + QWidget * main_w = new QWidget(this); + + + // Vertical layout. + QVBoxLayout * vlayout = new QVBoxLayout(this); + vlayout->setSpacing(0); + vlayout->setMargin(0); + + // Horizontal layout. + QHBoxLayout * hlayout = new QHBoxLayout(main_w); + hlayout->setSpacing(0); + hlayout->setMargin(0); + + // Tab bar for the main tabs. + m_tabBar = new TabBar(main_w, QBoxLayout::TopToBottom); + m_tabBar->setExclusive(true); + m_tabBar->setFixedWidth(72); + + // Settings widget. + QWidget * settings_w = new QWidget(main_w); + settings_w->setFixedSize(360, 360); + + // General widget. + QWidget * general_w = new QWidget(settings_w); + QVBoxLayout * general_layout = new QVBoxLayout(general_w); + general_layout->setSpacing(10); + general_layout->setMargin(0); + labelWidget(general_w, tr("General")); + + + auto addLedCheckBox = [&XDelta, &YDelta, this]( const char* ledText, + TabWidget* tw, + int& counter, bool initialState, - const char* toggledSlot + const char* toggledSlot, + bool showRestartWarning ){ - LedCheckBox * checkBox = new LedCheckBox(tr(ledText), misc_tw); - labelNumber++; - checkBox->move(XDelta, YDelta*labelNumber); + LedCheckBox * checkBox = new LedCheckBox(tr(ledText), tw); + counter++; + checkBox->move(XDelta, YDelta * counter); checkBox->setChecked(initialState); connect(checkBox, SIGNAL(toggled(bool)), this, toggledSlot); + if (showRestartWarning) + { + connect(checkBox, SIGNAL(toggled(bool)), this, SLOT(showRestartWarning())); + } }; - addLedCheckBox("Enable tooltips", - m_toolTips, SLOT(toggleToolTips(bool))); - addLedCheckBox("Show restart warning after changing settings", - m_warnAfterSetup, SLOT(toggleWarnAfterSetup(bool))); - addLedCheckBox("Display volume as dBFS ", - m_displaydBFS, SLOT(toggleDisplaydBFS(bool))); - addLedCheckBox("Compress project files per default", - m_MMPZ, SLOT(toggleMMPZ(bool))); - addLedCheckBox("One instrument track window mode", - m_oneInstrumentTrackWindow, - SLOT(toggleOneInstrumentTrackWindow(bool))); - addLedCheckBox("HQ-mode for output audio-device", - m_hqAudioDev, SLOT(toggleHQAudioDev(bool))); - addLedCheckBox("Compact track buttons", - m_compactTrackButtons, SLOT(toggleCompactTrackButtons(bool))); - addLedCheckBox("Sync VST plugins to host playback", - m_syncVSTPlugins, SLOT(toggleSyncVSTPlugins(bool))); - addLedCheckBox("Enable note labels in piano roll", - m_printNoteLabels, SLOT(toggleNoteLabels(bool))); - addLedCheckBox("Enable waveform display by default", - m_displayWaveform, SLOT(toggleDisplayWaveform(bool))); - addLedCheckBox("Keep effects running even without input", - m_disableAutoQuit, SLOT(toggleDisableAutoquit(bool))); - addLedCheckBox("Create backup file when saving a project", - m_disableBackup, SLOT(toggleDisableBackup(bool))); - addLedCheckBox("Reopen last project on start", - m_openLastProject, SLOT(toggleOpenLastProject(bool))); - misc_tw->setFixedHeight( YDelta*labelNumber + HeaderSize ); + int counter = 0; - // Advanced setting, hidden for now - if( false ) + // GUI tab. + TabWidget * gui_tw = new TabWidget( + tr("Graphical user interface (GUI)"), general_w); + + + addLedCheckBox("Display volume as dBFS ", gui_tw, counter, + m_displaydBFS, SLOT(toggleDisplaydBFS(bool)), true); + addLedCheckBox("Enable tooltips", gui_tw, counter, + m_tooltips, SLOT(toggleTooltips(bool)), true); + addLedCheckBox("Enable master oscilloscope by default", gui_tw, counter, + m_displayWaveform, SLOT(toggleDisplayWaveform(bool)), true); + addLedCheckBox("Enable all note labels in piano roll", gui_tw, counter, + m_printNoteLabels, SLOT(toggleNoteLabels(bool)), false); + addLedCheckBox("Enable compact track buttons", gui_tw, counter, + m_compactTrackButtons, SLOT(toggleCompactTrackButtons(bool)), true); + addLedCheckBox("Enable one instrument-track-window mode", gui_tw, counter, + m_oneInstrumentTrackWindow, SLOT(toggleOneInstrumentTrackWindow(bool)), true); + + gui_tw->setFixedHeight(YDelta + YDelta * counter); + + + counter = 0; + + // Projects tab. + TabWidget * projects_tw = new TabWidget( + tr("Projects"), general_w); + + + addLedCheckBox("Compress project files by default", projects_tw, counter, + m_MMPZ, SLOT(toggleMMPZ(bool)), true); + addLedCheckBox("Create a backup file when saving a project", projects_tw, counter, + m_disableBackup, SLOT(toggleDisableBackup(bool)), false); + addLedCheckBox("Reopen last project on startup", projects_tw, counter, + m_openLastProject, SLOT(toggleOpenLastProject(bool)), false); + + projects_tw->setFixedHeight(YDelta + YDelta * counter); + + // Language tab. + TabWidget * lang_tw = new TabWidget( + tr("Language"), general_w); + lang_tw->setFixedHeight(48); + QComboBox * changeLang = new QComboBox(lang_tw); + changeLang->move(XDelta, 20); + + QDir dir(ConfigManager::inst()->localeDir()); + QStringList fileNames = dir.entryList(QStringList("*.qm")); + for(int i = 0; i < fileNames.size(); ++i) { - LedCheckBox * useNaNHandler = new LedCheckBox( - tr( "Use built-in NaN handler" ), - misc_tw ); - useNaNHandler->setChecked( m_NaNHandler ); + // Get locale extracted by filename. + fileNames[i].truncate(fileNames[i].lastIndexOf('.')); + m_languages.append(fileNames[i]); + QString lang = QLocale(m_languages.last()).nativeLanguageName(); + changeLang->addItem(lang); } - TabWidget* embed_tw = new TabWidget( tr( "PLUGIN EMBEDDING" ), general); - embed_tw->setFixedHeight( 66 ); - m_vstEmbedComboBox = new QComboBox( embed_tw ); - m_vstEmbedComboBox->move( XDelta, YDelta ); - - QStringList embedMethods = ConfigManager::availabeVstEmbedMethods(); - m_vstEmbedComboBox->addItem( tr( "No embedding" ), "none" ); - if( embedMethods.contains("qt") ) + // If language unset, fallback to system language when available. + if(m_lang == "") { - m_vstEmbedComboBox->addItem( tr( "Embed using Qt API" ), "qt" ); - } - if( embedMethods.contains("win32") ) - { - m_vstEmbedComboBox->addItem( tr( "Embed using native Win32 API" ), "win32" ); - } - if( embedMethods.contains("xembed") ) - { - m_vstEmbedComboBox->addItem( tr( "Embed using XEmbed protocol" ), "xembed" ); - } - m_vstEmbedComboBox->setCurrentIndex( m_vstEmbedComboBox->findData( m_vstEmbedMethod ) ); - connect( m_vstEmbedComboBox, SIGNAL( currentIndexChanged( int ) ), - this, SLOT( vstEmbedMethodChanged() ) ); - - m_vstAlwaysOnTopCheckBox = new LedCheckBox( - tr( "Keep plugin windows on top when not embedded" ), - embed_tw ); - m_vstAlwaysOnTopCheckBox->move( 20, 44 ); - m_vstAlwaysOnTopCheckBox->setChecked( m_vstAlwaysOnTop ); - m_vstAlwaysOnTopCheckBox->setVisible( m_vstEmbedMethod == "none" ); - connect( m_vstAlwaysOnTopCheckBox, SIGNAL( toggled( bool ) ), - this, SLOT( toggleVSTAlwaysOnTop( bool ) ) ); - - TabWidget * lang_tw = new TabWidget( tr( "LANGUAGE" ), general ); - lang_tw->setFixedHeight( 48 ); - QComboBox * changeLang = new QComboBox( lang_tw ); - changeLang->move( XDelta, YDelta ); - - QDir dir( ConfigManager::inst()->localeDir() ); - QStringList fileNames = dir.entryList( QStringList( "*.qm" ) ); - for( int i = 0; i < fileNames.size(); ++i ) - { - // get locale extracted by filename - fileNames[i].truncate( fileNames[i].lastIndexOf( '.' ) ); - m_languages.append( fileNames[i] ); - QString lang = QLocale( m_languages.last() ).nativeLanguageName(); - changeLang->addItem( lang ); - } - connect( changeLang, SIGNAL( currentIndexChanged( int ) ), - this, SLOT( setLanguage( int ) ) ); - - //If language unset, fallback to system language when available - if( m_lang == "" ) - { - QString tmp = QLocale::system().name().left( 2 ); - if( m_languages.contains( tmp ) ) + QString tmp = QLocale::system().name().left(2); + if(m_languages.contains(tmp)) { m_lang = tmp; } @@ -324,69 +281,439 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : } } - for( int i = 0; i < changeLang->count(); ++i ) + for(int i = 0; i < changeLang->count(); ++i) { - if( m_lang == m_languages.at( i ) ) + if(m_lang == m_languages.at(i)) { - changeLang->setCurrentIndex( i ); + changeLang->setCurrentIndex(i); break; } } - gen_layout->addWidget( bufsize_tw ); - gen_layout->addSpacing( 10 ); - gen_layout->addWidget( misc_tw ); - gen_layout->addSpacing( 10 ); - gen_layout->addWidget( embed_tw ); - gen_layout->addSpacing( 10 ); - gen_layout->addWidget( lang_tw ); - gen_layout->addStretch(); + connect(changeLang, SIGNAL(currentIndexChanged(int)), + this, SLOT(setLanguage(int))); + connect(changeLang, SIGNAL(currentIndexChanged(int)), + this, SLOT(showRestartWarning())); + + + // General layout ordering. + general_layout->addWidget(gui_tw); + general_layout->addWidget(projects_tw); + general_layout->addWidget(lang_tw); + general_layout->addStretch(); - QWidget * paths = new QWidget( ws ); - int pathsHeight = 420; -#ifdef LMMS_HAVE_STK - pathsHeight += 55; + + // Performance widget. + QWidget * performance_w = new QWidget(settings_w); + QVBoxLayout * performance_layout = new QVBoxLayout(performance_w); + performance_layout->setSpacing(10); + performance_layout->setMargin(0); + labelWidget(performance_w, + tr("Performance")); + + + // Autosave tab. + TabWidget * auto_save_tw = new TabWidget( + tr("Autosave"), performance_w); + auto_save_tw->setFixedHeight(106); + + m_saveIntervalSlider = new QSlider(Qt::Horizontal, auto_save_tw); + m_saveIntervalSlider->setValue(m_saveInterval); + m_saveIntervalSlider->setRange(1, 20); + m_saveIntervalSlider->setTickInterval(1); + m_saveIntervalSlider->setPageStep(1); + m_saveIntervalSlider->setGeometry(10, 18, 340, 18); + m_saveIntervalSlider->setTickPosition(QSlider::TicksBelow); + + connect(m_saveIntervalSlider, SIGNAL(valueChanged(int)), + this, SLOT(setAutoSaveInterval(int))); + + m_saveIntervalLbl = new QLabel(auto_save_tw); + m_saveIntervalLbl->setGeometry(10, 40, 200, 24); + setAutoSaveInterval(m_saveIntervalSlider->value()); + + m_autoSave = new LedCheckBox( + tr("Enable autosave"), auto_save_tw); + m_autoSave->move(10, 70); + m_autoSave->setChecked(m_enableAutoSave); + connect(m_autoSave, SIGNAL(toggled(bool)), + this, SLOT(toggleAutoSave(bool))); + + m_runningAutoSave = new LedCheckBox( + tr("Allow autosave while playing"), auto_save_tw); + m_runningAutoSave->move(20, 88); + m_runningAutoSave->setChecked(m_enableRunningAutoSave); + connect(m_runningAutoSave, SIGNAL(toggled(bool)), + this, SLOT(toggleRunningAutoSave(bool))); + + QPushButton * autoSaveResetBtn = new QPushButton( + embed::getIconPixmap("reload"), "", auto_save_tw); + autoSaveResetBtn->setGeometry(320, 70, 28, 28); + connect(autoSaveResetBtn, SIGNAL(clicked()), + this, SLOT(resetAutoSave())); + + m_saveIntervalSlider->setEnabled(m_enableAutoSave); + m_runningAutoSave->setVisible(m_enableAutoSave); + + + counter = 0; + + // UI effect vs. performance tab. + TabWidget * ui_fx_tw = new TabWidget( + tr("User interface (UI) effects vs. performance"), performance_w); + + addLedCheckBox("Smooth scroll in song editor", ui_fx_tw, counter, + m_smoothScroll, SLOT(toggleSmoothScroll(bool)), false); + addLedCheckBox("Display playback cursor in AudioFileProcessor", ui_fx_tw, counter, + m_animateAFP, SLOT(toggleAnimateAFP(bool)), false); + + ui_fx_tw->setFixedHeight(YDelta + YDelta * counter); + + + counter = 0; + + // Plugins tab. + TabWidget * plugins_tw = new TabWidget( + tr("Plugins"), performance_w); + + m_vstEmbedLbl = new QLabel(plugins_tw); + m_vstEmbedLbl->move(XDelta, YDelta * ++counter); + m_vstEmbedLbl->setText(tr("VST plugins embedding:")); + + m_vstEmbedComboBox = new QComboBox(plugins_tw); + m_vstEmbedComboBox->move(XDelta, YDelta * ++counter); + + QStringList embedMethods = ConfigManager::availabeVstEmbedMethods(); + m_vstEmbedComboBox->addItem(tr("No embedding"), "none"); + if(embedMethods.contains("qt")) + { + m_vstEmbedComboBox->addItem(tr("Embed using Qt API"), "qt"); + } + if(embedMethods.contains("win32")) + { + m_vstEmbedComboBox->addItem(tr("Embed using native Win32 API"), "win32"); + } + if(embedMethods.contains("xembed")) + { + m_vstEmbedComboBox->addItem(tr("Embed using XEmbed protocol"), "xembed"); + } + m_vstEmbedComboBox->setCurrentIndex(m_vstEmbedComboBox->findData(m_vstEmbedMethod)); + connect(m_vstEmbedComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(vstEmbedMethodChanged())); + + counter += 2; + + m_vstAlwaysOnTopCheckBox = new LedCheckBox( + tr("Keep plugin windows on top when not embedded"), plugins_tw); + m_vstAlwaysOnTopCheckBox->move(20, 66); + m_vstAlwaysOnTopCheckBox->setChecked(m_vstAlwaysOnTop); + m_vstAlwaysOnTopCheckBox->setVisible(m_vstEmbedMethod == "none"); + connect(m_vstAlwaysOnTopCheckBox, SIGNAL(toggled(bool)), + this, SLOT(toggleVSTAlwaysOnTop(bool))); + + addLedCheckBox("Sync VST plugins to host playback", plugins_tw, counter, + m_syncVSTPlugins, SLOT(toggleSyncVSTPlugins(bool)), false); + + addLedCheckBox("Keep effects running even without input", plugins_tw, counter, + m_disableAutoQuit, SLOT(toggleDisableAutoQuit(bool)), false); + + plugins_tw->setFixedHeight(YDelta + YDelta * counter); + + + // Performance layout ordering. + performance_layout->addWidget(auto_save_tw); + performance_layout->addWidget(ui_fx_tw); + performance_layout->addWidget(plugins_tw); + performance_layout->addStretch(); + + + + // Audio widget. + QWidget * audio_w = new QWidget(settings_w); + QVBoxLayout * audio_layout = new QVBoxLayout(audio_w); + audio_layout->setSpacing(10); + audio_layout->setMargin(0); + labelWidget(audio_w, + tr("Audio")); + + // Audio interface tab. + TabWidget * audioiface_tw = new TabWidget( + tr("Audio interface"), audio_w); + audioiface_tw->setFixedHeight(56); + + m_audioInterfaces = new QComboBox(audioiface_tw); + m_audioInterfaces->setGeometry(10, 20, 240, 28); + + + // Ifaces-settings-widget. + QWidget * as_w = new QWidget(audio_w); + as_w->setFixedHeight(60); + + QHBoxLayout * as_w_layout = new QHBoxLayout(as_w); + as_w_layout->setSpacing(0); + as_w_layout->setMargin(0); + +#ifdef LMMS_HAVE_JACK + m_audioIfaceSetupWidgets[AudioJack::name()] = + new AudioJack::setupWidget(as_w); #endif -#ifdef LMMS_HAVE_FLUIDSYNTH - pathsHeight += 55; + +#ifdef LMMS_HAVE_ALSA + m_audioIfaceSetupWidgets[AudioAlsa::name()] = + new AudioAlsaSetupWidget(as_w); #endif - paths->setFixedSize( 360, pathsHeight ); - QVBoxLayout * dir_layout = new QVBoxLayout( paths ); - dir_layout->setSpacing( 0 ); - dir_layout->setMargin( 0 ); - labelWidget( paths, tr( "Paths" ) ); - QLabel * title = new QLabel( tr( "Directories" ), paths ); - QFont f = title->font(); - f.setBold( true ); - title->setFont( pointSize<12>( f ) ); + +#ifdef LMMS_HAVE_PULSEAUDIO + m_audioIfaceSetupWidgets[AudioPulseAudio::name()] = + new AudioPulseAudio::setupWidget(as_w); +#endif + +#ifdef LMMS_HAVE_PORTAUDIO + m_audioIfaceSetupWidgets[AudioPortAudio::name()] = + new AudioPortAudio::setupWidget(as_w); +#endif + +#ifdef LMMS_HAVE_SOUNDIO + m_audioIfaceSetupWidgets[AudioSoundIo::name()] = + new AudioSoundIo::setupWidget(as_w); +#endif + +#ifdef LMMS_HAVE_SDL + m_audioIfaceSetupWidgets[AudioSdl::name()] = + new AudioSdl::setupWidget(as_w); +#endif + +#ifdef LMMS_HAVE_OSS + m_audioIfaceSetupWidgets[AudioOss::name()] = + new AudioOss::setupWidget(as_w); +#endif + +#ifdef LMMS_HAVE_SNDIO + m_audioIfaceSetupWidgets[AudioSndio::name()] = + new AudioSndio::setupWidget(as_w); +#endif + + m_audioIfaceSetupWidgets[AudioDummy::name()] = + new AudioDummy::setupWidget(as_w); - QScrollArea *pathScroll = new QScrollArea( paths ); + for(AswMap::iterator it = m_audioIfaceSetupWidgets.begin(); + it != m_audioIfaceSetupWidgets.end(); ++it) + { + m_audioIfaceNames[ + tr(it.key().toLatin1())] = it.key(); + } + for(trMap::iterator it = m_audioIfaceNames.begin(); + it != m_audioIfaceNames.end(); ++it) + { + QWidget * audioWidget = m_audioIfaceSetupWidgets[it.value()]; + audioWidget->hide(); + as_w_layout->addWidget(audioWidget); + m_audioInterfaces->addItem(it.key()); + } - QWidget *pathSelectors = new QWidget( ws ); - QVBoxLayout *pathSelectorLayout = new QVBoxLayout; - pathScroll->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn ); - pathScroll->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); - pathScroll->resize( 362, pathsHeight - 50 ); - pathScroll->move( 0, 30 ); - pathSelectors->resize( 360, pathsHeight - 50 ); + // If no preferred audio device is saved, save the current one. + QString audioDevName = ConfigManager::inst()->value("mixer", "audiodev"); + if (m_audioInterfaces->findText(audioDevName) < 0) + { + audioDevName = Engine::mixer()->audioDevName(); + ConfigManager::inst()->setValue("mixer", "audiodev", audioDevName); + } + m_audioInterfaces-> + setCurrentIndex(m_audioInterfaces->findText(audioDevName)); + m_audioIfaceSetupWidgets[audioDevName]->show(); + + connect(m_audioInterfaces, SIGNAL(activated(const QString &)), + this, SLOT(audioInterfaceChanged(const QString &))); + + // Advanced setting, hidden for now + if(false) + { + LedCheckBox * useNaNHandler = new LedCheckBox( + tr("Use built-in NaN handler"), audio_w); + useNaNHandler->setChecked(m_NaNHandler); + } + + // HQ mode LED. + LedCheckBox * hqaudio = new LedCheckBox( + tr("HQ mode for output audio device"), audio_w); + hqaudio->move(10, 0); + hqaudio->setChecked(m_hqAudioDev); + connect(hqaudio, SIGNAL(toggled(bool)), + this, SLOT(toggleHQAudioDev(bool))); + + + // Buffer size tab. + TabWidget * bufferSize_tw = new TabWidget( + tr("Buffer size"), audio_w); + bufferSize_tw->setFixedHeight(76); + + m_bufferSizeSlider = new QSlider(Qt::Horizontal, bufferSize_tw); + m_bufferSizeSlider->setRange(1, 128); + m_bufferSizeSlider->setTickInterval(8); + m_bufferSizeSlider->setPageStep(8); + m_bufferSizeSlider->setValue(m_bufferSize / BUFFERSIZE_RESOLUTION); + m_bufferSizeSlider->setGeometry(10, 18, 340, 18); + m_bufferSizeSlider->setTickPosition(QSlider::TicksBelow); + + connect(m_bufferSizeSlider, SIGNAL(valueChanged(int)), + this, SLOT(setBufferSize(int))); + connect(m_bufferSizeSlider, SIGNAL(valueChanged(int)), + this, SLOT(showRestartWarning())); + + m_bufferSizeLbl = new QLabel(bufferSize_tw); + m_bufferSizeLbl->setGeometry(10, 40, 200, 24); + setBufferSize(m_bufferSizeSlider->value()); + + QPushButton * bufferSize_reset_btn = new QPushButton( + embed::getIconPixmap("reload"), "", bufferSize_tw); + bufferSize_reset_btn->setGeometry(320, 40, 28, 28); + connect(bufferSize_reset_btn, SIGNAL(clicked()), + this, SLOT(resetBufferSize())); + ToolTip::add(bufferSize_reset_btn, + tr("Reset to default value")); + + + // Audio layout ordering. + audio_layout->addWidget(audioiface_tw); + audio_layout->addWidget(as_w); + audio_layout->addWidget(hqaudio); + audio_layout->addWidget(bufferSize_tw); + audio_layout->addStretch(); + + + + // MIDI widget. + QWidget * midi_w = new QWidget(settings_w); + QVBoxLayout * midi_layout = new QVBoxLayout(midi_w); + midi_layout->setSpacing(10); + midi_layout->setMargin(0); + labelWidget(midi_w, + tr("MIDI")); + + // MIDI interface tab. + TabWidget * midiiface_tw = new TabWidget( + tr("MIDI interface"), midi_w); + midiiface_tw->setFixedHeight(56); + + m_midiInterfaces = new QComboBox(midiiface_tw); + m_midiInterfaces->setGeometry(10, 20, 240, 28); + + // Ifaces-settings-widget. + QWidget * ms_w = new QWidget(midi_w); + ms_w->setFixedHeight(60); + + QHBoxLayout * ms_w_layout = new QHBoxLayout(ms_w); + ms_w_layout->setSpacing(0); + ms_w_layout->setMargin(0); + +#ifdef LMMS_HAVE_ALSA + m_midiIfaceSetupWidgets[MidiAlsaSeq::name()] = + MidiSetupWidget::create(ms_w); + m_midiIfaceSetupWidgets[MidiAlsaRaw::name()] = + MidiSetupWidget::create(ms_w); +#endif + +#ifdef LMMS_HAVE_JACK + m_midiIfaceSetupWidgets[MidiJack::name()] = + MidiSetupWidget::create(ms_w); +#endif + +#ifdef LMMS_HAVE_OSS + m_midiIfaceSetupWidgets[MidiOss::name()] = + MidiSetupWidget::create(ms_w); +#endif + +#ifdef LMMS_HAVE_SNDIO + m_midiIfaceSetupWidgets[MidiSndio::name()] = + MidiSetupWidget::create(ms_w); +#endif + +#ifdef LMMS_BUILD_WIN32 + m_midiIfaceSetupWidgets[MidiWinMM::name()] = + MidiSetupWidget::create(ms_w); +#endif + +#ifdef LMMS_BUILD_APPLE + m_midiIfaceSetupWidgets[MidiApple::name()] = + MidiSetupWidget::create(ms_w); +#endif + + m_midiIfaceSetupWidgets[MidiDummy::name()] = + MidiSetupWidget::create(ms_w); + + + for(MswMap::iterator it = m_midiIfaceSetupWidgets.begin(); + it != m_midiIfaceSetupWidgets.end(); ++it) + { + m_midiIfaceNames[ + tr(it.key().toLatin1())] = it.key(); + } + for(trMap::iterator it = m_midiIfaceNames.begin(); + it != m_midiIfaceNames.end(); ++it) + { + QWidget * midiWidget = m_midiIfaceSetupWidgets[it.value()]; + midiWidget->hide(); + ms_w_layout->addWidget(midiWidget); + m_midiInterfaces->addItem(it.key()); + } + + QString midiDevName = ConfigManager::inst()->value("mixer", "mididev"); + if (m_midiInterfaces->findText(midiDevName) < 0) + { + midiDevName = Engine::mixer()->midiClientName(); + ConfigManager::inst()->setValue("mixer", "mididev", midiDevName); + } + m_midiInterfaces->setCurrentIndex(m_midiInterfaces->findText(midiDevName)); + m_midiIfaceSetupWidgets[midiDevName]->show(); + + connect(m_midiInterfaces, SIGNAL(activated(const QString &)), + this, SLOT(midiInterfaceChanged(const QString &))); + + + // MIDI layout ordering. + midi_layout->addWidget(midiiface_tw); + midi_layout->addWidget(ms_w); + midi_layout->addStretch(); + + + + // Paths widget. + QWidget * paths_w = new QWidget(settings_w); + + QVBoxLayout * paths_layout = new QVBoxLayout(paths_w); + paths_layout->setSpacing(10); + paths_layout->setMargin(0); + + labelWidget(paths_w, tr("Paths")); + + + // Paths scroll area. + QScrollArea * pathsScroll = new QScrollArea(paths_w); + pathsScroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + pathsScroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + // Path selectors widget. + QWidget * pathSelectors = new QWidget(paths_w); const int txtLength = 284; - const int btnStart = 297; + const int btnStart = 300; + // Path selectors layout. + QVBoxLayout * pathSelectorsLayout = new QVBoxLayout; + pathSelectorsLayout->setSpacing(10); auto addPathEntry = [&](const char* caption, const QString& content, const char* setSlot, const char* openSlot, QLineEdit*& lineEdit, - QWidget* twParent, const char* pixmap = "project_open") { - TabWidget * newTw = new TabWidget(tr(caption).toUpper(), - twParent); + TabWidget * newTw = new TabWidget(tr(caption), + pathSelectors); newTw->setFixedHeight(48); lineEdit = new QLineEdit(content, newTw); @@ -401,397 +728,122 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : selectBtn->move(btnStart, 16); connect(selectBtn, SIGNAL(clicked()), this, openSlot); - pathSelectorLayout->addWidget(newTw); - pathSelectorLayout->addSpacing(10); + pathSelectorsLayout->addWidget(newTw); + pathSelectorsLayout->addSpacing(10); }; addPathEntry("LMMS working directory", m_workingDir, SLOT(setWorkingDir(const QString &)), SLOT(openWorkingDir()), - m_wdLineEdit, pathSelectors); - addPathEntry("GIG directory", m_gigDir, - SLOT(setGIGDir(const QString &)), - SLOT(openGIGDir()), - m_gigLineEdit, pathSelectors); + m_workingDirLineEdit); + addPathEntry("VST plugins directory", m_vstDir, + SLOT(setVSTDir(const QString &)), + SLOT(openVSTDir()), + m_vstDirLineEdit); + addPathEntry("LADSPA plugins directories", m_ladspaDir, + SLOT(setLADSPADir(const QString &)), + SLOT(openLADSPADir()), + m_ladspaDirLineEdit, "add_folder"); addPathEntry("SF2 directory", m_sf2Dir, SLOT(setSF2Dir(const QString &)), SLOT(openSF2Dir()), - m_sf2LineEdit, pathSelectors); - addPathEntry("VST-plugin directory", m_vstDir, - SLOT(setVSTDir(const QString &)), - SLOT(openVSTDir()), - m_vdLineEdit, pathSelectors); - addPathEntry("LADSPA plugin directories", m_ladDir, - SLOT(setLADSPADir(const QString &)), - SLOT(openLADSPADir()), - m_ladLineEdit, paths, - "add_folder"); -#ifdef LMMS_HAVE_STK - addPathEntry("STK rawwave directory", m_stkDir, - SLOT(setSTKDir(const QString &)), - SLOT(openSTKDir()), - m_stkLineEdit, paths); -#endif + m_sf2DirLineEdit); #ifdef LMMS_HAVE_FLUIDSYNTH - addPathEntry("Default Soundfont File", m_defaultSoundfont, - SLOT(setDefaultSoundfont(const QString &)), - SLOT(openDefaultSoundfont()), - m_sfLineEdit, paths); + addPathEntry("Default SF2", m_sf2File, + SLOT(setSF2File(const QString &)), + SLOT(openSF2File()), + m_sf2FileLineEdit); #endif - addPathEntry("Themes directory", m_artworkDir, - SLOT(setArtworkDir(const QString &)), - SLOT(openArtworkDir()), - m_adLineEdit, pathSelectors); - pathSelectorLayout->addStretch(); - addPathEntry("Background artwork", m_backgroundArtwork, - SLOT(setBackgroundArtwork(const QString &)), - SLOT(openBackgroundArtwork()), - m_baLineEdit, paths); - pathSelectors->setLayout(pathSelectorLayout); - - - dir_layout->addWidget(pathSelectors); - - pathScroll->setWidget(pathSelectors); - pathScroll->setWidgetResizable(true); - - - - QWidget * performance = new QWidget( ws ); - performance->setFixedSize( 360, 200 ); - QVBoxLayout * perf_layout = new QVBoxLayout( performance ); - perf_layout->setSpacing( 0 ); - perf_layout->setMargin( 0 ); - labelWidget( performance, tr( "Performance settings" ) ); - - - TabWidget * auto_save_tw = new TabWidget( - tr( "Auto save" ).toUpper(), performance ); - auto_save_tw->setFixedHeight( 110 ); - - m_saveIntervalSlider = new QSlider( Qt::Horizontal, auto_save_tw ); - m_saveIntervalSlider->setRange( 1, 20 ); - m_saveIntervalSlider->setTickPosition( QSlider::TicksBelow ); - m_saveIntervalSlider->setPageStep( 1 ); - m_saveIntervalSlider->setTickInterval( 1 ); - m_saveIntervalSlider->setGeometry( 10, 16, 340, 18 ); - m_saveIntervalSlider->setValue( m_saveInterval ); - - connect( m_saveIntervalSlider, SIGNAL( valueChanged( int ) ), this, - SLOT( setAutoSaveInterval( int ) ) ); - - m_saveIntervalLbl = new QLabel( auto_save_tw ); - m_saveIntervalLbl->setGeometry( 10, 40, 200, 24 ); - setAutoSaveInterval( m_saveIntervalSlider->value() ); - - m_autoSave = new LedCheckBox( - tr( "Enable auto-save" ), auto_save_tw ); - m_autoSave->move( 10, 70 ); - m_autoSave->setChecked( m_enableAutoSave ); - connect( m_autoSave, SIGNAL( toggled( bool ) ), - this, SLOT( toggleAutoSave( bool ) ) ); - - m_runningAutoSave = new LedCheckBox( - tr( "Allow auto-save while playing" ), auto_save_tw ); - m_runningAutoSave->move( 20, 90 ); - m_runningAutoSave->setChecked( m_enableRunningAutoSave ); - connect( m_runningAutoSave, SIGNAL( toggled( bool ) ), - this, SLOT( toggleRunningAutoSave( bool ) ) ); - - QPushButton * autoSaveResetBtn = new QPushButton( - embed::getIconPixmap( "reload" ), "", auto_save_tw ); - autoSaveResetBtn->setGeometry( 320, 70, 28, 28 ); - connect( autoSaveResetBtn, SIGNAL( clicked() ), this, - SLOT( resetAutoSave() ) ); - ToolTip::add( autoSaveResetBtn, tr( "Reset to default value" ) ); - - m_saveIntervalSlider->setEnabled( m_enableAutoSave ); - m_runningAutoSave->setVisible( m_enableAutoSave ); - - - perf_layout->addWidget( auto_save_tw ); - perf_layout->addSpacing( 10 ); - - - TabWidget * ui_fx_tw = new TabWidget( tr( "UI effects vs. " - "performance" ).toUpper(), - performance ); - ui_fx_tw->setFixedHeight( 70 ); - - LedCheckBox * smoothScroll = new LedCheckBox( - tr( "Smooth scroll in Song Editor" ), ui_fx_tw ); - smoothScroll->move( 10, 20 ); - smoothScroll->setChecked( m_smoothScroll ); - connect( smoothScroll, SIGNAL( toggled( bool ) ), - this, SLOT( toggleSmoothScroll( bool ) ) ); - - LedCheckBox * animAFP = new LedCheckBox( - tr( "Show playback cursor in AudioFileProcessor" ), - ui_fx_tw ); - animAFP->move( 10, 40 ); - animAFP->setChecked( m_animateAFP ); - connect( animAFP, SIGNAL( toggled( bool ) ), - this, SLOT( toggleAnimateAFP( bool ) ) ); - - - - perf_layout->addWidget( ui_fx_tw ); - perf_layout->addStretch(); - - - - QWidget * audio = new QWidget( ws ); - audio->setFixedSize( 360, 200 ); - QVBoxLayout * audio_layout = new QVBoxLayout( audio ); - audio_layout->setSpacing( 0 ); - audio_layout->setMargin( 0 ); - labelWidget( audio, tr( "Audio settings" ) ); - - TabWidget * audioiface_tw = new TabWidget( tr( "AUDIO INTERFACE" ), - audio ); - audioiface_tw->setFixedHeight( 60 ); - - m_audioInterfaces = new QComboBox( audioiface_tw ); - m_audioInterfaces->setGeometry( 10, 20, 240, 22 ); - - - // create ifaces-settings-widget - QWidget * asw = new QWidget( audio ); - asw->setFixedHeight( 60 ); - - QHBoxLayout * asw_layout = new QHBoxLayout( asw ); - asw_layout->setSpacing( 0 ); - asw_layout->setMargin( 0 ); - //asw_layout->setAutoAdd( true ); - -#ifdef LMMS_HAVE_JACK - m_audioIfaceSetupWidgets[AudioJack::name()] = - new AudioJack::setupWidget( asw ); -#endif - -#ifdef LMMS_HAVE_ALSA - m_audioIfaceSetupWidgets[AudioAlsa::name()] = - new AudioAlsaSetupWidget( asw ); -#endif - -#ifdef LMMS_HAVE_PULSEAUDIO - m_audioIfaceSetupWidgets[AudioPulseAudio::name()] = - new AudioPulseAudio::setupWidget( asw ); -#endif - -#ifdef LMMS_HAVE_PORTAUDIO - m_audioIfaceSetupWidgets[AudioPortAudio::name()] = - new AudioPortAudio::setupWidget( asw ); -#endif - -#ifdef LMMS_HAVE_SOUNDIO - m_audioIfaceSetupWidgets[AudioSoundIo::name()] = - new AudioSoundIo::setupWidget( asw ); -#endif - -#ifdef LMMS_HAVE_SDL - m_audioIfaceSetupWidgets[AudioSdl::name()] = - new AudioSdl::setupWidget( asw ); -#endif - -#ifdef LMMS_HAVE_OSS - m_audioIfaceSetupWidgets[AudioOss::name()] = - new AudioOss::setupWidget( asw ); -#endif - -#ifdef LMMS_HAVE_SNDIO - m_audioIfaceSetupWidgets[AudioSndio::name()] = - new AudioSndio::setupWidget( asw ); -#endif - m_audioIfaceSetupWidgets[AudioDummy::name()] = - new AudioDummy::setupWidget( asw ); - - - for( AswMap::iterator it = m_audioIfaceSetupWidgets.begin(); - it != m_audioIfaceSetupWidgets.end(); ++it ) - { - m_audioIfaceNames[tr( it.key().toLatin1())] = it.key(); - } - for( trMap::iterator it = m_audioIfaceNames.begin(); - it != m_audioIfaceNames.end(); ++it ) - { - QWidget * audioWidget = m_audioIfaceSetupWidgets[it.value()]; - audioWidget->hide(); - asw_layout->addWidget( audioWidget ); - m_audioInterfaces->addItem( it.key() ); - } - - // If no preferred audio device is saved, save the current one - QString audioDevName = - ConfigManager::inst()->value( "mixer", "audiodev" ); - if( m_audioInterfaces->findText(audioDevName) < 0 ) - { - audioDevName = Engine::mixer()->audioDevName(); - ConfigManager::inst()->setValue( - "mixer", "audiodev", audioDevName ); - } - m_audioInterfaces-> - setCurrentIndex( m_audioInterfaces->findText( audioDevName ) ); - m_audioIfaceSetupWidgets[audioDevName]->show(); - - connect( m_audioInterfaces, SIGNAL( activated( const QString & ) ), - this, SLOT( audioInterfaceChanged( const QString & ) ) ); - - - audio_layout->addWidget( audioiface_tw ); - audio_layout->addSpacing( 20 ); - audio_layout->addWidget( asw ); - audio_layout->addStretch(); - - - - QWidget * midi = new QWidget( ws ); - QVBoxLayout * midi_layout = new QVBoxLayout( midi ); - midi_layout->setSpacing( 0 ); - midi_layout->setMargin( 0 ); - labelWidget( midi, tr( "MIDI settings" ) ); - - TabWidget * midiiface_tw = new TabWidget( tr( "MIDI INTERFACE" ), - midi ); - midiiface_tw->setFixedHeight( 60 ); - - m_midiInterfaces = new QComboBox( midiiface_tw ); - m_midiInterfaces->setGeometry( 10, 20, 240, 22 ); - - - // create ifaces-settings-widget - QWidget * msw = new QWidget( midi ); - msw->setFixedHeight( 60 ); - - QHBoxLayout * msw_layout = new QHBoxLayout( msw ); - msw_layout->setSpacing( 0 ); - msw_layout->setMargin( 0 ); - //msw_layout->setAutoAdd( true ); - -#ifdef LMMS_HAVE_ALSA - m_midiIfaceSetupWidgets[MidiAlsaSeq::name()] = - MidiSetupWidget::create( msw ); - m_midiIfaceSetupWidgets[MidiAlsaRaw::name()] = - MidiSetupWidget::create( msw ); -#endif - -#ifdef LMMS_HAVE_JACK - m_midiIfaceSetupWidgets[MidiJack::name()] = - MidiSetupWidget::create( msw ); -#endif - -#ifdef LMMS_HAVE_OSS - m_midiIfaceSetupWidgets[MidiOss::name()] = - MidiSetupWidget::create( msw ); -#endif - -#ifdef LMMS_HAVE_SNDIO - m_midiIfaceSetupWidgets[MidiSndio::name()] = - MidiSetupWidget::create( msw ); -#endif - -#ifdef LMMS_BUILD_WIN32 - m_midiIfaceSetupWidgets[MidiWinMM::name()] = - MidiSetupWidget::create( msw ); -#endif - -#ifdef LMMS_BUILD_APPLE - m_midiIfaceSetupWidgets[MidiApple::name()] = - MidiSetupWidget::create( msw ); -#endif - - m_midiIfaceSetupWidgets[MidiDummy::name()] = - MidiSetupWidget::create( msw ); - - - for( MswMap::iterator it = m_midiIfaceSetupWidgets.begin(); - it != m_midiIfaceSetupWidgets.end(); ++it ) - { - m_midiIfaceNames[tr( it.key().toLatin1())] = it.key(); - } - for( trMap::iterator it = m_midiIfaceNames.begin(); - it != m_midiIfaceNames.end(); ++it ) - { - QWidget * midiWidget = m_midiIfaceSetupWidgets[it.value()]; - midiWidget->hide(); - msw_layout->addWidget( midiWidget ); - m_midiInterfaces->addItem( it.key() ); - } - - QString midiDevName = - ConfigManager::inst()->value( "mixer", "mididev" ); - if( m_midiInterfaces->findText(midiDevName) < 0 ) - { - midiDevName = Engine::mixer()->midiClientName(); - ConfigManager::inst()->setValue( - "mixer", "mididev", midiDevName ); - } - m_midiInterfaces->setCurrentIndex( - m_midiInterfaces->findText( midiDevName ) ); - m_midiIfaceSetupWidgets[midiDevName]->show(); - - connect( m_midiInterfaces, SIGNAL( activated( const QString & ) ), - this, SLOT( midiInterfaceChanged( const QString & ) ) ); - - - midi_layout->addWidget( midiiface_tw ); - midi_layout->addSpacing( 20 ); - midi_layout->addWidget( msw ); - midi_layout->addStretch(); - - - m_tabBar->addTab( general, tr( "General settings" ), 0, false, true - )->setIcon( embed::getIconPixmap( "setup_general" ) ); - m_tabBar->addTab( paths, tr( "Paths" ), 1, false, true - )->setIcon( embed::getIconPixmap( - "setup_directories" ) ); - m_tabBar->addTab( performance, tr( "Performance settings" ), 2, false, - true )->setIcon( embed::getIconPixmap( - "setup_performance" ) ); - m_tabBar->addTab( audio, tr( "Audio settings" ), 3, false, true - )->setIcon( embed::getIconPixmap( "setup_audio" ) ); - m_tabBar->addTab( midi, tr( "MIDI settings" ), 4, true, true - )->setIcon( embed::getIconPixmap( "setup_midi" ) ); - - - m_tabBar->setActiveTab( _tab_to_open ); - - hlayout->addWidget( m_tabBar ); - hlayout->addSpacing( 10 ); - hlayout->addWidget( ws ); - hlayout->addSpacing( 10 ); - hlayout->addStretch(); - - QWidget * buttons = new QWidget( this ); - QHBoxLayout * btn_layout = new QHBoxLayout( buttons ); - btn_layout->setSpacing( 0 ); - btn_layout->setMargin( 0 ); - QPushButton * ok_btn = new QPushButton( embed::getIconPixmap( "apply" ), - tr( "OK" ), buttons ); - connect( ok_btn, SIGNAL( clicked() ), this, SLOT( accept() ) ); - - QPushButton * cancel_btn = new QPushButton( embed::getIconPixmap( - "cancel" ), - tr( "Cancel" ), - buttons ); - connect( cancel_btn, SIGNAL( clicked() ), this, SLOT( reject() ) ); - - btn_layout->addStretch(); - btn_layout->addSpacing( 10 ); - btn_layout->addWidget( ok_btn ); - btn_layout->addSpacing( 10 ); - btn_layout->addWidget( cancel_btn ); - btn_layout->addSpacing( 10 ); - - vlayout->addWidget( settings ); - vlayout->addSpacing( 10 ); - vlayout->addWidget( buttons ); - vlayout->addSpacing( 10 ); - vlayout->addStretch(); + addPathEntry("GIG directory", m_gigDir, + SLOT(setGIGDir(const QString &)), + SLOT(openGIGDir()), + m_gigDirLineEdit); + addPathEntry("Theme directory", m_themeDir, + SLOT(setThemeDir(const QString &)), + SLOT(openThemeDir()), + m_themeDirLineEdit); + addPathEntry("Background artwork", m_backgroundPicFile, + SLOT(setBackgroundPicFile(const QString &)), + SLOT(openBackgroundPicFile()), + m_backgroundPicFileLineEdit); + + pathSelectorsLayout->addStretch(); + + pathSelectors->setLayout(pathSelectorsLayout); + + pathsScroll->setWidget(pathSelectors); + pathsScroll->setWidgetResizable(true); + + paths_layout->addWidget(pathsScroll); + paths_layout->addStretch(); + + // Major tabs ordering. + m_tabBar->addTab(general_w, + tr("General"), 0, false, true)->setIcon( + embed::getIconPixmap("setup_general")); + m_tabBar->addTab(performance_w, + tr("Performance"), 1, false, true)->setIcon( + embed::getIconPixmap("setup_performance")); + m_tabBar->addTab(audio_w, + tr("Audio"), 2, false, true)->setIcon( + embed::getIconPixmap("setup_audio")); + m_tabBar->addTab(midi_w, + tr("MIDI"), 3, false, true)->setIcon( + embed::getIconPixmap("setup_midi")); + m_tabBar->addTab(paths_w, + tr("Paths"), 4, true, true)->setIcon( + embed::getIconPixmap("setup_directories")); + + m_tabBar->setActiveTab(tab_to_open); + + // Horizontal layout ordering. + hlayout->addSpacing(2); + hlayout->addWidget(m_tabBar); + hlayout->addSpacing(10); + hlayout->addWidget(settings_w); + hlayout->addSpacing(10); + + // Extras widget and layout. + QWidget * extras_w = new QWidget(this); + QHBoxLayout * extras_layout = new QHBoxLayout(extras_w); + extras_layout->setSpacing(0); + extras_layout->setMargin(0); + + // Restart warning label. + restartWarningLbl = new QLabel( + tr("Some changes require restarting."), extras_w); + restartWarningLbl->hide(); + + // OK button. + QPushButton * ok_btn = new QPushButton( + embed::getIconPixmap("apply"), + tr("OK"), extras_w); + connect(ok_btn, SIGNAL(clicked()), + this, SLOT(accept())); + + // Cancel button. + QPushButton * cancel_btn = new QPushButton( + embed::getIconPixmap("cancel"), + tr("Cancel"), extras_w); + connect(cancel_btn, SIGNAL(clicked()), + this, SLOT(reject())); + + // Extras layout ordering. + extras_layout->addSpacing(10); + extras_layout->addWidget(restartWarningLbl); + extras_layout->addStretch(); + extras_layout->addWidget(ok_btn); + extras_layout->addSpacing(10); + extras_layout->addWidget(cancel_btn); + extras_layout->addSpacing(10); + + // Vertical layout ordering. + vlayout->addWidget(main_w); + vlayout->addSpacing(10); + vlayout->addWidget(extras_w); + vlayout->addSpacing(10); show(); - - } @@ -799,7 +851,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) : SetupDialog::~SetupDialog() { - Engine::projectJournal()->setJournalling( true ); + Engine::projectJournal()->setJournalling(true); } @@ -807,286 +859,146 @@ SetupDialog::~SetupDialog() void SetupDialog::accept() { - if( m_warnAfterSetup ) - { - QMessageBox::information( NULL, tr( "Restart LMMS" ), - tr( "Please note that most changes " - "won't take effect until " - "you restart LMMS!" ), - QMessageBox::Ok ); - } - - // Hide dialog before setting values. This prevents an obscure bug - // where non-embedded VST windows would steal focus and prevent LMMS - // from taking mouse input, rendering the application unusable. + /* Hide dialog before setting values. This prevents an obscure bug + where non-embedded VST windows would steal focus and prevent LMMS + from taking mouse input, rendering the application unusable. */ QDialog::accept(); - ConfigManager::inst()->setValue( "mixer", "framesperaudiobuffer", - QString::number( m_bufferSize ) ); - ConfigManager::inst()->setValue( "mixer", "audiodev", - m_audioIfaceNames[m_audioInterfaces->currentText()] ); - ConfigManager::inst()->setValue( "mixer", "mididev", - m_midiIfaceNames[m_midiInterfaces->currentText()] ); - ConfigManager::inst()->setValue( "tooltips", "disabled", - QString::number( !m_toolTips ) ); - ConfigManager::inst()->setValue( "app", "nomsgaftersetup", - QString::number( !m_warnAfterSetup ) ); - ConfigManager::inst()->setValue( "app", "displaydbfs", - QString::number( m_displaydBFS ) ); - ConfigManager::inst()->setValue( "app", "nommpz", - QString::number( !m_MMPZ ) ); - ConfigManager::inst()->setValue( "app", "disablebackup", - 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", - QString::number( m_smoothScroll ) ); - ConfigManager::inst()->setValue( "ui", "enableautosave", - QString::number( m_enableAutoSave ) ); - ConfigManager::inst()->setValue( "ui", "saveinterval", - QString::number( m_saveInterval ) ); - ConfigManager::inst()->setValue( "ui", "enablerunningautosave", - QString::number( m_enableRunningAutoSave ) ); - ConfigManager::inst()->setValue( "ui", "oneinstrumenttrackwindow", - QString::number( m_oneInstrumentTrackWindow ) ); - ConfigManager::inst()->setValue( "ui", "compacttrackbuttons", - QString::number( m_compactTrackButtons ) ); - ConfigManager::inst()->setValue( "ui", "syncvstplugins", - QString::number( m_syncVSTPlugins ) ); - ConfigManager::inst()->setValue( "ui", "animateafp", - QString::number( m_animateAFP ) ); - ConfigManager::inst()->setValue( "ui", "printnotelabels", - QString::number( m_printNoteLabels ) ); - ConfigManager::inst()->setValue( "ui", "displaywaveform", - QString::number( m_displayWaveform ) ); - ConfigManager::inst()->setValue( "ui", "disableautoquit", - QString::number( m_disableAutoQuit ) ); - ConfigManager::inst()->setValue( "app", "language", m_lang ); - ConfigManager::inst()->setValue( "ui", "vstembedmethod", - m_vstEmbedMethod ); - ConfigManager::inst()->setValue( "ui", "vstalwaysontop", - QString::number( m_vstAlwaysOnTop ) ); + ConfigManager::inst()->setValue("app", "displaydbfs", + QString::number(m_displaydBFS)); + ConfigManager::inst()->setValue("tooltips", "disabled", + QString::number(!m_tooltips)); + ConfigManager::inst()->setValue("ui", "displaywaveform", + QString::number(m_displayWaveform)); + ConfigManager::inst()->setValue("ui", "printnotelabels", + QString::number(m_printNoteLabels)); + ConfigManager::inst()->setValue("ui", "compacttrackbuttons", + QString::number(m_compactTrackButtons)); + ConfigManager::inst()->setValue("ui", "oneinstrumenttrackwindow", + QString::number(m_oneInstrumentTrackWindow)); + ConfigManager::inst()->setValue("app", "nommpz", + QString::number(!m_MMPZ)); + ConfigManager::inst()->setValue("app", "disablebackup", + QString::number(!m_disableBackup)); + ConfigManager::inst()->setValue("app", "openlastproject", + QString::number(m_openLastProject)); + ConfigManager::inst()->setValue("app", "language", m_lang); + ConfigManager::inst()->setValue("ui", "saveinterval", + QString::number(m_saveInterval)); + ConfigManager::inst()->setValue("ui", "enableautosave", + QString::number(m_enableAutoSave)); + ConfigManager::inst()->setValue("ui", "enablerunningautosave", + QString::number(m_enableRunningAutoSave)); + ConfigManager::inst()->setValue("ui", "smoothscroll", + QString::number(m_smoothScroll)); + ConfigManager::inst()->setValue("ui", "animateafp", + QString::number(m_animateAFP)); + ConfigManager::inst()->setValue("ui", "vstembedmethod", + m_vstEmbedComboBox->currentData().toString()); + ConfigManager::inst()->setValue("ui", "vstalwaysontop", + QString::number(m_vstAlwaysOnTop)); + ConfigManager::inst()->setValue("ui", "syncvstplugins", + QString::number(m_syncVSTPlugins)); + ConfigManager::inst()->setValue("ui", "disableautoquit", + QString::number(m_disableAutoQuit)); + ConfigManager::inst()->setValue("mixer", "audiodev", + m_audioIfaceNames[m_audioInterfaces->currentText()]); + ConfigManager::inst()->setValue("app", "nanhandler", + QString::number(m_NaNHandler)); + ConfigManager::inst()->setValue("mixer", "hqaudio", + QString::number(m_hqAudioDev)); + ConfigManager::inst()->setValue("mixer", "framesperaudiobuffer", + QString::number(m_bufferSize)); + ConfigManager::inst()->setValue("mixer", "mididev", + m_midiIfaceNames[m_midiInterfaces->currentText()]); ConfigManager::inst()->setWorkingDir(QDir::fromNativeSeparators(m_workingDir)); ConfigManager::inst()->setVSTDir(QDir::fromNativeSeparators(m_vstDir)); - ConfigManager::inst()->setGIGDir(QDir::fromNativeSeparators(m_gigDir)); + ConfigManager::inst()->setLADSPADir(QDir::fromNativeSeparators(m_ladspaDir)); ConfigManager::inst()->setSF2Dir(QDir::fromNativeSeparators(m_sf2Dir)); - ConfigManager::inst()->setArtworkDir(QDir::fromNativeSeparators(m_artworkDir)); - ConfigManager::inst()->setLADSPADir(QDir::fromNativeSeparators(m_ladDir)); #ifdef LMMS_HAVE_FLUIDSYNTH - ConfigManager::inst()->setDefaultSoundfont( m_defaultSoundfont ); + ConfigManager::inst()->setSF2File(m_sf2File); #endif -#ifdef LMMS_HAVE_STK - ConfigManager::inst()->setSTKDir(QDir::fromNativeSeparators(m_stkDir)); -#endif - ConfigManager::inst()->setBackgroundArtwork( m_backgroundArtwork ); + ConfigManager::inst()->setGIGDir(QDir::fromNativeSeparators(m_gigDir)); + ConfigManager::inst()->setThemeDir(QDir::fromNativeSeparators(m_themeDir)); + ConfigManager::inst()->setBackgroundPicFile(m_backgroundPicFile); - // tell all audio-settings-widget to save their settings - for( AswMap::iterator it = m_audioIfaceSetupWidgets.begin(); - it != m_audioIfaceSetupWidgets.end(); ++it ) + // Tell all audio-settings-widgets to save their settings. + for(AswMap::iterator it = m_audioIfaceSetupWidgets.begin(); + it != m_audioIfaceSetupWidgets.end(); ++it) { it.value()->saveSettings(); } - // tell all MIDI-settings-widget to save their settings - for( MswMap::iterator it = m_midiIfaceSetupWidgets.begin(); - it != m_midiIfaceSetupWidgets.end(); ++it ) + // Tell all MIDI-settings-widgets to save their settings. + for(MswMap::iterator it = m_midiIfaceSetupWidgets.begin(); + it != m_midiIfaceSetupWidgets.end(); ++it) { it.value()->saveSettings(); } - ConfigManager::inst()->saveConfigFile(); } -void SetupDialog::setBufferSize( int _value ) +// General settings slots. + +void SetupDialog::toggleDisplaydBFS(bool enabled) { - const int step = DEFAULT_BUFFER_SIZE / BUFFERSIZE_RESOLUTION; - if( _value > step && _value % step ) - { - int mod_value = _value % step; - if( mod_value < step / 2 ) - { - m_bufSizeSlider->setValue( _value - mod_value ); - } - else - { - m_bufSizeSlider->setValue( _value + step - mod_value ); - } - return; - } - - if( m_bufSizeSlider->value() != _value ) - { - m_bufSizeSlider->setValue( _value ); - } - - m_bufferSize = _value * BUFFERSIZE_RESOLUTION; - m_bufSizeLbl->setText( tr( "Frames: %1\nLatency: %2 ms" ).arg( - m_bufferSize ).arg( - 1000.0f * m_bufferSize / - Engine::mixer()->processingSampleRate(), - 0, 'f', 1 ) ); + m_displaydBFS = enabled; } - - -void SetupDialog::resetBufSize() +void SetupDialog::toggleTooltips(bool enabled) { - setBufferSize( DEFAULT_BUFFER_SIZE / BUFFERSIZE_RESOLUTION ); + m_tooltips = enabled; } - - -void SetupDialog::toggleToolTips( bool _enabled ) +void SetupDialog::toggleDisplayWaveform(bool enabled) { - m_toolTips = _enabled; + m_displayWaveform = enabled; } - - -void SetupDialog::toggleWarnAfterSetup( bool _enabled ) +void SetupDialog::toggleNoteLabels(bool enabled) { - m_warnAfterSetup = _enabled; + m_printNoteLabels = enabled; } - - -void SetupDialog::toggleDisplaydBFS( bool _enabled ) +void SetupDialog::toggleCompactTrackButtons(bool enabled) { - m_displaydBFS = _enabled; + m_compactTrackButtons = enabled; } - - -void SetupDialog::toggleMMPZ( bool _enabled ) +void SetupDialog::toggleOneInstrumentTrackWindow(bool enabled) { - m_MMPZ = _enabled; + m_oneInstrumentTrackWindow = enabled; } - - -void SetupDialog::toggleDisableBackup( bool _enabled ) +void SetupDialog::toggleMMPZ(bool enabled) { - m_disableBackup = _enabled; + m_MMPZ = enabled; } - - -void SetupDialog::toggleOpenLastProject( bool _enabled ) +void SetupDialog::toggleDisableBackup(bool enabled) { - m_openLastProject = _enabled; + m_disableBackup = enabled; } - - -void SetupDialog::toggleHQAudioDev( bool _enabled ) +void SetupDialog::toggleOpenLastProject(bool enabled) { - m_hqAudioDev = _enabled; + m_openLastProject = enabled; } - - -void SetupDialog::toggleSmoothScroll( bool _enabled ) -{ - m_smoothScroll = _enabled; -} - - - - -void SetupDialog::toggleAutoSave( bool _enabled ) -{ - m_enableAutoSave = _enabled; - m_saveIntervalSlider->setEnabled( _enabled ); - m_runningAutoSave->setVisible( _enabled ); - setAutoSaveInterval( m_saveIntervalSlider->value() ); -} - - - - -void SetupDialog::toggleRunningAutoSave( bool _enabled ) -{ - m_enableRunningAutoSave = _enabled; -} - - - - -void SetupDialog::toggleCompactTrackButtons( bool _enabled ) -{ - m_compactTrackButtons = _enabled; -} - - - - - -void SetupDialog::toggleSyncVSTPlugins( bool _enabled ) -{ - m_syncVSTPlugins = _enabled; -} - -void SetupDialog::toggleAnimateAFP( bool _enabled ) -{ - m_animateAFP = _enabled; -} - - -void SetupDialog::toggleNoteLabels( bool en ) -{ - m_printNoteLabels = en; -} - - -void SetupDialog::toggleDisplayWaveform( bool en ) -{ - m_displayWaveform = en; -} - - -void SetupDialog::toggleDisableAutoquit( bool en ) -{ - m_disableAutoQuit = en; -} - - -void SetupDialog::toggleOneInstrumentTrackWindow( bool _enabled ) -{ - m_oneInstrumentTrackWindow = _enabled; -} - - -void SetupDialog::vstEmbedMethodChanged() -{ - m_vstEmbedMethod = m_vstEmbedComboBox->currentData().toString(); - m_vstAlwaysOnTopCheckBox->setVisible( m_vstEmbedMethod == "none" ); -} - - -void SetupDialog::toggleVSTAlwaysOnTop( bool en ) -{ - m_vstAlwaysOnTop = en; -} - - -void SetupDialog::setLanguage( int lang ) +void SetupDialog::setLanguage(int lang) { m_lang = m_languages[lang]; } @@ -1094,270 +1006,322 @@ void SetupDialog::setLanguage( int lang ) +// Performance settings slots. -void SetupDialog::openWorkingDir() -{ - QString new_dir = FileDialog::getExistingDirectory( this, - tr( "Choose LMMS working directory" ), m_workingDir ); - if( ! new_dir.isEmpty() ) - { - m_wdLineEdit->setText( new_dir ); - } -} - -void SetupDialog::openGIGDir() -{ - QString new_dir = FileDialog::getExistingDirectory( this, - tr( "Choose your GIG directory" ), - m_gigDir ); - if( ! new_dir.isEmpty() ) - { - m_gigLineEdit->setText( new_dir ); - } -} - -void SetupDialog::openSF2Dir() -{ - QString new_dir = FileDialog::getExistingDirectory( this, - tr( "Choose your SF2 directory" ), - m_sf2Dir ); - if( ! new_dir.isEmpty() ) - { - m_sf2LineEdit->setText( new_dir ); - } -} - - - - -void SetupDialog::setWorkingDir( const QString & _wd ) -{ - m_workingDir = _wd; -} - - - - -void SetupDialog::openVSTDir() -{ - QString new_dir = FileDialog::getExistingDirectory( this, - tr( "Choose your VST-plugin directory" ), - m_vstDir ); - if( ! new_dir.isEmpty() ) - { - m_vdLineEdit->setText( new_dir ); - } -} - - - - -void SetupDialog::setVSTDir( const QString & _vd ) -{ - m_vstDir = _vd; -} - -void SetupDialog::setGIGDir(const QString &_gd) -{ - m_gigDir = _gd; -} - -void SetupDialog::setSF2Dir(const QString &_sfd) -{ - m_sf2Dir = _sfd; -} - - - - -void SetupDialog::openArtworkDir() -{ - QString new_dir = FileDialog::getExistingDirectory( this, - tr( "Choose artwork-theme directory" ), - m_artworkDir ); - if( ! new_dir.isEmpty() ) - { - m_adLineEdit->setText( new_dir ); - } -} - - - - -void SetupDialog::setArtworkDir( const QString & _ad ) -{ - m_artworkDir = _ad; -} - - - - -void SetupDialog::openLADSPADir() -{ - QString new_dir = FileDialog::getExistingDirectory( this, - tr( "Choose LADSPA plugin directory" ), - m_ladDir ); - if( ! new_dir.isEmpty() ) - { - if( m_ladLineEdit->text() == "" ) - { - m_ladLineEdit->setText( new_dir ); - } - else - { - m_ladLineEdit->setText( m_ladLineEdit->text() + "," + - new_dir ); - } - } -} - - - -void SetupDialog::openSTKDir() -{ -#ifdef LMMS_HAVE_STK - QString new_dir = FileDialog::getExistingDirectory( this, - tr( "Choose STK rawwave directory" ), - m_stkDir ); - if( ! new_dir.isEmpty() ) - { - m_stkLineEdit->setText( new_dir ); - } -#endif -} - - - - -void SetupDialog::openDefaultSoundfont() -{ -#ifdef LMMS_HAVE_FLUIDSYNTH - QString new_file = FileDialog::getOpenFileName( this, - tr( "Choose default SoundFont" ), m_defaultSoundfont, - "SoundFont2 Files (*.sf2)" ); - - if( ! new_file.isEmpty() ) - { - m_sfLineEdit->setText( new_file ); - } -#endif -} - - - - -void SetupDialog::openBackgroundArtwork() -{ - QList fileTypesList = QImageReader::supportedImageFormats(); - QString fileTypes; - for( int i = 0; i < fileTypesList.count(); i++ ) - { - if( fileTypesList[i] != fileTypesList[i].toUpper() ) - { - if( !fileTypes.isEmpty() ) - { - fileTypes += " "; - } - fileTypes += "*." + QString( fileTypesList[i] ); - } - } - - QString dir = ( m_backgroundArtwork.isEmpty() ) ? - m_artworkDir : - m_backgroundArtwork; - QString new_file = FileDialog::getOpenFileName( this, - tr( "Choose background artwork" ), dir, - "Image Files (" + fileTypes + ")" ); - - if( ! new_file.isEmpty() ) - { - m_baLineEdit->setText( new_file ); - } -} - - - - -void SetupDialog::setLADSPADir( const QString & _fd ) -{ - m_ladDir = _fd; -} - - - - -void SetupDialog::setSTKDir( const QString & _fd ) -{ -#ifdef LMMS_HAVE_STK - m_stkDir = _fd; -#endif -} - - - - -void SetupDialog::setDefaultSoundfont( const QString & _sf ) -{ -#ifdef LMMS_HAVE_FLUIDSYNTH - m_defaultSoundfont = _sf; -#endif -} - - - - -void SetupDialog::setBackgroundArtwork( const QString & _ba ) -{ - m_backgroundArtwork = _ba; -} - - - - -void SetupDialog::setAutoSaveInterval( int value ) +void SetupDialog::setAutoSaveInterval(int value) { m_saveInterval = value; - m_saveIntervalSlider->setValue( m_saveInterval ); - QString minutes = m_saveInterval > 1 ? tr( "minutes" ) : tr( "minute" ); - minutes = QString( "%1 %2" ).arg( QString::number( m_saveInterval ), minutes ); - minutes = m_enableAutoSave ? minutes : tr( "Disabled" ); - m_saveIntervalLbl->setText( tr( "Auto-save interval: %1" ).arg( minutes ) ); + m_saveIntervalSlider->setValue(m_saveInterval); + QString minutes = m_saveInterval > 1 ? tr("minutes") : tr("minute"); + minutes = QString("%1 %2").arg(QString::number(m_saveInterval), minutes); + minutes = m_enableAutoSave ? minutes : tr("Disabled"); + m_saveIntervalLbl->setText( + tr("Autosave interval: %1").arg(minutes)); } +void SetupDialog::toggleAutoSave(bool enabled) +{ + m_enableAutoSave = enabled; + m_saveIntervalSlider->setEnabled(enabled); + m_runningAutoSave->setVisible(enabled); + setAutoSaveInterval(m_saveIntervalSlider->value()); +} + + +void SetupDialog::toggleRunningAutoSave(bool enabled) +{ + m_enableRunningAutoSave = enabled; +} void SetupDialog::resetAutoSave() { - setAutoSaveInterval( MainWindow::DEFAULT_SAVE_INTERVAL_MINUTES ); - m_autoSave->setChecked( true ); - m_runningAutoSave->setChecked( false ); + setAutoSaveInterval(MainWindow::DEFAULT_SAVE_INTERVAL_MINUTES); + m_autoSave->setChecked(true); + m_runningAutoSave->setChecked(false); +} + + +void SetupDialog::toggleSmoothScroll(bool enabled) +{ + m_smoothScroll = enabled; +} + + +void SetupDialog::toggleAnimateAFP(bool enabled) +{ + m_animateAFP = enabled; +} + + +void SetupDialog::toggleSyncVSTPlugins(bool enabled) +{ + m_syncVSTPlugins = enabled; +} + + +void SetupDialog::vstEmbedMethodChanged() +{ + m_vstEmbedMethod = m_vstEmbedComboBox->currentData().toString(); + m_vstAlwaysOnTopCheckBox->setVisible(m_vstEmbedMethod == "none"); +} + + +void SetupDialog::toggleVSTAlwaysOnTop(bool enabled) +{ + m_vstAlwaysOnTop = enabled; +} + + +void SetupDialog::toggleDisableAutoQuit(bool enabled) +{ + m_disableAutoQuit = enabled; } -void SetupDialog::audioInterfaceChanged( const QString & _iface ) +// Audio settings slots. + +void SetupDialog::toggleHQAudioDev(bool enabled) { - for( AswMap::iterator it = m_audioIfaceSetupWidgets.begin(); - it != m_audioIfaceSetupWidgets.end(); ++it ) + m_hqAudioDev = enabled; +} + + +void SetupDialog::audioInterfaceChanged(const QString & iface) +{ + for(AswMap::iterator it = m_audioIfaceSetupWidgets.begin(); + it != m_audioIfaceSetupWidgets.end(); ++it) { it.value()->hide(); } - m_audioIfaceSetupWidgets[m_audioIfaceNames[_iface]]->show(); + m_audioIfaceSetupWidgets[m_audioIfaceNames[iface]]->show(); } - - -void SetupDialog::midiInterfaceChanged( const QString & _iface ) +void SetupDialog::setBufferSize(int value) { - for( MswMap::iterator it = m_midiIfaceSetupWidgets.begin(); - it != m_midiIfaceSetupWidgets.end(); ++it ) + const int step = DEFAULT_BUFFER_SIZE / BUFFERSIZE_RESOLUTION; + if(value > step && value % step) + { + int mod_value = value % step; + if(mod_value < step / 2) + { + m_bufferSizeSlider->setValue(value - mod_value); + } + else + { + m_bufferSizeSlider->setValue(value + step - mod_value); + } + return; + } + + if(m_bufferSizeSlider->value() != value) + { + m_bufferSizeSlider->setValue(value); + } + + m_bufferSize = value * BUFFERSIZE_RESOLUTION; + m_bufferSizeLbl->setText(tr("Frames: %1\nLatency: %2 ms").arg(m_bufferSize).arg( + 1000.0f * m_bufferSize / Engine::mixer()->processingSampleRate(), 0, 'f', 1)); +} + + +void SetupDialog::resetBufferSize() +{ + setBufferSize(DEFAULT_BUFFER_SIZE / BUFFERSIZE_RESOLUTION); +} + + +// MIDI settings slots. + +void SetupDialog::midiInterfaceChanged(const QString & iface) +{ + for(MswMap::iterator it = m_midiIfaceSetupWidgets.begin(); + it != m_midiIfaceSetupWidgets.end(); ++it) { it.value()->hide(); } - m_midiIfaceSetupWidgets[m_midiIfaceNames[_iface]]->show(); + m_midiIfaceSetupWidgets[m_midiIfaceNames[iface]]->show(); +} + + +// Paths settings slots. + +void SetupDialog::openWorkingDir() +{ + QString new_dir = FileDialog::getExistingDirectory(this, + tr("Choose the LMMS working directory"), m_workingDir); + if (!new_dir.isEmpty()) + { + m_workingDirLineEdit->setText(new_dir); + } +} + + +void SetupDialog::setWorkingDir(const QString & workingDir) +{ + m_workingDir = workingDir; +} + + +void SetupDialog::openVSTDir() +{ + QString new_dir = FileDialog::getExistingDirectory(this, + tr("Choose your VST plugins directory"), m_vstDir); + if (!new_dir.isEmpty()) + { + m_vstDirLineEdit->setText(new_dir); + } +} + + +void SetupDialog::setVSTDir(const QString & vstDir) +{ + m_vstDir = vstDir; +} + + +void SetupDialog::openLADSPADir() +{ + QString new_dir = FileDialog::getExistingDirectory(this, + tr("Choose your LADSPA plugins directory"), m_ladspaDir); + if (!new_dir.isEmpty()) + { + if(m_ladspaDirLineEdit->text() == "") + { + m_ladspaDirLineEdit->setText(new_dir); + } + else + { + m_ladspaDirLineEdit->setText(m_ladspaDirLineEdit->text() + "," + + new_dir); + } + } +} + + +void SetupDialog::setLADSPADir(const QString & ladspaDir) +{ + m_ladspaDir = ladspaDir; +} + + +void SetupDialog::openSF2Dir() +{ + QString new_dir = FileDialog::getExistingDirectory(this, + tr("Choose your SF2 directory"), m_sf2Dir); + if (!new_dir.isEmpty()) + { + m_sf2DirLineEdit->setText(new_dir); + } +} + + +void SetupDialog::setSF2Dir(const QString & sf2Dir) +{ + m_sf2Dir = sf2Dir; +} + + +void SetupDialog::openSF2File() +{ +#ifdef LMMS_HAVE_FLUIDSYNTH + QString new_file = FileDialog::getOpenFileName(this, + tr("Choose your default SF2"), m_sf2File, "SoundFont 2 files (*.sf2)"); + + if (!new_file.isEmpty()) + { + m_sf2FileLineEdit->setText(new_file); + } +#endif +} + + +void SetupDialog::setSF2File(const QString & sf2File) +{ +#ifdef LMMS_HAVE_FLUIDSYNTH + m_sf2File = sf2File; +#endif +} + + +void SetupDialog::openGIGDir() +{ + QString new_dir = FileDialog::getExistingDirectory(this, + tr("Choose your GIG directory"), m_gigDir); + if(new_dir != QString::null) + { + m_gigDirLineEdit->setText(new_dir); + } +} + + +void SetupDialog::setGIGDir(const QString & gigDir) +{ + m_gigDir = gigDir; +} + + +void SetupDialog::openThemeDir() +{ + QString new_dir = FileDialog::getExistingDirectory(this, + tr("Choose your theme directory"), m_themeDir); + if(new_dir != QString::null) + { + m_themeDirLineEdit->setText(new_dir); + } +} + + +void SetupDialog::setThemeDir(const QString & themeDir) +{ + m_themeDir = themeDir; +} + + +void SetupDialog::openBackgroundPicFile() +{ + QList fileTypesList = QImageReader::supportedImageFormats(); + QString fileTypes; + for(int i = 0; i < fileTypesList.count(); i++) + { + if(fileTypesList[i] != fileTypesList[i].toUpper()) + { + if(!fileTypes.isEmpty()) + { + fileTypes += " "; + } + fileTypes += "*." + QString(fileTypesList[i]); + } + } + + QString dir = (m_backgroundPicFile.isEmpty()) ? + m_themeDir : + m_backgroundPicFile; + QString new_file = FileDialog::getOpenFileName(this, + tr("Choose your background picture"), dir, "Picture files (" + fileTypes + ")"); + + if(new_file != QString::null) + { + m_backgroundPicFileLineEdit->setText(new_file); + } +} + + +void SetupDialog::setBackgroundPicFile(const QString & backgroundPicFile) +{ + m_backgroundPicFile = backgroundPicFile; +} + + + + +void SetupDialog::showRestartWarning() +{ + restartWarningLbl->show(); } From e1236f53e2af1569182f01d6ec451c2cd1dd1bbb Mon Sep 17 00:00:00 2001 From: malcops Date: Sat, 7 Sep 2019 22:18:45 -0400 Subject: [PATCH 379/445] Remove maximize from Meter(Metro) menu (#5071) Fixes #4984. --- src/gui/widgets/TempoSyncKnob.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gui/widgets/TempoSyncKnob.cpp b/src/gui/widgets/TempoSyncKnob.cpp index 1e2e249f3..d769fd831 100644 --- a/src/gui/widgets/TempoSyncKnob.cpp +++ b/src/gui/widgets/TempoSyncKnob.cpp @@ -291,7 +291,11 @@ void TempoSyncKnob::showCustom() if( m_custom == NULL ) { m_custom = new MeterDialog( gui->mainWindow()->workspace() ); - gui->mainWindow()->addWindowedWidget( m_custom ); + QMdiSubWindow * subWindow = gui->mainWindow()->addWindowedWidget( m_custom ); + Qt::WindowFlags flags = subWindow->windowFlags(); + flags &= ~Qt::WindowMaximizeButtonHint; + subWindow->setWindowFlags( flags ); + subWindow->setFixedSize( subWindow->size() ); m_custom->setWindowTitle( "Meter" ); m_custom->setModel( &model()->m_custom ); } From 2e84cd3e0ce3b888d4dd9b87a85011af26e29767 Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Sun, 8 Sep 2019 13:43:15 +0100 Subject: [PATCH 380/445] Fix stuck keys when dragging on piano view (#5127) * Fix stuck keys when dragging on piano view * Add comment Co-Authored-By: Shmuel H. --- src/core/NotePlayHandle.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/NotePlayHandle.cpp b/src/core/NotePlayHandle.cpp index 1e6ce01c9..d62857350 100644 --- a/src/core/NotePlayHandle.cpp +++ b/src/core/NotePlayHandle.cpp @@ -199,7 +199,12 @@ void NotePlayHandle::play( sampleFrame * _working_buffer ) lock(); - if( m_totalFramesPlayed == 0 && !m_hasMidiNote + /* It is possible for NotePlayHandle::noteOff to be called before NotePlayHandle::play, + * which results in a note-on message being sent without a subsequent note-off message. + * Therefore, we check here whether the note has already been released before sending + * the note-on message. */ + if( !m_released + && m_totalFramesPlayed == 0 && !m_hasMidiNote && ( hasParent() || ! m_instrumentTrack->isArpeggioEnabled() ) ) { m_hasMidiNote = true; From a0e7a88e67d560264da8cb31576db4fae62c52b6 Mon Sep 17 00:00:00 2001 From: Hussam al-Homsi Date: Mon, 9 Sep 2019 00:22:43 -0400 Subject: [PATCH 381/445] Remove "What's This?" leftovers (#5173) --- data/themes/classic/style.css | 3 --- data/themes/default/style.css | 3 --- include/LmmsPalette.h | 6 ------ src/gui/LmmsPalette.cpp | 8 +------- 4 files changed, 1 insertion(+), 19 deletions(-) diff --git a/data/themes/classic/style.css b/data/themes/classic/style.css index 12d90981d..97d68f6e3 100644 --- a/data/themes/classic/style.css +++ b/data/themes/classic/style.css @@ -897,7 +897,4 @@ LmmsPalette { qproperty-brightText: #4afd85; qproperty-highlight: #202020; qproperty-highlightedText: #ffffff; - /* the next two are used for whatsthis dialogs */ - qproperty-toolTipText: #000; - qproperty-toolTipBase: #c9c9c9; } diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 5d889295c..ff6d032c2 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -920,7 +920,4 @@ LmmsPalette { qproperty-brightText: #d1d8e4; qproperty-highlight: #262b30; qproperty-highlightedText: #d1d8e4; - /* the next two are used for whatsthis dialogs */ - qproperty-toolTipText: #d1d8e4; - qproperty-toolTipBase: #101213; } diff --git a/include/LmmsPalette.h b/include/LmmsPalette.h index 49b831346..a8ee5d1c8 100644 --- a/include/LmmsPalette.h +++ b/include/LmmsPalette.h @@ -43,8 +43,6 @@ class LMMS_EXPORT LmmsPalette : public QWidget Q_PROPERTY( QColor brightText READ brightText WRITE setBrightText ) Q_PROPERTY( QColor highlight READ highlight WRITE setHighlight ) Q_PROPERTY( QColor highlightedText READ highlightedText WRITE setHighlightedText ) - Q_PROPERTY( QColor toolTipText READ toolTipText WRITE setToolTipText ) - Q_PROPERTY( QColor toolTipBase READ toolTipBase WRITE setToolTipBase ) public: LmmsPalette( QWidget * parent, QStyle * stylearg ); @@ -65,8 +63,6 @@ public: ACCESSMET( brightText, setBrightText ) ACCESSMET( highlight, setHighlight ) ACCESSMET( highlightedText, setHighlightedText ) - ACCESSMET( toolTipText, setToolTipText ) - ACCESSMET( toolTipBase, setToolTipBase ) #undef ACCESSMET @@ -83,8 +79,6 @@ private: QColor m_brightText; QColor m_highlight; QColor m_highlightedText; - QColor m_toolTipText; - QColor m_toolTipBase; }; diff --git a/src/gui/LmmsPalette.cpp b/src/gui/LmmsPalette.cpp index e58e72cea..e0b356d7a 100644 --- a/src/gui/LmmsPalette.cpp +++ b/src/gui/LmmsPalette.cpp @@ -42,9 +42,7 @@ LmmsPalette::LmmsPalette( QWidget * parent, QStyle * stylearg ) : m_buttonText( 0,0,0 ), m_brightText( 74, 253, 133 ), m_highlight( 100, 100, 100 ), - m_highlightedText( 255, 255, 255 ), - m_toolTipText( 0, 0, 0 ), - m_toolTipBase( 128, 128, 128 ) + m_highlightedText( 255, 255, 255 ) { setStyle( stylearg ); stylearg->polish( this ); @@ -72,8 +70,6 @@ LmmsPalette::~LmmsPalette() ACCESSMET( brightText, setBrightText ) ACCESSMET( highlight, setHighlight ) ACCESSMET( highlightedText, setHighlightedText ) - ACCESSMET( toolTipText, setToolTipText ) - ACCESSMET( toolTipBase, setToolTipBase ) QPalette LmmsPalette::palette() const @@ -90,8 +86,6 @@ QPalette LmmsPalette::palette() const pal.setColor( QPalette::Shadow, shadow() ); pal.setColor( QPalette::Highlight, highlight() ); pal.setColor( QPalette::HighlightedText, highlightedText() ); - pal.setBrush( QPalette::ToolTipText, QBrush( toolTipText() ) ); - pal.setBrush( QPalette::ToolTipBase, QBrush( toolTipBase() ) ); return pal; } From 91cf5bd88d3cb0878fa7af50f75a15a51316542c Mon Sep 17 00:00:00 2001 From: Dominic Clark Date: Tue, 10 Sep 2019 15:17:55 +0100 Subject: [PATCH 382/445] Support compilation with MSVC 2019 (#5180) --- plugins/vst_base/RemoteVstPlugin32.cmake | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/vst_base/RemoteVstPlugin32.cmake b/plugins/vst_base/RemoteVstPlugin32.cmake index 9a8f04529..ec290ce96 100644 --- a/plugins/vst_base/RemoteVstPlugin32.cmake +++ b/plugins/vst_base/RemoteVstPlugin32.cmake @@ -13,7 +13,10 @@ ELSEIF(LMMS_BUILD_WIN64 AND MSVC) SET(MSVC_VER ${CMAKE_CXX_COMPILER_VERSION}) IF(NOT CMAKE_GENERATOR_32) - IF(MSVC_VER VERSION_GREATER 19.10 OR MSVC_VER VERSION_EQUAL 19.10) + IF(MSVC_VER VERSION_GREATER 19.20 OR MSVC_VER VERSION_EQUAL 19.20) + SET(CMAKE_GENERATOR_32 "Visual Studio 16 2019") + SET(MSVC_YEAR 2017) # Qt only provides binaries for MSVC 2017, but 2019 is binary compatible + ELSEIF(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) @@ -39,6 +42,7 @@ ELSEIF(LMMS_BUILD_WIN64 AND MSVC) ExternalProject_Add(RemoteVstPlugin32 "${EXTERNALPROJECT_ARGS}" CMAKE_GENERATOR "${CMAKE_GENERATOR_32}" + CMAKE_GENERATOR_PLATFORM Win32 #CMAKE_GENERATOR_TOOLSET "${CMAKE_GENERATOR_TOOLSET}" CMAKE_ARGS "${EXTERNALPROJECT_CMAKE_ARGS}" From c436e5ca578e98f5d9b8eadbb077a283978cd867 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Fri, 13 Sep 2019 07:54:48 +0900 Subject: [PATCH 383/445] Remove MIDI connections from factory .mmpz files (#5163) --- ...apDan-TwilightArea-OriginalByAlf42red.mmpz | Bin 51694 -> 51679 bytes .../CapDan-ZeroSumGame-OriginalByZakarra.mmpz | Bin 43076 -> 43070 bytes data/projects/demos/EsoXLB-CPU.mmpz | Bin 33938 -> 33924 bytes ...- Krem Kaakkuja (Second Flight Remix).mmpz | Bin 46102 -> 46086 bytes data/projects/demos/Impulslogik-Zen.mmpz | Bin 37337 -> 37190 bytes .../projects/demos/Jousboxx-BuzzerBeater.mmpz | Bin 43351 -> 43235 bytes data/projects/demos/Momo64-esp.mmpz | Bin 55497 -> 55428 bytes data/projects/demos/Namitryus-K-Project.mmpz | Bin 63584 -> 63445 bytes data/projects/demos/Oglsdl-Dr8v2.mmpz | Bin 43206 -> 43069 bytes data/projects/demos/Oglsdl-PpTrip.mmpz | Bin 26086 -> 26015 bytes .../demos/Popsip-Electric Dancer.mmpz | Bin 26235 -> 26220 bytes data/projects/demos/Root84-Initialize.mmpz | Bin 17157 -> 17017 bytes data/projects/demos/Saber-FinalStep.mmpz | Bin 45501 -> 45429 bytes .../demos/Settel-InnerRecreation.mmpz | Bin 35882 -> 35811 bytes .../Shovon-ProgressiveHousePluckDemo.mmpz | Bin 16145 -> 16014 bytes data/projects/demos/Skiessi/Skiessi-C64.mmpz | Bin 5033 -> 5029 bytes .../projects/demos/Skiessi/Skiessi-Onion.mmpz | Bin 26929 -> 26919 bytes .../Skiessi-RandomProjectNumber14253.mmpz | Bin 18142 -> 18137 bytes .../demos/Skiessi/Skiessi-TurningPoint.mmpz | Bin 20851 -> 20844 bytes data/projects/demos/Socceroos-Progress.mmpz | Bin 18487 -> 18425 bytes data/projects/demos/TameAnderson-MakeMe.mmpz | Bin 60674 -> 60609 bytes data/projects/demos/Thaledric-Armageddon.mmpz | Bin 53974 -> 53910 bytes .../demos/Thomasso-AxeFromThe80s.mmpz | Bin 15390 -> 15255 bytes data/projects/demos/TobyDox-Psycho.mmpz | Bin 5856 -> 5787 bytes data/projects/demos/unfa-Spoken.mmpz | Bin 212235 -> 212173 bytes data/projects/shorties/DirtyLove.mmpz | Bin 8660 -> 8595 bytes data/projects/shorties/Root84-TrancyLoop.mmpz | Bin 4464 -> 4386 bytes data/projects/shorties/Skiessi-222.mmpz | Bin 4825 -> 4747 bytes data/projects/shorties/Surrender-Main.mmpz | Bin 3176 -> 3110 bytes data/projects/shorties/sv-DnB-Startup.mmpz | Bin 3906 -> 3829 bytes data/projects/shorties/sv-Trance-Startup.mmpz | Bin 3924 -> 3855 bytes 31 files changed, 0 insertions(+), 0 deletions(-) diff --git a/data/projects/demos/CapDan/CapDan-TwilightArea-OriginalByAlf42red.mmpz b/data/projects/demos/CapDan/CapDan-TwilightArea-OriginalByAlf42red.mmpz index 1687e8c343327ead0d969653b68a562567aa0c00..b4a00e1ea86f149a9fa998ff8b062971c1c7079c 100644 GIT binary patch delta 17931 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 KfBU~%OgH~O%@C~s diff --git a/data/projects/demos/CapDan/CapDan-ZeroSumGame-OriginalByZakarra.mmpz b/data/projects/demos/CapDan/CapDan-ZeroSumGame-OriginalByZakarra.mmpz index 95a29daff1d211fd6cbb3162656afec54ceb7998..578c4f926d40ebc42e42664c1b72a5c356f25108 100644 GIT binary patch delta 32433 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 Ku#W}DqyGoJ6ParO diff --git a/data/projects/demos/EsoXLB-CPU.mmpz b/data/projects/demos/EsoXLB-CPU.mmpz index 1c2549027e43a6b8323abaa43ef5fc23be978d68..bc2445e8761f703419afd9d899fd64bfbdff937d 100644 GIT binary patch delta 17243 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 delta 18444 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 diff --git a/data/projects/demos/Impulslogik-Zen.mmpz b/data/projects/demos/Impulslogik-Zen.mmpz index 05fa375c49f21628b86169c557b625083f1315d4..774ce89e3d5c0190db819712eddbcc75945e3349 100644 GIT binary patch delta 9767 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 J`+uM_4)h4qK2ZPw delta 640 zcmV-`0)PF4u>;Am0|WpN`m?bFS=N7hc8vxSkA6>Eo(op77};;=ch`>XqzCE%X8?CC zy8Lq4u~u5giUPNPvZH}o#nC`kJN?oRn0~Uy1hsvj)OqIxy9I5{x@E1-x`#gA+t$vW zb{{_<{M$_C5_GCRYI+Vji#)V!`2nVD}XOC)XCQI)9ioz@6TT@9xnd(?0hg2v!^dv-zxtoM-7gPck{<@2dfo2)=0oShDvCCL>2|+=|NiNF z|C1jqyAOBWyZPsjt7z>Gdfk683LGo?WJfl2+8O)ur`d{{+fTDKiOij6{6WjCBJv!4 z=rAiKUKFdL`_n9pUR<&>Nmih1g&}3M`Tshu)A|29-&amVK8739B7dQAkbL|en47sJ!krf2@Izb1cQhg4sG(X>sp z`}{pt?q4X@-xpv^{zA=ZZMuJDZQ308uFYWScpoEw^OxS{`LFxWkA6fAB=?m|7E$ht zAg(3;=HnmH$4BbpzkhT*o2ue3v}V@y!$(?(b{TE7SKXrP`_BD}P-Fk%E<1XzVUuFJ z2CQ8cjjO?5{+;yL|0rz2qltsHfJS#;!2_ aidOA=ORD^?yIzMMcXj>rZ~qV0SAjd2AZB0y diff --git a/data/projects/demos/Namitryus-K-Project.mmpz b/data/projects/demos/Namitryus-K-Project.mmpz index 6d463cbb95497e8233878585ed60e9f1deced5c1..4d62826c9b4d5c78b7e3e34e4d4e8e6d262c575e 100644 GIT binary patch delta 7393 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 CAW!lD diff --git a/data/projects/demos/Oglsdl-PpTrip.mmpz b/data/projects/demos/Oglsdl-PpTrip.mmpz index d1baceeba51d3dd468e5dc5f008a9ac7ad5f7b04..776aeea2bdd76055b17e10357e4fc5a47852a46e 100644 GIT binary patch delta 24682 zcma(2WpErp(=~{SEe4Av%aUa=T1*y`#mvkWGee6REM|+DnVFfHnVEUV&-=U^_uIG| zu|Fy&t1>IArn@?3`sB&|5%7!=Z~zSY!o(%*tWCpyhrOEanWw{dMck^o*km&8dfHzn8O2>qag&^uS?5(1UTp=vld!P6(=PDw7&QfWwm#W>+>Hca&|nQ6F-E@Ml2N)u0`GBTRR_6p zuRTL^2NTZZO5fz4t8cy7#jy_475T1rcu7o|AHJxFzXc>d*4Q?xyV%lA^F)75 zK;SDDRO@qJK*$Lo+{bthskMoj4I|6}n;g1+ewdaazaf;~jpbK{Py~Mmf0r~cxwiZq zP_z@IjX0R`7Vyzwtw-i^4s`a*MsHI=V=d=b zbs)A zpnG{R$xI8H^^F9n^|A_sLnop7#A^%J#qafO`py@LfCeHm@UF%cV>gG<6^=ZUe1Csn zX@zO7a9+olvM|ysL3xxJo_fzy9ZtfsM!}Q;-NE}}b##j8;y&Ia))k|rPm|P$ml1AB zC+}g@>#tiD0J;CknQ6?zpZ#h&b?j9V=8-EF>^(q1wQV@Gz|pVkrkeTEz(Bl9R?=xR z@nqlxn~7Yjqc90Yd&^PlvAiRETQOAm$PRiRmK;&f(Z?=~T(>+thv@R!Zd2&y5PGUt zMrX5Euj~knIH_-(cqi?7;_pe&rm2`)v)A8P1D)L(0LLQ7}eTxySVi5bbn zZ&7A}x7fHl@l&9Y-I8@N;(f!V23gqq z*nI;g%$vrsbz$W!Q1hBK#OP6L{1I<74o-qkL%Vni9!gxpoHa+>xry%=npMS|y^5h* z9iGjKM3b*KI~|TS!fs|R(&9-J0n>+3r3QfvP}##83%eZ9bmEB*YqQS#9YR>f8OAkX z2o-3ewVR@#jpe_&gC)aUq?5pP%8SL|!(`5^9&Tl^7ERNQI{rR1)}w2n8P!Y0vSOld zq%i;PTJwwTuAei|y-0iTNWF68(08r!5c@RA$qGZF!D2%-LaVjpa9e9_Yg?$*x%MNS8MGFs+()kRBQd-5yuj(?wa<|O}nx;oUK(xw`}AvR6aj{YUfFr z5Y>6_=zf)8f7c#8?T!R6OYrnAHdKah;Jm!i?=L{+HRaN;TNvo+1aoHZd1hU$sP1C- zGwT0!oamx^MDQK1=G73WE`LVroutVCbXt}BF`N|m>d#ki(ld-BkHLQj%!)5VtfDFy#Jen2euU!cXM2Y0SGEwA+S#-ah1*rOd@Hp(JyWa+L_jo= zKhByOLwKjt=<4`%Q9JLX?rh%HOLDucRS*A=omJvpMvDi*i#QOQoRiix#F~Ie)oeH^ zbxhh*RgR1o(mEKjDFb5VTCw6l(-Y*Wo8Onn08kI#Q<_UqcNm zV)gmF@`u__w)XE~8=TEEPCn;25Z(9Ae&@_S=TOb)htio`KIiRR4h3hZYnJ5gBB6}c zd{UZpOeJZSeMdH8WutR~h5MG?WA|UHSt^(4yv%iLv|i^s_g6ExfFm5;l1Y0bM-2|x zVSK+dzj`wa7llnJA2#T943``C&eSq=Qe;Oe!`UL{%|B+dkf8-sgq%4MQ1yrUb2Yf^ zj#-gbpBvp`E?@__pdi8ghNs$?_9l_heCp!FeoqvBTbVm#P$LKg;s_-M=N= zWv9KO^{eJ(zpB>JPq_apUcSz|pV{w8*W=d5v9y;tTv+CrUeL6q6r0uu$T!TfuPi&d zo;6)4M)V-17Ktz6Sp{|s{Ah8Pz~yiw-B`}#RqO#+qc9juI5_gW{LCWYcWM6A@Qp)o zAnd+!6CEsDEZIjvZI>gqcFLN3rJKf`v4bTpY#@PUJZ$*3XD zlh5dY1ZkDx=l>CT7kWjC$+!*fFoa^v&gWcW?9LX6Bx#tj7*VXEREZZNe*IJ9mz4)% zLX$K%`eM)Wnssptd5CByP@Q<}vPv3rm=cM!iVa?NjxN{F$h*rn?j|pGj+pshtaQqg zEzQsPtehIUkavwu-mP`Y^N^jV2?N!D`3=wrc94ZmIkEY^G@f)ctpPc00YzwiEEUXO zCvw51gt2ty^s*B!Q;wB+r&*i8=2-ZzDc91wRKv3CW0?vyo(Ed6tjIfWJq&ATFdN+(KL>!Fq)y&DKaE$>LsW^8HtAc_Ov1#W}S+?S2qn2uwd5`g=O)W zqX-N^^>rKgoWd&b8x__P_Zu@@Kcbw0g}_COoI#+A0b{46aA87!p~<7!=;w2B&eo~o zEMkAob{WGJWPAb0jUmMmAy_HjNLI5jVH^)evv4UQMOo0q5*EW%a}xl59R~^baXC4( z;wuvFlQ-&yE3@IDxe1;RD(>rYvd;y2N(7$4W=jsMPz1x(T+T=#16KQQE#Zi7u(Prn z7DzIMIrWHFbTXoW9bRNR_#&c#yveAz@6X8smsf+A3u2z#e1RR(DFKMkEP!0q(O>dW@`~CBxO) z6lfN#;0UvkxPU|+Nv)%J_qRNT1dAD^s61tL7@gX@A_q&$BTlW3I;x!vqDs!!tMmD4 zITcotUtfw9c_tF%R78GbYw)izb^$9?#|d!p1}Aa$;g*^80IFuPrMz@feE{Bf^dII% z_X8#DrPA*%&BLoQeAa?>5Qeb+c<_dZ9(#z6vltPXIg|>Y)e9LO1HUd8(!#H^AO{uF zGJ-3QFv2GWJ+2oHQiUd3LTD#YA7+4UVl+W~&`y8O^ZgL}tyN9~Ch4&OJ@R#y7;?iE zv#A=2sEj9W7{KEjc)=7dqJe;I6O>b&C7vc0n=(=typE|*d$oLiTspM@0-YdK2< zaSwqYJxdgT0WK@+2m4n?P6;$7q^O9*@{259I|S-aV6=J&G%6+amiITY32`CaUx(Lb zEM$C#*XpDce4$@|#}|4_QE1J`hS3NlF5HTT`{fq+0P2QlFlolwSZLd1p~fS%aXsRL zfx6LjIap|$N!iq7w0WWGLVQ-Cnney?@mDXhFNP@8V%JTl2=}Z zhz6>+v4Z0;8~9*bD2)GW|D|S&AT$i}kW*(Y6HX8?kItJ`H$1AfG{gn9+<7(}8HME0F(jJ$Oir(+*#iDS@AsEh0&Gs16a@a;?>Pc_Z}ay~=H@U-n%f z`JcsdXH8AA_5LjfNSTFMn1uz#VSz77m_}1k$Jv)qsem^2zx&E9&4&I=N~AECk-A3~+9RT)LhuzFXF)Oy#rZY5ziE1jn(G@+i%HD-%wUG>^`oR0nd4YOzc?L4AJ9XfcjJ<}f=%(>MfJr9{fM z`eN!@Z4DLEw)%3palztp1(49bgZG!xZ9B&L6{pm|mtEQnJ&olsM~liy!H7oZ=JGJ?TK+(0s58b=|IxqlYarEcdV+eJ&l)ZqhiOW7fbjr#EaP?Uvo z5y?~4VyRJqF1iTlqAO?^%4-L&I>`G$_`k&8+$K*9KE z=0NNxV|d8|D-6J73~rX7ha&Pscd2~G!1W;ZtB?kH2*K#2%Nt(GmGTI|Yy`&efrfrl z2*YfofClRnLJ`}EZ^;-Rmq9~>NO^;sIfbs#U82I2jE~Lx5Fm{oq#c5cI-jyY#w<`= z<~UH~*nc5qL9>wsqPxf$A1mVk(CCb%2Y~AlN}8%mu?4p%|9UtM*%~H5e%@?rW3phh zt0K&LF>+|D(BFQJO(Shi7>BvwssVHU7jYe*aeZ(N$9h*eoXwU{WJL-`qX}{+$*RNU z`-67nx{FWSiLVuzJIeFKW?L+Y520JkbkgJ`!hlF$9irdy_xl&v(MUkh^<{X>H+Ut{ z+)(0_U~tTa;$f?Ij!f}k+TXCv9e&Qqp4O)>M*=QxZB@+1B1dqQtm2;+b5YT*~NwwN*NF6!Z69y zgCf#D6_8|1#yH8@?E>J|$Ty@8pvUwRd`1x6z<#KqfklTyDuuucQkR0EJt=J1OTb2V zmPaEDkt*In<9!^E{&Zeznd>Rwm9D}3tXbiMd4AOWgnp0Tc&)>G)dSI9mf<~@j`A@m z$xrGNfBj`zn`@{y+KQ~`=8!Av7P{7M#V8_iA;ZdwH)BI*T@yf2*Y4o$Xu$zEI=DYP zYyn&Mh1@@zEQ(jppCu1m5zSo?zvc~*5oIRbDe+Msu<;VS6gB+nm!SWeXgNVe?h3AD z#Xz^Y5U5e057Xzy5YEK>XsP}#a25y_Ar5xhYXisQ74A{lNsi5n=fFC7c=JTyG9$-` z6U28^T{%CpMg@G?XicV{^9PF))eRA%>^O+6O!yZd!cc0Tq)4*z>#pyg-U>hk-YJ{@ZEKj&@Ghki>oi5N=0 zUumN|(J6g*hED!y)-0fOWl9Z{>@7z8?T+Zvo3*mZODF+acUDW{St3pI^O5_u{mU-Z zP`TN=T;RzFE5jvKvKE%+F}+L>smph9Ki5Hzl20O5#j5qiwL8QYnHd=Q;xYMcbs8gXE%j%0k84X^^45@ zw^-kkyJsALFUY@1oON}|A>|tm)qW^1M7qP5fLhDQYPy_FBgC9<;RIxt#?p979Hzza z_2QfK9){A)l@^H$&JPV8UhR$T*5nk%!0L$8#B<-ri!}fdmv~;C2)BgI+PC|-yF0M) zM)b!kRP)EQ&imC&BJ~lQSbR2)2uxd&((kSI*jPe9iymeslv--%ceKyn59!<}=~v6L zb6)8=rXl+`MK_n|Y_&g);KF)F2z;vHh@_f(f*V4`nz^?9AML%YvUOMBJlQ7<<|4Hv z-HTrF1iYVWf3vr@c05WtRR>L9dwp#f61#B5 zZ|y_}nhiFI@P5Y#qs)4FQw^L-*}h-xJf5H2y-g5EfO$08TpbAC3U>?e0!_`WA9n@| z&5#O?jwE5}FzQW5CVThYwhGB}Q`(L!%3Fp!FqRhqH4f4%hh+k~k{J*`oC?9Q&OA>@ zuzf3VeNil>5wSL>h;L&Ie}?4%bD!hI42+h>=*oeX#^xuxslMscHQn=T zRS&Z;ZtX{QZ4s}jU)xer!+~yihNG&7p;Kwx^=5$1VW_6AW}vk zrsCIcEG1Me3+05A>tw5A!MZBTH9bnn7BDMXS`+tlB`BN@-K>tZoSgjkG0TEKx_A-P zu<=S@+e+zujF&T*wCf}Ye(|l>-Eb^_%wX-?I*%sSOpwi+zvHak_567+j2TRP`>da zpvaP3`gkn65jfbyW59fnoAAEarBh?Mr#l<{6S2+X7FFXP`F?I3sE;iEAwAcA^7U=G zGC6qa6esPDj~&+e%|A=}9G<;~6XK3GCFe2!of{?KSoG8QqR5^bhBahD^05v6Rq|J9 zF6h=&l$4-c^ve^rPw=`7eo~a^j#QaMYp>#+-MjY@44xBi1`? zS{QB>P|6WFmczN11XAPdbQV_>*|6BmJV7G#}((N@G96iY;RxTX%_jheQ?ejwY ziyB!?Sau_yMzoCW-)VcH8_nJVqw1OdO?+A&tzD1b#jF;XpeF>hs` zF5PtD!u2eU$ms~VO2Wi^wuv)WtNHnE5<{Sujv$`BN}}OTtJ#X^yVFrK=I0iNxR~|} zEzWu>v{Z++>|U}pEY|K`vh>B=94r#nqvgC1sb=J8KtDE8JajSlO|4Yx0B}FtTMZkN(3MQ}txM1>2|2DnLj#LOuqzG^7(Ri~>y+-G{}i zinvmQ{uk6dC~T*C&@VLAoETyVb5Eg=&Xj+CAW>)QdEmn$tc+pnF?=OF-`s(X7F}lr z1PB>|Vg;9m4E~Fyh93PdRy8P=(7#xN|6-|uViEs~HJAeOGYApZEekktM=7PuAHqYz z@~K1CbB8T;%#fYNRLyB3{3BIxK6Cj{5qrn!05N{BGjO%GaPpEt*&?J>W_Z`RihIJC z5II6&z}(o{-qHcQ-QD!vy*+LuKJ1LVgiSzQW0}GK>Ry0anT~#Sy*rtVPAhumbRZdc z)d`9;e0Tz>Ei(&Q-iObfp`jF?zit}QiJ$Ti29TiY=n%1hjW2G?io(~qFm-HmhJT8y$ zOzLBou++62N?4m}M#N%?QHtU8iu$S)(k^NX{|-A-2u#oj=f3+|wX~&kqXw)Z|Rq92|i~3 zG7StZ?h;0k^PygnwWaY>2CS8Y!|dYfGK2l7biBst!WN2~Wiu2|AVU^7t(IIpwof$L zCN^oILC1z&F-mT6 z(Q+vF@YYI#?5yIf-f%j938a#0pVk}74+0G!ua|#bT^m*89GU1`Y1rS%2u~Xid!88d zvpXZh)@#UHS{mP7fSy=W4n6Rx*bxpY0K4HKk!^vXN!qcw+@WB&!F2DSHTNd`0mZSp zLZ8aGN>yeN+5>VPUEkii(+xrwfSlj)Jk_ZDda=LZd*?Fwid8xQ`EW7xOs0fDgM-AA z0qHXJsQjDxaYDl7yxF-VNCrr2mOfUb6!H7NU&3%bS@0h9AY@$cyK4zRNxDo7Q}`0F zWjZMXdT<~OcXMKhDxgp%Ve5uGmPdj>J)Jo;%P)3*wy(e+dLTtF-i6^Onfvi4zC3i( z7#QtG)zDOWiKcRF5d_}VUtY?F96*aho37v|30djfF;HHvQMhPGf?Z9>%E}|Hjn~|P zT9>RatU;IT_uEA*9M@OynOF)ga)_eASUE0w9*W0j+1*!+U0*9)(V9gy!?dNMRxjAU z3AqI)2OJ#t!Z>+NqKS;)_yN0je#JbO&xF6#?{_HgXYQhklV?m~+qrN6{A)9~=O*l+ z&xh?`Im?-KSS1d$jHx0#ZVD!txzo={c_eoUVov0Kwc(qD)zI&w+?I|$Ouq96F_?VU zW9~!eqA}jqwCb$rU>}a%`SF&koG1-?mQ5C8yHsfbZF%cSi>bps$~zS40d0LwcuuY7 zq2g0EE^BIw8V(1vYni_RcHc9^Q_JC*N_0GF-0M4h)_1HMju925)DbVTcdWOiM~&Mc zM%Q7JE$f<$z>LjWjAx&XeMa2Hl`pL1Ez(m?P%9wa!rCN=+}_Ck(aFS-;5j5xjbNOw zsY)a&*|BHMT$^s>+>hedD#i_!m?PGGg4>Q^L6VACeNE*<>KveyZmqq3`H+@0a-AAK zpvBX-Dqfor(jg4Md&!^7jF#n&5A<%JYy255NY)U$XS#amh3UPf+*i(iqj}{%aFYMX zN!Av71I-}kB)V3RoD_OXegviWDwtZ!MsAsY9()-KK#_DDS#?j#b_Ewucv_R0N_*U% z8=a*6x7rMVxF*ko0Lb`Pjo>Ckbo6;i`**VTToe1}zpuVpn*~~5wZ5cn9hs=Qy{SE- zv<0$ZYGFsaq9vQuXbJ7Ruh0?S5Hr&M6CK9uW2IJ|UR3`&6Z$Q|qc=++gS)2lLl4Y< zd^Us)*S}D$;X3|z2FUvM2nZX#TTWaOGXj&i>+(S~OOBrUCq_CuVPJ?2nyfPzYcy%5 zq33nJz==-gT{|p#SRr)!cOUfGUA4W| zmK@>lN_lF9$6J%;a4oTGnv>@GO6iOp``4+B@3_Z~Lras_#BPj4ryBF;dBkjumOQ(! zNUZWr+f3PKfYw#&tf<~`W_q@G6a9-i+{{e`la$04=ow6pv8(Eu(Gl8z2W178h~>*l z?J_-XT$dd{X|McIxd)%DlUDDHO1mjP>%y2fab|l(4@?km<`kI^ywi zqLDi9em-H1f_1w>xUpV44oB^F9tF^YmRftFl{#s?vFj*%Qei5i4(+e58)qrAmmc-t zcWHM`W`hML=iEBz7wa+o4>aj-vLM!peje1WGlfc5dRFj13d)?c@;i*1wjC7MYosQ) z176Sdb^koZas3Yjq0?sECMx!|rBJmQG854`u1*8O(p-pJ215>3bg?AwcE?XvsR0#GwArZOB+tyX*Y(QHhEUOG}PNzS7{qgTpiI@A3R5;vt@9La+j=B z4_(u?u-n#eG;5`?uK;T_(rJ6@KtmY13CF_QcCT8yqdTt+k#ySFS4+LX1;;?9y}po| zAaK|=)>V-5lk0uEcZqiF5+vDpdLC99u*t`bqw0V3tX#@eJ<#2+s})P1wt)`){d&_d zHs~Z>Xq~pr{M9t*w(DDOS#&q40`(v2K_aZp`9BjDM!AxKIZVGJ1$Ks#Fg2~wV}0fS zo}O{T7j2WfZ!?KD#5w1vD|aC2{Q{C!Cog*-o%XEZ0rC@Z4xM{1Z%;|e=pQC}#$#ki zR3Q<9PaT7WT!)CD{`%uTiOkiL$|^YCI#_tZAsiOo{BHg`T5f=?CoG(^9ar5DcJ^wl z5)`pA7K79u$3TPK<~KTu_}JKW zQaS>|H^H%6sFXgL@f@~0NSXI75?d^9CR~>=qh~vqSV}ThaK%_%GHr13*bXvGaN^iG zvTxufu@7W4{7jOvHMn8&XAZn+-r`a|H!d{LZfQGUfOBvzq)w)g$6ZPO29mGW%wmy-jb zLVHiB6q`rMh&xb2yGVbNY{-SsXr^ZZp(3@H+^JL{HFObsNl6G^9E(cD4CH{T5FZ?m z`IZP;BZQ`vKw49SB+q8xt=s}nJ!VKWVL-)ul)1)LqkX-kAa{cQqrtlJE|iHihsjCh zN@&`q3{H`AG_MOH+F4hb*Y8Di9(O7-)>N|pE#$* z4dQ-}>kzduE)op%_h@gWZBMHzJ19A0FbTI;xRW{vCm=owV=_2vS(^XpGQQ|z-|k{R z-`GIv+L5q3$^qKjewTg!^PYvJrACd(INpWrCh^o0aG8~Ye*LY;#@DkJN)8KVr zYfTR}Q~Q_8dzxq9EH?`D-2PEU4z zgT{MRh&&FZ|D#5}P@@X7&<284JtFSbon{43@KG$K4u?(fAveE}@<47;>3G1{NgkF8 z16R1Pgdh0Nh(c3_f*zmj{8t{fxlqMFDB2-o1!%B=Pw&V=Qx5FQk@_YIyXgcl=^?E( zY+>W;ujBcHTwD~KT+``N(a!hkPOMQsFC=T`44$Yqlbl&OrjkKsc?YuV@ksoCb9&A# zzLImIyP8x$rxUoYCzlV?=s+{Kwegv7KU740N@t1Z{rbbkyW(~1IUyBEzl=+y6w8!L<_?*^$F-UFa2~`U%J0(zjr%$ zGatq0%1XDGNX=H6;ld$%Ouvt?JI&*8agTH zZw}T3j@{2m;Ahz3A?RVG>ab!Y3Xc((-~Z45>A#}9N20oC0&Yw&{PY~;d9DN>h3GSS z*K__Sf5B1WfNWZkZn*u6Eq2!RHeL1^BBdz{LU#N5d1mbF;O1o{^@M-q>dk3ID zXgJ8AKc~04NWoa5BBDz%+4>o!hZNP7!wf#m*#*y9>pD%`()BbZGvIYh8*?=sHej?; zGc2afm!T2fb~Kwxq<*M4nyE@J&ELoReP7 z+7}t^pxu-f@~Y{GTSdY5bVzoUX=(1dM7DUXyC6A0-0RKSvr z=!_|hUSSgTJFLUBEyi>`$8dAFZz4m|3+1b-@KI+fhpFOTZV}ZYl~2cIG{;nDwU+kA z+Q$3y)An%lG9FK+_w$_|)ZMHGAvv`hA;eYN!r-Wb+sve043WNT~j6 zR&7fLxrN>IOAieFrR+Hl;wsFr!4za2VP+eHyI>md%HICs=J{d&iFqIqLB&X0NQZ>x z_9n4pOb(b7y9y-9sLT%j*axM``s_fJQ(rk37B$ z(LxrCs?%t07B*+T}1Va7r?fUG&Av%C$ z?*~2eTM|K51DeQdPK^eVS8Hlps``iO05yHuZ3W>1!k53xMj3r6$N*fw*4qztQpvA` zXEW&p7^L}uS{YXKUQc)1&piuXnMGKRRa@tTBc(q>(%4O*tQR{)#x>7cG5k=YD?{RI zIMS-mwedf93fYAaAOG^6i#o%Dn_NIZLe(wbgGcWC#PVYmlPL2N99;Pv4^>yiGmOtW zxeWzbmoRZqb{!sB)&c0#C-9T{l3C?z3l25d9f=G3;}(?l_zJ734PN{=D|Q*LEpN^A znNer3O%Fj~M>=gbRoM1pT@IJA6tZEP_qPBK=6Q_LNtHv=H}}TUQ`rmK1dFMSjZxW2 z{-e#JW#_d#9ej3ly%d5RrgX>Svdo%q?uFUDXOG*=p`+>^m>IxQ>1j}>iN%f`cciet z2w08sIV2?0@Oo2LZlGZUwlmwp!2)5k=&uXI6nT!}Zjp{PO|Qnx#j(7pFtho?DxdZ4 zX81P}_<@iQ=M5scZ+bIJ14Ex5lc#a|X{+l5mUv7Au~wwjzMV_~!RgEq^&~J9d#Qt z2I@52?tke9)&EI17_EQ`k zng6`oAu&oZEx~FYXT0NQQx7{MjJ62HJFsf35>Zkd{lr95T_Od+>zjl2bn|p}ka{wL zlFo1s?^u5*&xx&tR0m$JE7e;hc8K2SZ9ZJLe`;I|dN35xI#ayYG}NY@F3J%L{}@)} zE)>tz^(xJSt4O5g5kRm2F%r1+uYUlBcYy};-amk{m>0}nXM)u8I!04$I7rvFc@FN+ z9=TqWJeFa_CKF{|_r0q;dEr$HyhYXTd5LX}~0>GE`5Jx9? zP#(bjQ5D||Yi)>zV9OxdlcswBhogetqcr5Q3bYm+`qmCBW-kCoK_xLZP(kN4s?JaBwMr?}8`aVz{F(&%UcC944^=jK^8BF|b4?{LYt=##z7nPA=z7cDy+$g4b> zADGopPaeS3rU1}s5XC{}H5#2>%}$OP`5#jc`USsNxP%>?4MNh1^CRnDaGJ*n1PeGk zQ>DmvFpmw}1=33wvd}Ms!XLgZ%!wk9J7R zz>gV5?nj0JInp#^G4?+#V zs{_CYq_}JU@VXRWbLz&m`$SEtziQJmF|sJ}IcXKu9eo1G4ew=p$nGz1$Zh@A-ekc0 z|BA^gIi+SHiQ{InWKSX}5W;!IHk*GhY{W6)x-O+%sxDGV?8+9Yn(8eWU<_5b6ipI& zb2p|W2JWyOT6)h;m%JqobPMC8B!6+7U!`A%b<_ugl8AvI8JBDp{pfhr(F=$Ds%-OIi?+mSAqEVC@ z$)V=JmQrA(w5wi;5$g(AOOOoRItPL8x=tYQJ-ZA9zSkNwfJ`qoEwn&#ZA(2!cQ@v` zC;8-{A9SPNt5rgP?a9t7vZ}XiJLP_F=#0HUcww!&KirG3#^89>AqYZT5xK) zLjAQ>_}dqj(H^!~Z`T)kwa!-01RC9S9to@;)*ZqKNeu_t8ziIX>?KM)Fyq||v7Krl zr_EB3lg&KHi5)Npd8O6;^BU*G%k)!G1WSKQr12gH8Tm{yND(q?HnO27m+Yskp$=t< zBJjk_vCv;>4z};#ulJk3FBC~H#Gm_nrK2U1H~op+TH~D^Y7Z?+>eJ`e!@fjPl?fhe z13!WDenV1?dZ@DQa%)Wm5axIIZ$P;Ll+_OM6ChQQwo;e*(F1u?ct;~^YLl0KtLbFD z>?_Zk?J;MOLLLs%yB8e6f|N4KjLGfX@68~%pJ|H-GsE`u-txJWr4YYcm?PSt)@cpA zdC5yKvU$`3Co)=VL&U*&y*1@GbC)EB?#Q6+H)*a#`KuiUzEN;EO;ZFSORFnjXMD!` zVh#i@{oS(7xJye^QIy``-#4evW9?iG8_EtUNOM zEvT>C$=p#j4<->-(4$a}S6HJ^WgqFO9C*8)?bjBJQTooG-79}nzC?=+z7O+s2L56G za8>t!n7YLHPOj}%lbkUG2AF*A>;NvAM&05uWlmuH4vb7U2m0fDzwt6)yxYCGyy@@f zo?v6%bWyjKBW&DlHN?x;iYJyhFgkamDq~YLxO@&U{Q~WimqEBugmDb4Uest9OtQvF? zR7Z1=s0CS3gJg9JRPO&2@k|ajm6Vm+h)lj}*7E#}Zg zu)^5XsPy&!uI2&$Q_kb!B2FnYSHvl?$8xt|0rMv17qv0{^mt}GFvAk~Y;Fpw=`jV> z^uSo4Bfm(+=e?&qYmoW9=l2b4Wb=Z!_#X|J|GYY~x~JdAu7k+JUM5p^R1!D{f-Nd< zGmTLcF_NuesY1K9{Zc%GrT9ipy9)UwNb&FlN$UYbNLFxKuOumNS~ln;n!lw|kYPjd zbq+>heTj9BMlEZ}5irm~YP@(zR5-?QZ{0pv-pbiT!+$Fle1i}1Xkw~oq_6L`LG^MY zX!^+8x(kq%z*eUO41##@!j=wc>saY@Tm)%+3dM*<#_mo5k1A`Uwx*6xf^{yGHrTP2 z>lQ$he(+HGOAmuSt@DHHQ)rYnqKqIF7AnWn+N#gK^f>)(>fDq2%TB|{O@;IR>Fdms znbZ6Gs~H2AGcV4;0rmm)$Lm|)K%Uq8rQy4q7uwpW@x_74)affPA=ul*L5cmNyQ`Pi zLs#fH?;FIE3E>AP@5kM$_l5Pl3E zAYak`{`_)TfP$St2)s?aNJzZj-7ItjUbMek@V+0|xjyK6zTUscT%6yAZ8CVI@b*`i zf0(emzFy8O4Cwf-JjFj(SjV<(RRG#FggZA69Xe`Pr%@XlTBE?n!p`YQL9!9v5MWJz zk$=?S90edJ@@h1{oY3#LY|L378ML~*?}&ehJw0DIf5c!vMBU8YWuPeE-VTg$J?#`6 zGCaAx%rPolupOl5Lq$a~-MM|$c&7(mZ>{c3HhIReMmRPbz&`c{tUG?bH+g*A_$8#t z5R6FCjnc2vU!3vop=1C}F3!&Hz)S(>EcKML_Bvbw&_i^ai=2BqB|J+CT zPW`x&gUn$G4T6AY!+8B>-+b_shp9-;fUq;&*%Is|*Y72vPaE#wfBL7jc!Pyq&t=jYIv!?I8r5p3@XJ(RP&aPaB3|M(zAa=_z`*DzQ2~Ar10Hlnu3_SsVM8X5vx$eNoP$IEaTQ* zoc9XW(cy{OKk2xzO44?r9S-^$z5DS2tI?u*7Gv4c#PrXrn**y(tGo2GRMwehU19xh|PcBKjVChNIQXudzPyCbC3I zT_3xz8|D3%q5PKrLIVP^&g(KJyoo6 zC7KxM=2#kYvE8&HrbT?G&f{QOaNCmGtYf+;IIYb;5KHTx z0$jIGX~?RQ^4kFSW2<7g0@-@q8ueSe;eGJ=*L<@Yuw8+L1Q2f)9cTihuhi^}Y#R%` zz-kNEKkg zOubT5!$F;0oSrrFeYR1rJRqZ76Qu~}Z-QC8%F!vt!?g2IiQ>C|b7L>?0 zRq7@w7>lxqFJWaZD$tlYsB>XGtU{V~K`~a0`WVIM0)@(f4vR44&To3=;i8fkoXhfM zoxSjrZWd51LaSXYlSSD%(=?Lx*DsbXrdEyQ{-Me2ZY>LEND$~tpso2@x*jgn+F z)FCz*kQ zX|kz~%Jd)9aK<&p38FT>iLx*33&gg^&!RGqb6Y@;bvdX=56uP2{!)psf-3LgA4tg; zkgz?m4(kT{TA4M0_hE-j6iFyP68lJbwj2m0?%( z9e;JS)&Zkr>}t*X-j9}2!*0xcT8R176>d;IsYAhyqrRwcl4qr3lynLK4@s5E5(+S- zzX0AA>$t+EYTFIEmSasH=#~)%pkHzQFeJQh_6=NEXkO*BFA7Kf6)V=yzWeM2s+Xc# zjHxmcRGp$@FLY>Wu6Z2YHcNFNkQqji;;iY1V)OV?E~2zNtcMVXYFZ>@Eyl^2V>BPt z%aMaP)2p_p&|f+4?tEk!~Q~G->4wg)#-^c@zbkl^^B^h&sJ8 zTh~1Giq_VHwptdQ`1>S;29Vxs0C?Ir%i2}wtGMYR{$*Povr zv*O%N^1gv1ZsC-kKl3RYHaOrh&`;t?^!`S36JuQWXKMIX+T^B(xevJc^eD8P+Dp%T z>+)yk4OfPXr51Q`F!>}LQq&N|v!?xeebRRqRPjb6eJ>}%67A1|T#NPNK1pRa^}Z~3 zZ1D$Ed;sv7!*+VG{U`_0{bxz(#{vvFMFLd1jqe=r?#P86DDqY%rwK0F^XqOxY7}I39Ip?%WLtCzE|19d#q&Y%(&anz zua_k~{3nQ!oZ{K;rNXZ|edb+x?(c^&kjdk)(u=)k4Q^`vs%P=`=IQx74YDX^;5FVs ziHP~h05$6o+_9vd=bzjaw-pNJLrFLy2F@9YI4R%<^%}4-1{poKf?}|Y!%?hvy5=n> z&r@9y-m;0OH|vi6Ky6_qmvyabCL)(j{PAReG(Xwd_9v@t-0~DRd$O}uPnOsow4vJ0 zEze&@n&eX(KAu~}2?9Y4L2h|-C90>>L%hx(SjfesnmtR?zHR38mG5bCW&4;^mJ4Wn z%HH?~mza6NDJ|N)^KJx=5-lrcupa4)YmI7M+)P!=e!mY*$*mtm$CbnA4o=y-T}&x? zV$v!T$&EL|f$WG+@ziAJ#{{g{f-B;C-QE7odh>5zhFxV@i76H}`NMgn_+h{*tc% zzMMmg7fmO;y;y51YDT4s|H%`4ZUd456ZD@z3jYNVq_|oHL5l847Z9Tm{uf434q_DH zMh7)x;(!~CwU=eV7m5yIlMN98R;S42!rSC4e%0B7BhR0+M9q)?umd~AEV8vEf-_JW zERthnqhmoZ0-f!N35ekef)NPSPfS3YC6F&j-UN0n1TTW_Qtgw=z4(9lfrokr|KbO( zV@>`iKM;5#2y$tgOTShl&KN9UO0Oz7D0UlIu4`Fue^1b%+9~M84f*!tF$Q^P5!#Qi zc~ET%e|GV{#@F4G?MAUf(63tWwe>2Cmk=bi7EBsh0F$6#l3z8L)TaBCv|gG6&+jG) zf)7AH!uCE`!0AG_3XcDlRSzzWNr?Df$`=cHqA>mnTG(H$~saA|vfyc4NDE1SmLZE<`l zzg=%z=ba(!LK@1dd=KsGCLy)Vj7%D?q5lk8KEaG)1^9k_5t#fV)+gFZZ z;vapGH%1AL2JByneCng`O8XoiTy{L#gRl}ZQ)N=1XN>kRwb(>^gi+R^^xpZ~YN;Ox z=KhUt&&>U29!G{>V4eyax$`DTe-{W9(y58N@1rvX%qWe;Ws)BSS%v*9+`^*q*<0p^ zMooQxazj>)u1L*+|0N3&wIYfFH25_8aDJXRhlO3Q5*p5aIl4Jslw;D%8`R`a5->q4 zc^3CxFtmdw!oO{B(9e~+OgVX&y^(P{!GQ;sCfSpe=6LkqBthC>38%qHzTsl0H}5nl z$28b@SZ_}VZg*~^r-yd90i55#cxu>q7GW02MnBW0_*C8`rA>!5>-qZ}c4r|qvg=1$ zZHC4ziKYKfe4+P_;R#<5V97H>dW>Q{h8|j#yh_F85g{&{&!qJ_GpyPee7R}>s~e_k z1JWujp|6@ox@~p5^2jhR_FuO6=AT<5=wTR70irf&l?o{pSaV1<-`Wb_RpSwMt6Y2F z<{;(hKI4PryyG0G6F5|mob9g1-%$G6)VjeIJHWpWerGKx6co1w*^GU0W|yQDbi-M& zb(N)ETho|Bg?+_8Z|4c)^A3{{h0dm4%yh~}*Z&0xla_+Zr<%2k!%+j;imf*vH|)kU zfLJ4So!yFgpys0e2N`N2r)pDuzQA$@Y{Ri4m95-{cR3?+-MJFg#X-QH)B28;>O%%w zd7c+NapwWeNNk`AeCRf>R;4=?fTzKEx@!*%vIV4>HcjOhK$ZwQsR8UJ&i znA@y123ENFHrc`EJjb4Tw=KnyBxO*Jrskr-j$w5uK{3H5P~4xpmE^tr8zBn&8IANJ z81H-}S}Mr)ps}B+Iwf4)4{0N{1AhAxzc}%4O6Wsm7s2QIv<4uqekInAUoFpj_;&R^ zzw8aT1DW5`B0w7-czH#!pN;5sl=LEwBo9zx^LzBb@b3>8TsLA-|B>kq&Cv6atn5gt0n7Cb$^Dy6e9aBq!G9FX}`}wAfxDQ z`x2XD#6?3{11$9=z5R^ZgYb{ni+`caKauq-eXHv%Bau^UPtKH@Zhy^Kzxv6*hv*}2 zu3Sov#ncK!E-VL+4vSLb3mC2I${U&8S~TW;cN0lApAubcg?u$KIP<9+eq3{V_S^W* zI^`kf(~U{x7wn&y=%bPkSE-6(WLIr6bK_aqVO(*#zash0{p|k2)F~q#rh>;a9k<6B zZ>LGze&D*f;g6=`U^Fs@RB7*>ZQ$(G=EUVb@mT;;PQiG{c4`JQa(ExDLrK?rK4X$z zLgPubT#Dt);=0R}&tdmwtCIa)*a&VNTKC(HH=dTb4N4p^0ynt5o8aVo zQEX07NlG>qc~t>r`9o4`svj|#BWpGGOKrV=RrK0;gw`+d$&|iz4|%53l@EEFwL8Iv zRCd6_*Fh1)Jg?+O2(t=Xqm)!;c?NUeq}!Q>fh#RT+$97pgEqS{CH6%X7#me<8Arcw{+VhZ+QkkW0jr14dzWX zol|;S6C4}L^mRVlrBmX)F4%E|*Y~E#t*6So$7~}ix~K3f%i4%ECqD1l4#yfKJG#jM z-XELBY_^3Qrqj*szurf;Hi{FwBJD)d+}kPd06N5GMI6yPd_>8p{i3(FM9INQ>->Mk z&O~J;XhO|zWqH;yoKc3mNq27@$5M6k!IqNGh}p$=N)DD0m7~xpum{zN6AZ7d7lIs9 zac@c`sno2IjSqT%iJ^sOJC8y{Y3yKXZ!lsP>8|Ig1L^~XT58tAQml(w9e_H@MG!ir zf4c}ef-@3UlEYYtZ)12mJ8$@+Wrw#mBdW#@mC4&Y zQ%xl!p@~nPl&+2YNlBS!){Fn5S5N)7+SwIjw0z4wCQh{cu(ohsWR5`6wpYB=GlugV zl>xNpTll2g*AgQ^{InD`Kx>CJS=N_qsK%okZbvNT|5deQElRgZksHR`JC1=~GDR+k z@UhzA?>5q_?c~wFdYFkCmH33F#ie>W{Dt>HwtQU^?MmPCCkgQ7p#x4%x-4~>+&q}_ z&^;$7@h+^v!pr6urDz*DF~aX%6wloNu`(XXSk~tLq>o1U%$Z`}1Enm#<`*N8E0R&a zSpURu*8fRtn2v;7V+T!>lv8T4vn>o1jbQXB{~xn#Zk^f%Gon>OqhNEQ^%zdHzHfOTF#;VXq1TQ1qfO7 ztuo-#WaG4U6^<@i0d5qxk{%a$~Uz6v4rh+Nd`SRsK#>sWn( z%%IXq5HFrdN3~O0%oqm~M6t$!=PnRB&-HRmC2y~%PT{S;br(5+)0-Rq?}0v@QorDn za2!x263u82eYcTpy2!VA;cqd`l45X9kQ*g^)5PN)XGpW%e0d@25gQf9 zaJvyDI?yR9(WV2|;qmPIxZQbm0#{WDNhOg?e7PZ zs4v$^+rH6!{XqUtF%`lXWnP?7QH*6Klyy>mM%>X%4B6#HQNaK%I(Iw7f6oXgMRTlU zba6BC_K%W*by;Am?O-#CNfC?@SsrrWj>7riSS?EkBC34R;Qyx(+>CGF4G-AUNR<_? z(8cYfLX!?(ss+h=4?Y81jEX$bzw@fu(7?yq&ICv6l;HQ|e{l=KlI!C3-AUv43FcC% zF96^Osz{YH-gQ#AF1oL@Wak*Ba#P%W=vl#YgLFqZ1Cm|PJYq6{u*Ha~?BH>8xBIZ_%d(7i&0!7;(DPcuPq?Tm3V zgPCbZz;$|sApde-t1sjgH~>fo1AGYJ!bMd;_^nFVg$cez>`z5~W#^U=+q!eFM3ag$$0cZ}pDWVgWsghXWra!MhXz{kMEjy>5`z7Zaf@sP5^m;y_tQ`}HW=fg zB!=0tMWMZR`s@eiSIuh9F9v!tAt*R#GP=`aSMWeI4kjfIWPBT*x+|vab0L~DkBjI+ z`PBFrd^Aq@3$SO%pW1|RJH8%16bF+GM+>*uP?n7fSF7roOrXV(Z%wpyCN&~B7aP@~ zNzNbw=rL2-WRPuV`^xC(;)8N8@(6g;jWkp&3mW(aIAFbVxM&;$EF6e4D6Znf34pIW z)B7HYM1g0Ds5HSu9$KVPfZbAWa&elsgFus_+}Udo{6R&nJ;P8S2!ClJ&1N);OB9a=03r zG%RtZiJepAYMFvg)i9?EE7Q2Fn5F#nlu z7o6^CHi#rY_%lA?v@SXEHv$32hg$M&_(J^Q_{U>Y_0gaZXS1H0Nit0LX2&!gS2+VF zLXp}PAbtI3)}$2AZjDYf!ynIlrTr(!1a_Yv-S-mtG?1adOTG#V}6c zj>>+5u{;WTp}8Ut>vQ(k%{5&h6q(vbRblgSq-ZIkbUVdnNcr*H0tnxIkK8IrS$GV8 z2mcCkZ1sm7IsJM4b)Nape4lM(M?=-s(fT`XxZfTp1b6Pq8Q;)eS|P(n*(Yag6vZij zd_9RPsBspYdGY(aR<)sM(48lZ-jG?_hv^ed?J3{mYmhZ~;uu6{Fk--NK=|QITkbsG zzgexMVrmmUGN6j})hN)?=By^2ym>#2fYL)jf^$k*THnt+e0nOXoFweNgI$Xc<#thd zhG((IGud`dA4P1~M$8Ah(~V+TazK-dFp2DA7Gw~KZC_Q;lHI*BQT@=9qw$`M_u^mY z>^MH7glvPc4Pu{q+y{&q|LeuPJ!G;*1$LFKJ@A~}*K2$V;3}@I}WY)WQ$fsUgjOKA(o|@b7k>_)t$yoJoVj%W4O;*<*PIq7UiG? zGo4D}Z<1X){N?3er{?9n6GmVjr9WeIVfdcdP`NKHJhN)_2=Bn%<)74Zv8 z6>c&tHc#4i(ua!p49|k*FcSd+N|g>0s}ljCM;EVS~rF7BY96EmOS@R6jgCHM2_hsO^DYraQl5 z>UXJ$Yl`6K+)Y*q8<9osW_l35QN^>!+c(<@x=JnC11}q@=-FR>w4C*d&*z(ohaUiu*w;f`7d#UCRoKoEQNo=8q9wMC^uukFI)#I_KjVd0 zcA55CT9?vVvz5FlzbqS|D{F};RM5M5yQdf=PhH+j{SYASU8eE)+Y_d@f|*(3?&_EV znX~F%LcdoD#3>!F9{o5LAo5*14W%LEFtk=vthdfUgTS1cnZGsU%!rjby9XhV~ zfrzev$ggiVmE5eUsgT-mfXz#Bm!+3NXa4WbdDNTU0uo$-bAAuI()sGe4NvbgWViTk z-I!2(w++ELJc;U9mi$61amDZPTwdWx-Y5qXu3UduCWM9BbW1%&k9sIE!!(~i2XDX& zM{7^HGRcAjujU%}yqF=tJ}t(p!$(_iXMz>wFkw$$r#>Z_dr5LqBkd1;0nt(tc$4&V z6*NQe=zyj${~UdKdIkx+6S>G%vcV#9>z}k$^)>;Py1*9mVI2fIVvTa@H(GnmT=f&X zP000ox*SUWJm|kj^!(%Gz#4QkE`7p3huBn4UQfdNkkE8^v9k^=9G?AdiBzxW^B_+2 z#!@&~PaZfN?RIFGt+QID4cqt|^#rs0KX8ti%Ylu$@14KblkcGwY;2EVi5u%iM3lX# z2r0zDYWAN3KS}EvzgSVL?slYiX(fxqKHT8bF1FDo;y(F&GgtR2Ajuebu_gDJSeuBl zDDqY0v)sm6{n#?wBa~|BXQ5l;O3WYAH8JakX5WZXh?lK@oBRl%iC3ELUE}K^RsPKW zrs$L>%yT+)TH2xFCjX(-oMD>j@FhdM-Po@^11;lfc*QVSi#)QPFH3j#J{@9Jjz8bP z52j{`emhE=4QtCUEb(C6u$CM8`iVd3}6)Z3#hZ+s$~5% z=kd_=9Q*6OCKBLJJW~Dh_>s+H=+_zaj7IQNzf?FT*EI z22`0IX>ZPr58Lc7;D8YxM3qQ({*BGnt@>a*I%J6(KxSF$C=_1%;URz3R+HCrE8`(5 zjv|cb)bf+g;kotRM}YVIeDe@sbyl=X57vr_FEa5sWBeMU!2X%%Jj=#p=c}4NEoNx* z-b&rp3PXP>w;dN;S%Gkg;(--9&ySl$-Wz;&rhj7`0ibWG$+EHPoH!secH_k= zks|mcQ(JXmehC){ihAb5Y^LZz=9M^?zcG3yEIV4$EOxzq|LslK=Vp<*e zWoPWPXSBv!0Z>z1DWkMdRVxifZhclEjno=yfy%hh-3R$scMY`+JTWJyZm8u{9J1 zx%emwZ@ft7zzfz5N(l^Q{2=%slEIA8$2wy4W7e7fknW$yg8CKFuGk z29gX!bOGX`^!%%Aod8UoZ^=Q+cbTL??ph+Raam{P%24;-kga$`8r~hJjr1(3B8c1S zlWWCLe>YXE$mo6_a~^`X51)MSR?Z${$%JebBeG;BZJ^XBTq~wjK;xeAB<2I+$nG1? z1UfPcUV^@TizrgBr~_Lf5fN*p(FSMw6`!*fh9RJ?0DY1xbTNItKZ)J_=X*QP;+{>o zmhlPK4zz?XOw>Qi?F{^X)qO|DPgrFV7u{_{%1xy898BMXLPu(e>0Alp4A^4Gp{6xN zHD77nFsKwvWju&u$knf7Y!s*^@Az&i9?#Y`uJ5lON$+QSQ?M_Me(KAJtN^Vst#>yM zyQe^alOsRLUAZ?2hVU{lWV8)EHMV!~rb!!`bh;jGU)|Z+*_Rc7t+N%6x#b2IF^&PDIL&U8QkX` zT_r7&Dx9LkC2j2b=&_%YA+zzJh;gvy>OOAzK*Y~gA77OE5vj#$ z4e1flM$h&)TPg`g`y`LvgSw&cO*|GFw*$%#Ug;x zAA%@&PYFqGy@rH{#=_@xy1;}z0REq4xdIFd%v$r#IZhT+NTt5(z=KFS#v>{cpqm#% zCiG=Oz9uX$dsf!{M+zd~h*C^MfNA9ddBENy)Z((9eY^$M#B)=Kgow>$kbJgf+tvE3 ztyhsdSG8lxp?$_o#7qQxhlUj2N#ji;MT=DV5T}LEh+w~K7&m)?yGH?MuZ;fyNjYP5 delta 24756 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 T4ARK8Z>$>t{q``Saj@|}aA{W! diff --git a/data/projects/demos/Popsip-Electric Dancer.mmpz b/data/projects/demos/Popsip-Electric Dancer.mmpz index fc93dd64a23dc693793182e58b473cea3afdc069..1c935dbe1264073b6a6acf4ca61e7041ba64a9e8 100644 GIT binary patch delta 1397 zcmV-*1&aFn%mM7o0R#XAI<>I`4Pk#~VJp7XzwH`%+dtQl8%({yx#!M!=VVfF_O{kr zO|!30P3z4uLYsqKB8G_2e~MxoM*bW(Qw(O*r*+P%X;6V%4cHtAv^qvhsE6p`qG{*3lH3S)!erSp^WHnKSymt69TT7*g!)(f_ROsQT z)LY|GU9XN~FPIJ7MYswwy?_EA`)NV7RSQ~<)Ph-wU9_N~TDFaXui%q8G;5=TUP241 zs-`H8BPyO$gRfW(IxngQov(jV4QksPzAz_7SF0PW0hzD{RLUB#(7x9)Lv;3%Gel=! z~77oAY*S2>}K+Mt+R>lojf*3n*cl4xJ$Br%a) z@~4BJe11NS5Q;bDo3one^lnJ9UiYZi+Oyuqtq)b*v5ZEX3qrOznn} zSgPr0I>I6J1`K-CzrKr0ZM%=HnG)q<0T$`G9-MgL}!R^a#oj{TJVRY&u8h%Y1u|uGE~Pv-BL@;HGDNj;`lZYrOQ` zAmlYQ@Yn4&{yYYiSKw^<^XT#o|2)_LoX<1?Nqsf#&ERpSydHn0wjS_we}kdnj%wW0 zRl3s>a$xg|qEJWP6y4U2ei;9c|NZX$$@R(q9{-Q`m+!8B{d79`@%rQW;M324KR)`+UxA7<~`NMdWRdy53o(Abx ze*?cC>Nvi27ykU|`+xt%i)L=%{`+6EuVd)0?-^Sr>(76WY2SWtD$0g{Gx;8-)WV(r zmA7d*aOeIVSdxfS9&Kw`xDl+u<0M>uuPnd(b@TZqOklzkzM6ZtN#To>Q})gAAIb3z zY+8Ol_5(0&@ahz8`!Fm$APT zY9kkJ=|(Q>te5x4eDQtnEtbjCU!Sq@JG6Fu6LHn??G58Qo+8GZeLwgwH(0sR(?Hd} z8>p~h`gUjT2e4rAJ!-Mpp~YX>JZ{y--^|2rZE1fD&gE=64_C9{G+cmd&2`sE4*HvH z^H)8yQ`R$Y8m19^!S@50*j~hsWvb2ol)3nW53u7KoQKn_#AenXYOM`Q%j#?D?iznp z{eHmrBr$AC=8Hu<^uy6SUXK2!n*!{Ai|@n7|JPkC|C*+QGxUln`8t=>x3hxEEjfOU z|Gs6)C1BTe*X4Zn{kPK^SkJ7>de$A?`o`Duc*L;`4s38N<^TL2{w0Ej)@TvGqr{EO zV7_GOWfsTcw_oPVIN2cP^QDsA)pxdclE?WmXBLMIeHjLK(2r@~AFnI=;ots$tIOQq D8QB6Z delta 1412 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 diff --git a/data/projects/demos/Saber-FinalStep.mmpz b/data/projects/demos/Saber-FinalStep.mmpz index 5e3d1d1ffc6a26e339f864341fb0b0e2434d9b40..05a5022a7d47b5c546f0eb6aaefcb8596077081a 100644 GIT binary patch delta 5720 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 Y?>!R2_UyTvO>~k``too8A7bbrZp;IFp#T5? diff --git a/data/projects/demos/Settel-InnerRecreation.mmpz b/data/projects/demos/Settel-InnerRecreation.mmpz index aaa01e0bcfe9f6df594bd08144199a33a020ac2b..78e1d611de830cc14cb3e86ec455a61f09f00658 100644 GIT binary patch delta 30409 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 delta 30388 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 BQ#Swr diff --git a/data/projects/demos/Shovon-ProgressiveHousePluckDemo.mmpz b/data/projects/demos/Shovon-ProgressiveHousePluckDemo.mmpz index 2d31bd7bdc25008624f6eb0b345c4ab635ba05c1..3ec6a2cffde81abf1a6b130e1ea1b8b4c68966ce 100644 GIT binary patch delta 764 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

6-+Nfxx{V%e{K3PY-yh?{$I% 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 Px=ihN9taMpnC<=_t^GU6 diff --git a/data/projects/demos/Skiessi/Skiessi-RandomProjectNumber14253.mmpz b/data/projects/demos/Skiessi/Skiessi-RandomProjectNumber14253.mmpz index d3c6e0f8d0ed65b18121ef34bc63c9ee9943b67f..bc2810567b911f68adbc8518df9fedabaa556e44 100644 GIT binary patch delta 10958 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 diff --git a/data/projects/demos/Skiessi/Skiessi-TurningPoint.mmpz b/data/projects/demos/Skiessi/Skiessi-TurningPoint.mmpz index ee5be4b553e9f3f9ba5cbc36d314bae47ed2fec4..47a0a3672c696a68fdc1f8fed34f0db45548a535 100644 GIT binary patch delta 8601 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 delta 8608 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 BfbakS diff --git a/data/projects/demos/Socceroos-Progress.mmpz b/data/projects/demos/Socceroos-Progress.mmpz index 74ff5774c94e30fd98d03372ae2690386d3fa967..854663787c30cabf73e38ea3e24820a925eeaaeb 100644 GIT binary patch literal 18425 zcmbTeWmKF^*DlzNHSQAJ3BeQG8w--)?(XjH4#C}Bf;$BFKyY^n1oxmpr^)lYXT9^C zIkRTX52|-vTS~f%YwzkC05B3mZkZ?E)(INwaF$!q90{kWFO(BKesuhFZZjlW zXnL@c-59sAqE*9G9(XTSCi%m7V&Lf(`VPtu223HO{O!1Rw7*3ZDqIv(!bkvttor%n zl03~j;y1@j!f!M5qtO1dSB5MOny_}@g{fdWcBCc zt%Zf^4PB@3(I3p;_m{-tia7DCg^K+GBOb3xmW~fO5MAp(2#AV#)l15T(pF1);ME^( z|6B?-)Ylk$&`vZ7<)WrW)tCSHr-VVM>-c8xJyUb@1XD$%*c@ON@Z$f>aB25opHXD| zrbIqE!Z#Z2La>0CiLWhcD`VyNQt%mtRL&MfrwsZ_szv690f7S3@qyz{*AXY%+U@l6 z^-Y9}c+Q^Ik@bCFtt?7@0+sK$mqSYmGl?%t!+u1n$5E?aw-%em-G>Qh;u=Ty$0xHh zPPZ*RJ6?WwRwMhCSXxY~H7X-E8wYJre@~A#lhG=Y)P4+@;|now{w5QM(){umAJV36 z-@5L5nkZ_Vrph{-!dQmA^T2lxJ=LrdHo(w@bh$>pKCogv$3f>zT-^3i4Y=j%+ai<$ z{R!tK3`ebve4jAc+9#1-Lc5>I&wb!0Nk>Qn zHbeEUMLyvtID2-0pYA4@4=&eEpAPO*URqXzjTcdOMnvw=_+~Sa?x|!ldKLtRDfu+Y z^u6C3z6&n-jho_)g}Y*RrnJKT&tE{6E<-}Rbc}88oCO1PIeV>Z42Ud zt8oiR_YbcxZ}-O}M$B9&ip>q@X{$*Km@~FG)@LT_iDJ)pc}C)kP0~qcq)Ds`?y#&c zkPgdQZjMx$*E^ohZ^kZl#j0zo7%#ax%)<*_y6%Quex#6A;a(FaS*#q(p)}^`Jli8C zEQRj-4eAv^n>4ZZc~qt5y{$){C@~9isP3|lpt1hOP0ZPL%tXyE!)hPOt8hBMHrpC4 zrS&__jU=Bh7FKG2{3%WM5J5Q;JzUW;mY>+k-@?BIf;3(%lN<3lu=*D#fTe zzXvV9%AUzIdOeuecN7JB+4(h1N5)$brj&NjGImptH`YIO)>$Ufxn5xq6lO3eKkZu0 z876xzkp+Te0+gyEXVE7+A5)DEH;4f>Zsb-tJCmv6nHR0WNvn+4 z1)lfZkgB^8-o15uzMROo_4U2{Sxvdy(yo1+Etcky&@#2q^>lyOx8Xx_38czDs*a=- zKATg~B_D_yNyb?T!QjcBJ~@H&ex&VqXRF-R8VetSja|`+)elcjNiSp#o8`J#P4oP~z8ILHT=g z$I&gPRZAi&`AkIQn=hK?B5WQTODR>Cfggr{TQ`UlJ7We1$H#pTWfY1AcmynpZ0~Ui zjZbj$4h8^Kp3^FcXd{chK1Elah^+W@3b6}0R)4=QJUru_!`W4?-kTh(#yxi*{=B0b zYV|2uX#V<$%V*x}pke{_iarnF%eBT=t9N$TlaFFLw-?D-Y?~8F$MsQV#&lHOW^?Cu zpSOM&T9~0?^?eW!J5bRTXro0ak-+N=xmbqZuC`ClLX0Ib_uBjSf3C4{wZ7$V4y4O~K1;pgkJ{gO-Ee5gMf~-4S%O83Zx@dN2yVO*`L-bN zb?OkRT(%{miC?SM=?3C?o>ZYB+~WB_?AJ&0QG+~f|N z-ltcaXD;Ec);#W3ur4-OmDKi_e$l3>cuG3?Ffb)4MW<7aYi9l{LbCu|1jvU$s%#)msZ=DV?Qy zQ5_RnhtT`2mhX$_(AD>RhFb4WpYeaWaSUfktC%K?Yu~+F#%}(J5kVmN_1qB=IboK- zeEQhN?DKr*Gv4Y@hER*N&QPbvoXNE%6r7ca4x-w{bPanFERY_z`&)VO{7o$A7Ll z(YVa0Ao}0ZuKIGCFI@megoo2-m#>#koNf0G5zBTw2u*=xH0AOZbQvOLZGu!87m_%ye#Y_`*cGKahjC#$)}_ao%}vpi_LNf)gToYmDB{ z>gSZuZVOFD0FaN21)>|XA^XA8xCj6+v{p7lBly|w@`Ml0@C6@n{n%AKioOK-0q47^ zP-@Y1+$Z|O|^v~}izKFS?#W)J{VKtb;Itu&9 zVL<##UQQ{WWidV;lX<=K&-v*|b=QwG8@(RK%-HQyj)?d%=fu;pS)xMUadgb_uWJ)r z;qWqoc|I||IcWsL8^`$tTh#hq?T(&w^-n&S;euBd2}fgBWu$d$#n0$#hjk4|`LIbUgB(x1IXkY0E|>{60ZZJ^sRf4sHlrt}J$-b06COQ!7bD zGnEx)$xdLjpr4Q`B1V^_(lh+3YQBu@h_5 zC3wwoMprfxWw7$}+d*~7cR0h(x2spsmUXwx8;_4a8I39{FvH(*>dvT|>)02rsa{4D zoOq2DG*_UMSnUl9&TyLTWm(R@VLbzCa+s`(G+B+dhgvPAx}&W%yuT#LH8(W%KVkTm z`6cW6oRN_Ch+LDyWgcR6ToG!$yr_=0dX>;n--$0GK3@9XiKNrmaG%d;WN^}bC^;(c zvPPOvWY0gthax08plFJoVs$VGZMWU)_UGIRCuK&~{m$SGZ|xqdLlLiS17lWChP?X6 z-=%ULJ|+5a4%VXS?{;*Kq(bbrqe#@sR^*HgkLlhc5E?G{3N5{9JNY;`C=mjnB{ala zl~}YJXNaoxl&7+)_^1F9S$ZRo!EC%es)d}>nS!)EDq{G{uOl%g?jg0uiZ334*Fj20 zK$+&KdY)c+@>?IOmGg3Ky_(Q`gMSBcJiGP2#c8PPM#;4g+176u4?#d5pa1#@<6g<6 z=eLVzY!Bv8;cVfv9harsSnYed9PH7o=CkkK`(@tvP?KVt3f92!}?h4#P&PXk@t@_;` zZKdBnIAt+J2kMx~b0bSk%N$7w=W>El5!*Hi`N@|xqYf3DCe{bLL2il#m3DObL>um% zFy@4;BgF|mtUfeAv5KD;WX?#i z&Ma<0yfk!j#8PFO+`xgoViwTez*E0$*wDYqYzpy-tzyGDB&@oq*3N8Zw&|_&o;ncl zpx(PiKQr($@=4D6vHf**J;Xd>Ab8n2+sHi4R1$OUWRq}x1*z(YurkBpJ73#ypNMjO zt3J2Pl%mE}owp8NN~c79-TZ!i1VDetg4F3x&$mpwg)&lCcdaJD*0ojNk3m~bAAkAn z7s$q)6g&wmCyQ0XmD7yyt@;@05KnQ%{B{ZnVXjjQptiWRqqAJ%I2xLm65ylWsTgR9 z_`s7-b4*Q8p*}ZXF<-BJyNh_+QGApubpBp=`a;D_=*Kz8e!k)6{pa^~HE+sK9;~hT z=*pJww3R!U^Lqv*ogXC{ThHv~piLEyj;M2;JI|U7r7hNP0KHgO>pD<{Z!LUL&~x@z zRseqxmRI1$AbiP#aTi<53$y2|esrnse&@et=?Auo<65ePtAQJ-!Vj3dE80v=oMoEDR zehve}kqnVz*lqgrVXjlv@W+07wM~H724-RcL7l~_byP55n{Z|_fQFh1pFj1`dko~A z9npn;od7Q^3{Y;c*yaj|>`b&Exixpu)mdHz$xrg%JvMg)ewYk-q^oADLGIXX`ZVoxw#He z!aKHkx~Z#4(wniyQu+^wkuHFF)2|&T68#(=7~2eSq1fEv$`upq_DA}y;`RU^u9q(0 zv>Kk9vK@enBi{}Es}iyn|8^V<5SBmlcW6dB$g0;Pz;FUXnvhk?!gNh)rE_6IMxlu9 z!TePzhpG|;Fq8jD={t_uP>PPqmp`3MW*a=z{Z@k?;7(6M4xaS@XsCoC^HKBz8minL zO_9O!*gafokRgB|`pI63h(Lc_T*$`AK?bpegx%Cb(NKf=pceQSwL@fvUVw6^=L1#2 zLf{K9QbP?oDp3kLAXq6Z>sS$r%ywYs%D)^x!IfVavXL#BDlS6u?(#}_*vYpr(B>9e z>#(r9!9;$-^icSI!j}}N#ou>@kRrpN<=n)`AdODHzm8WnHRRnACGy*PH8Qw@7{MKA z%O&az0ckraVu7?W%v*XEx$CfEhrvXjSNC=T46cPyuL7=}%%R1O5I`_5c0yAgP^2)Q z6i9znH=KY_zoKa$T$7Bu1CqP;DH@A zh$3L-ieB_dr1DtzUl2GbP*3de=+C<=O26Lg?6IYN5(cda5oQuvtqD6Y90h|`*A_P* z_~;$T=}mXdVszhvxQpgkwQT1)nQ zxe*a0A~MK`$|B?_jmZxe=N>0aB{cZxfU5=p7@K2oK_JbkB^v~fv~bx&j)q&MYtMs& zUHKMyGD(|RZDJPk0mN;t>l41F?-VeT#%QRIL_k-P+h@Gtu#B- z-&?IBJG$QweR5Ufb1MLGp0$3890vR;VqxK}0E5cLhZ>E9dn``ehg`W138)&mj_-`- z0t`wMN0g+vWoT|t5I784t#lm=G7>!n>J$2&Ex&4CGVL!Y!f3DP^N7dU~ z(Jsiqi{mZ3C?Xf78OZ=Up}*VkZB8TGXssMuS2(SLR!ka)jvZpCVZNNoB;o4I#o zM^nXgTJfb`O`x7-);flxOJuRkL%+;qAaUtJb>m1f&q*$IAnzh_9}z=UEAB6F0|&Bw z&3*c(GdXVc8a+4Yt_dA1Te3kMcw4)#1;SQ1{713#p%sKo6J0dx;0i_b_08WA&>@`X zBvA0SWG7fPT4*+8mn1dz0h6fi2e>JA(YYcnIMAwyOL-D zqn+-+ozHTC;zob~0$PxO7$Uelbj%e9!!Czf8d{3L&Y}l0LdhdSuZD$ZNAC*$LWw>N zenW<(j%B8|99luC1Zd?7)T8jTgEOIESzllyL=RzQ`7qg!4+DnXr~MWNy(sVCj|>(c z4kp?srY?bjNMc0Y(eaRT#UsV^3-Bun{;#wJa7or8gPzoPAP0E>IH&26Tv zXL3A$rubogI6;*^+gcJ>>r;FHQDL^83{&N^h0_`nrHUrfU{GU6LplQ(6bWI|RQWJ{ zaWoi3snCBrUM86G>7t1fkSGKV*(Q|#%5)z3|G}j`cmIur1R0V>?=MP&VJ!U*2$|yF zFbtnxh2LqCqJKuI@+;u~4!gq&aiRFf1s#%YEg;V(kQ@Dt5G*OGj>QsA`yc-bgnv8& z-{v=@Bw1cJ*ch=bk)_*KhoYrfp-X!wpg=``OtnJq51zKjSw7V$?-+)gn&(_1qlxlO zKoS1*07a;Mh~n!7={o1Ev|36B@Wvu2l1l! zX`(sjx@uYmpc;)@tbdxFUl1WKO`i=UPQ78b2Px>Hx#lLQoYgQp;zT5`Ngr8eT^lEj zvt@z$h+)JZuBuuLW5Ny_WRYR{SN&U`G)la_E}&|BXo;ND%MBb*Ug#wXn-38}Rnc`k z(6$iAWq7j*29bQN263SuA;NIA%qp6LNRaI|&&Gj3)Yp@?2_98M-+Vo3a9rn1Q1Et; zlh&YxW(zrKFr2R^O@t6$P4xr#PL%>%Q%CAx6CDy!;{Cd)SE;dA`s>#(?LSFB=bSS7bh$AX93gH(M)$Y zps9Iz`Ms!QQqe%i)w zV}bj0yyPG!{3-KS_Wzf?riVmOY?t;?+AC;!Sf}7-yVK2ut!r zM~(Ex&8fV6CDC7eoxrwh(W1RA;Ht!9BT^~HP3XR#!9UkYCjY8gBN8ve)mh<8f3qOh zTaNB+PjgPH9dwXj#59tOG%CE*cK@xfM_p97ImH#!LW2NpFxG}|hbZCI@7eGr6aBja ziCb_8>BiGnZVvEWLGBC7qx_@*ts~aP%hx~bVE94^0fNLjeOcbT zLWWo`Px=qpcWpdEED*aIZ`ptwp{4Y@=e`^Mi<3Y-385E=8s;SM1N+5O=!qw0p%#cd zj^Y8-bSBvkq?J$Th6;k9c7R?Au@8O_$sQmzD{2G=>MwS_1%k*J6sVvf5(bD&Q1lnV z{+j9tI^Yil6n^&&KLQsZFOK3>3g-g+q5Kcl69<(5XnBo3^cG_XkgP7!4TO(2;v%a> z7#k%(26jYYjGB{GdP!Fp@=vk*_ryWoE)H=ysG3m%C{(arp#+@AH+D5B4-hLYP|XDe zG6ycm9M&EQ61zpiKEa8XIRbuElgIm;_@IPz8)bg76=8&p0RLeZmB3->3JDARs)onV z1-Eo8{vkSW+7caOax9?cnBZ3|sbm`Jr>Y)*X;g;hkWC~%2g}&c$)hgfYBng4)E~$U zO4f$Vl(sE|_9r((8zc~A$ms#D=WA z&N7S(lKuac&f89jAu562dk`2MRbrePl&Iae7sJGpzQjKC?Y(%sw&7D619sH^5+!X(fA8*qABe<@{>wpQ307=JOkR62kE{or zPLSfN4+?~2{;%ah_c$B^S1L&ch>-zO^!$8X?1P1r30~lF zi`E(ukyUp_JlslM`xDD`1p|2~kG75>8)rNhtFY{a!dpIb5-w_@Zd6qHn5Z{+kg6aK z*l~d9;uO~P4hgqz&(*4D95wDna@RwyJNv8)#LG)1p@tf{a4FIqm_@vWhT;jSGFVX{ zCC5J{g7D1X(VC)gLQ`MwbwCV&mq!%sTppDT$RY(k+DB(a*Z+BsGXXq4kKOzMQftwP zz0tb7LZ=2ml6lKI5HG*z88`VoGHz7~=jkNVeili->q}4X^{g)SHo(OrOmOtb{Iw{6 zC@5}8+-vOkeK98kvqk1tBd|b7dj&@)_CFx9QYmLrNnh1{>qh z;6qg}@5yuuGhJ3W*${LFIok_FV%*Zb7yKK?`dA|nSF(7NCmMgHS0z-;j zYRYvEsa)c>>K4Av z_Vb%(=VpK$(g9>(Ww`@SGm*KuXo%mgGk2ojYgyp8j?$3`U{GR?1wxuFu&v>H5%5{E zjue*SBgdzM)I<&{1N{Cm3x&|I5$N!H~tqF|K;g{=l@BlD|wP8l?J_#u{=^dn%}p+*aIt=F|4$iVF=50$Mp znPwk6Sg~6)WbMsA>t80xzvyqSi{(moeQgKgF~7DUFg(?tt9#9zBL~%rSf%%R>_DB~ zV-MF$4_}>@--ZN`oPyVUD(MGH|8lzKn*RUf^tDpi|0Aa}pThqC<8&s;|Bcf(dmLyg zdMG~t^idL_bA(}Y=lXWr0KJe@dRA<TaEI{Ds~W=J61ounmcED33A&XOz$xX`+xXSnW(LoJ#r|y+ z!wEl#PlxdbIDl46|ekxlzeTQl+Cz|6`;-e)U!Z?d1%))JXdH>(eXB zKcDt?(M0Kby}Psb29A|PLu+`t#P5qe^a%g;$v3{i@W&G2U3dV|?iD zK|4odpe{dje?UsQK431vMZ>f)P&T^A;l7`-%w8@8>%4?h8T{nk%D9zzKzGe$lqBIf zQ6MZXoi?tYTv~Mg=(}d};Ej=ln|vPe+@wkNX0B6<=Soc4B_r5<%BhStrn#+@PybN) zvB1ZCn|X(&+PavgI0D4%esJFBCDdiP=bm`n`yumWrH6B64`Z-$PonVQ4`rBAJ-WIdO}J&EK^XV;x%f`3RRyo7ENg`_T0+sMqrI z)R4%k5p(O1s>&ruv{b#5vgqKC|^mFLP!xC4b!Ui+(yQ&|fnBWD)$x$!RYJ{iJOl^31p` zGK;4Qxd7L`YBwLN_KA&V!#S@!x_-R@zp@pscqq3b%o;CHbfkigPn9nfWCR`^FFLOibSL z)p~dOVty<}jcBcpxw4IY+T{!Wd`v5(Yc^YAm{H&HK2h#azA5VPp1X7ZM~VNitC@g&uE-$3k-O2)6Pa$ zWzYKvKY;AZ^CdO!0KJ6tkB*YF9r;N1&mJ9nF(hWAB4UMQ-FMiok{3818fuwHE4Sk4 zMy@sdsWVRe8stK4&EG|9n-7zuXniXeyA8BEi^G4H8#QZ0qD!e*gHNJHO;JGcS!Vw` z2Oq9*^nGLW@BxjCWXFch)as~ic(pFLiSo!N{`<2Mj z6_uUwFQT)xjT^VH8eYb$I6cLk6;12K5+-ON*_0xO^m@D^S*qa-XwIa#t2;-10p$Vr zh^d2eFUkSsB2S^PoPX|XHuG~k1DFM8eUmn~pl>9e!Y{>H2Teo_tdx9! zs-#WtQmWA+_AB3D~63RIU*&2PztyT{2&M1|B4Lr@Lu2C1Y)|`;OB?PC2dSbk;{?> zXAJmMPe+lP!kt0>x0@Tk>m&zPLsh^B1SM}Nih}h&pbU4*OI~nOL4%U@6v2Sx4TZnx z4={Dl4rKfTYRH_1iN#>BX=Whf$Md5803>V3Lkt(?{$p56p5*@>3m(kt4+Ep3@y$RT z3Na!42lyYg9?CLeAC?_sY#jCLluD7cfWY8kQDZVP05lQ|j2>ane`22p2;p}Fpn4I3>q&ZwRoTq|!p{-o#;?FW(9>HYx2a=uCQUtiZs1`G{hqRTCj@IvuR2a;%~ zUNTeUx;Oagm_x=1G1~mv@)CGQIQoQ#G08hGi%@D6N0jIv@gPVGo%#Uz0)RJy_Mbh< z-Fim*0oZ*;@?SNVC@iVtwUL9PJAHvH{(^^U@L#Sq*|_iKz<@DiSrAvha@RFv5de1jD`xU9R_(e2xgGwyj)5oAL?C2( z=8TagkOT0>5*6Zd!-px`+EnjYm2nzz8ja{|0<1_qJ6XsoqqS=ljA*h z^er`mJV${l8}cdYzq~Ht*{+dj&lRA>WS;baNPgW)szh(X@h|{lTadRe&JDvqyo!qj z6S6-nXrKl%mUw230UWJAK>lLyd0EG|etzBV%v2-|iz>=WJ!)2i2CTR%PpMj1jGf|U zwNt~E3>=2F_>p6;8c(iBYwZE|F9Rn3fG9Nl|LQh^1~}$6)2%M>BP+exrVRQ_F&O?; z#jsbHThSP@;%6LWG^cfTj$LwDCtDx@(->r&WsBace;J0tH$7i*JjYiyB+T$Pu`)Cy z6!chGT+L>k;^1iBOI>j^f*C#G-o42*-Mt~QN=#dEgmhE=zVUxw%??C>=po(UZ~P?` zdNvd9oAsndrJSt+FEJl2YD{h;8s<-Ni#e?!~|!o zINpzW8vPb1lHk+bI96b9Q_A_lr0j_M5SMvuUuiMLiJMWo_;>N_2mkH}>nqe5GN5A1 z!uJ2B{quj)cH^$h<&XBAi2ts?A5gclMYH#yqw{3^RCg$5ou~dK*afFVEG-9BUSnP< z+WuQdCE}SNr!UzIb1#4Qr?I~*kFM_Lu828R{rscvs`$gpp-tn)7UtM#G=o_nO3wda z`HrLiu)NEh+GU@RiRgf)51voNjXkFN1k;cv9zy5C{Gja;2-U~WR}Vk0Rp80k)rY&$ zF7{of8jkv-Y4r0|dI`t7*aAUj@9KDX8gou+3(S3T57GwXtcW)r`$}|`n51P+OJAf2 znP>N_SFF02^QU_qeZ+iMDp8^=beV|n^KC34Oz+=jtbg?6))x5#tJp^K7xk|5Kzn0a zL@F)Gw_inlF&D5;HCcP|bx0$2O}5|Ht#ZT{w{j@cPMb?GWr>jLYr7(UbUw(n_JLim;yQ}yYlB@$Bs)fH|c;O6y9?8BR`LQOWPBb&Xu$~7E~Iex0Zvu~dJmd$G! zhK(C1d5mXy?7H6qWR~~#3#EC?XJqaz8+9BgyGXXOOjlMIHmom871ZWpJa~R~5lA1f z2{IS3waZw{tx*&0e&64vsWQv$qQ?pShuzg6?5_D=?0$1{zrZxUg2zcdf8Eq}=uFZP zf9VnCdhvc_MBRlh=4}H>koodZvwM7zaW=JNVuIL?VxrMX%VU7E`eZWi?vgYKNm=^C zonu3!;#DGUhgHtPKoRpH4w7I6JbFmQjZg~d)mN7m%ek1g|ByQd%Kx3*4Q!JY_2x3v z-RSBCW$gI_EHMnzIAp&uFVOaxM1Ahnwnw&wb4NC9CV|^T; zyTlj^;CdP=-zdXmGG1ck8;}E>hN++(f(TaP$hq)Fl13CD6|iTeJWjf2o)IUP3_TI2-^} z1MDV1e&PLmw}Bb_lEraf{pN82<;hTWGtc0K33YjY@VPt+y5Oh%5q;=)dM4-Xmk905 zm8?6isw=ho@JLh}Shv(H)T%8SfIOb{VhP^{lb?WoJb z|9#1J>dUCE_Zg6F(kJDba{0`l9GgZ{&`Q(X6L|?XUwF*~_OhE$=h*+lnoP`@8^)A} z66=Nev73EjaejNh-KOg|od?TSEMt6z(7@vDnU!1BavVJu5gJ$P+wyUnq#Y*&+D}{a zjw{vExL@Yg-qU9YU$DQcq7rJYHSJWIGH}w)VLoXrpA2HWTMyiRR}(<@DSFusGw#gt zy9ZYkojB~8nWWkQ?RTI$!}rK5@vsIxQ$2}K&VzxEgw7%U?P@Paf)+c^&rA`~T`#|- zHYNj({p13XYztVJtK+KaxIXk-td}1htv^R3Qzcu4^;9g8KN68{`Ep#@7ToPN^%LT= z^yA>!AL-{QhrYYP7e8e((WU#IE&%THUfyUlXb^I14=%71bZ_>q5J%8neQEt>?43_jXYU%Hy!bj#ctJ z=2I4l=u>3$=9^32{F+pZxApZd_(S%x-6NaaTyZ^7lf`wda^5!6+T#-TK3qwyESJUG zD~j1K1KrJnSzgML)8Gj|OA@KkmOBmx&J`;9{H&eP`iu={ZCrg82q<&bO4uI? zLYYHhJbE{B@q<(ABch0M;AsgksMTGpo*8c3=O}!nUKkt-wOzxC49GE!W)u4_pY1Bz zOjW$%?bX&HEO>N2hALqa z(Sro<=fi40eqlGLh&$^cz^F>RZwWjvT$3Z5TOzkPcsU%5Ii|2D!#{9-mU2oC`f|*c zgNfe`?RMwjt5;o^@(6t(!Tb<99jE<(Qbft?j8I4^4F!NSaDXDpHcTQZahEp1*yyWd zU)n6m`dM9 z@!h8b&%~PD1PpIdSPi&TNY}-HGI7r^kFs(c_ z%%yH|%*L0jA%W6Uv%Ef4b{P0Lq=VbJt%4Y}C~Q`!z?E=T+uXAmri`Enh~Y{;FIInd zwNtsUDf5u*4JQh}eh{&609d?T*%5~gT*7=a%E7XDixAjI)9>!ODp3kmpfyJ6a2(dz zreU|2a~@u5J+B4RhWlRmz%TzXepV#41Jfarffo6OhyHs#bai>O`i~LBMTNZ8)gpGV z`ibb`rD7U!?}zbeb!9)+Tdx~6H3=!zV7y+{t+Ve9>gxjs->L2oZW)9Ek=U_|U{BK8 zoai3jNSAm1bPdJ<;tP#&w_Q7|x25^NGvT$^sY#no7NI{-&_L&HKEate_1cj@QW@?# z3=m?uRhB*xd}t7f=D&sGX(%MFi(>%s^sg>=rB{RQ z`!a=G@7;wL<4oS?fO1@uZdYr~efju8p#F%v676ESJ8oR=bhz^EQZ5Ze+k<|5FwI+= zTh&~KPB4>f+r4+3AVE*Tn(X{GzKU{R61G%FzszaM@2b6#G9epzGp0VC)yONCJcSy~ z>+0pHx6Vq?+e34$@f@!GQF5_oRR<2*7@uF?({TlV5}T=j&Wi94O_kSi%a>sO@T%ORpIz*jk0ZD{lYEy+aTZN*8m72#g{R)GxwLI;cOnWU z#J?9LqL9yrtB}p|woet~D^P&b6e1MHs-b|&NNDP`IsKi9HS)Z=qrT;AkO(pheUP>L zDnTCq+$=+fNd*6$bRLf1-i-<4pa#!^Eg3Z5C^Ju%Y4Tcj;pvIT)a5Q-BX4TXLeHaB z#Gkd>>-_2C{Begh;G-3@8Ag|n&(tB5=A7k6&#;YULv+FN$XjlgjVreyqJrJ*DO)?+ zls7%lE_Gt3OpM3rYY$=t4H+@?OQn@v>e2`4@+(@bJYOcVcGBfH46E@67P1ASJvYc) zzlnp>9ko5VcLm^E1H?oos)DI|^Ur zuxK#Z35h~u|e*Zz?D@ZACxk8q`S;B(YIfN#Qr|Gc9dC~G`C(|*8q z9$2(j^G0~{bH`yrv?u+>B8r9(e-iatNrG@*!@71!bcvHD>tmVRinivs#-G4aE!+sf zp;DVS`y%3x(+U-{MZw_a;Q0?ev&j;k4|YlZUKP?4jPi(?HuIh-KKPP{hH9h zjVW5zOEM1f*NCd8Dk;`bI8B|q2~@*PR&+Po9%Lf5-r`L~8nqA6R)Hn?S4AK$?1$?3 z-H7?UKetA_#Yy65MpqXnpU})`Z*)C!h2vg|tT-FCZc|8d<%oQzvCtx(REHHfW}l^+ zX4Gq6=$C|O#QuDWp?I}+0^2_>B@6TH=AkYoAD70L!6js~qhrFuz!-@`D>>H~N-G95 zL92_33MXb$%i-iZ9d#XY*$E+q=OU39QDfMXant9fWyssu((d%I-GtO~e(BIZMlrN~ z!Gv(h+56x_@qxgQAG*`GB7U6fN$|)B@&mv^7_DsRH$WhWj%kq$ zqNnFaGjpRYlgs7Ij-V}dBTEb@#lu8Q_uHS;jg|;QNYoujNBoXaxuIDcP{PS%Ap@Hg36qkH*L- z)rMMk`BI}rt=3bzb(UCm3lx>dTHTzC)5|39J)JB-m5qQU3yM%5J4h{ zv8$T%XD}ox+nhxKs!A3XaVgKsPrXXVc-5~0=Rd(99JeX|vP)9bd7iiKa?U!x zAu$9p5vO@rtiW@y`OuByzFd<)EXG}8Sq<$S$e(d`i%z?nuRH5|>)h1bKbC-+CM0!> zo@4L8bJ|rr`*vu$+C39QX4>)C&jOE8ja@`&Vfem%cZ7o*EYBeqoN#4?|JD1_rT-Wu z8H)D$in49{=2Znf7xiDgziwA8`p(~zAi$vu9UA(4?LQ8K?XUR7+5@2!9_@b*`M=K| zC9Uh{l0P@IfY#FgTH}{4;N9uJ>jfLGzv6DI&mkJ|O}8bKWeMJh6RG(qmXdSWko1*U z((c{z4?Y1Jc@?W|svh^GdxVkuGt*EjJQ~h4?Th(GyE0O%Lpr3rDvR}2iQ~0q4xbSL zyL0GA=t%fE=L2S?`I4^8!vz7Ef!uAnd2?rA(t?dSF`w1 z8@s3_wi(PRof@{*Znlh`+|xhjwm&KFSzOJ0KU%hH;<;U2I^<*0)Xq8QuAloBZ{;kr zIc??K#HX2MTQ~R9#$oC3*r%zLx@4`4v;JJk#5Z$GgLjT%a3jxs`N^SFG;72$TCr`u zoJPm5;21rB?t(R5S;M!oiHDWwxJvlYA@EKgfn69}e}y^MUJ>FY^YWPq>%QU1u}5BX zUfTDR`A{cE7TbkBlxh{{drdK$Bq}>O1(44zk|#|UvxHPkndLZAN_`%A!ZrU}`E=%e z!N5rqR}ll_5u33!Y%5c4#loJD&itv9tVYC*ltz%tM~!}B=B;7ERt+b?d^01&p?r3l znCiIeRpfW=>13Z6KFe@TdAKnIjb2$2C(KA^#(Q+FQA8zoc~Eb~8*V>d_N9ZKp{3(+ zh(!umMNK`B6P<@9mD1dp3fYKnOz|&;rI$#r4V>@8;I2a%qSjM}K0Qhmcz};I_lTxN z3}waF+fHa=P?t)~40%;@DgUh9Xp3!D1n4Te_lg^xVMJ|pvqzM)?MItqy1vVi6%D>a zq%Yq_L3hA`N2w6E#_(+)s(a^vkBp7@QB~ZMeSKC#W=FtD8lQv{3o+ zJd|X74V2)AZCyqJ<|r{Goca(?T$v%hpo$x;sBg)=LUVf3y=W>(DF(_Ft(E>NXijC! zl8feJ%4kaYt3iIb-fw_8Z}lENNsvmw110hhD{kD+hfI~={p1lp`O?ACc=F|;FK)*Z z?Ft1$T{5~MRu!R7q5DL>M@$!r+K8XIF>K&9l<2!u7ADA-fcyBB_mESjfTfzfrsKEw zggO@g?&wt(iixMTMFs`%+LG%XF)Q2 zYWw~9d06F9nH3BK+_lTy!^`>pSmh|0vpisa2Lnxd`(qeWTk;+(zR1P>@WAcpy1Vdt z9afA)8RbWNEm``ox(M5}Wr4P%f zN`3EI2m>#$r}fc%QG-!ccNS@(aapOx$-a~zU#p=@nYW-1#9;Tmi&*pCteOv0d9UD- zZ5QEPWf#GSP_jt(6MLoEjB6k+RIx&bt7zg#5v4@!$xdn_M2>Cy2|yU+plOhg5#t)9 zWHQ0CkN-18M|Ul9l!keKq2yx&1#FkBf31J0gwl5{YO0zy*b;JBvzJ_$vrx*%VJmNY z-o!>|+3EIaGb-~K%%E9ZOS+*hsTE4}?n=02|G=xYHl;Q-Jdpau?LnJoAnlD|xi#l=;`1R%OLSnvV6sQR`9q)336bwE!s?FH;KOvxpG)<}Az_ zYsoukTA)ph1VW}~1FdnK;D%Y+eI*SVr(fw?-(yx^`bOkT6O)WI?I_%$M@bVC!HBd< zr`z_lB@+|X0BO1vUA}(DP-B-B3C6F^}n3L^Dzd4+J)Z}@f8guj~J6NM)ZIbW*w(|3&rTWHR|Le-!&PvZJ}|H z)U2taa&#KBQI)iqv|%B0=nTwCF3ss3%}MGhxG*yB)$wbfHJ?o}aXVVJc>4|~o`|od zI*j0G+O#|+4J0~;tmyLM{brIs09RwO zMrb)Fz~ntXKCuvpQdNby=qu2l6UT@8bMFrQr9SPdS>DSra>7vco}Fonjv?kwi0Jh{ zYQSz9gfJ50J$d4t{m^{mG_H?c-DU(-eB>r>IkTVol5}qbr@-i}Ufi}VPUp#Su)Vaz zxU>+pz_o<%_0&K3(?YuDNM7IDHAC3~YVDnPy0=gdCHVhW06GK3{KiTyl}iT7C0EKN z*UBYrmGf!cBVWyzl9X}=&M0EuS=$vR9J6-Vd51y}H)BK47?mR*B0BgTi^ETSH`T2ruhI)q-^6znUCsV_CGXhb= zmPid_U$fd?;u1yd(be;+x@8i#C27H1jkSQi5xi&2_DKUvYB?|~U9^j2)i^czOUn~|sfB3n6;mxhZ;^mu**~M*H9)Dac?(Xj9ckVpP zZx$ckE#AF+ad}%F63B!!v;X&} zt3_4wr>jNX*mbu1GOHdvyO`}!8<+d=5GP-L{PXWoz6;av&wr^O7f4_~+V-(*e&1En z{c&koZ2?T=M>MJqVe%K;rz4?z2y--@F3arrqjmiJm-hE{R-!@Dd6Y!^vhyIXTB)8~ z{!w0DC)xJnWt^gA8a@5X40oOUM1{~NL!C~=J^I`ADJ@Tb?smY#9oQlZBmeP#L>B%p zBJ$xjE@tR|MH!oSlwI7Ve_mEKI+Y zw{dziL&iyXjcgaBR+2BX@CFUg%NbHKv)k+#?N14MSmJhy+w2aF-7mBMStQxrzs}l5 zFo9EnDgFBT_51nk*}tNXhdPJ8-H{b9mdi2B!yEL8Z!htX__5k>|Ca}pyRM+Gu5&z^ zyB&IT=*aHJM@nYN(QY86Y9C{AEXsNh mG5*_XJcCwm(v7!8^$0bKctu}fksJ=iWz)`2fBOFzZz0*lSYhh` literal 18487 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 Y%_3aUC@hlWvAAy9`S}n3AF{)gARr)h4gdfE diff --git a/data/projects/demos/TameAnderson-MakeMe.mmpz b/data/projects/demos/TameAnderson-MakeMe.mmpz index de0152818816daec384ba000e646b9808fa55129..b69a64e3afef4692accfad724b0263f4aa6d099c 100644 GIT binary patch delta 3116 zcmV+{4Ab+1+5^Ga0|WpM*n6=Ax!`|o<5>88euXCcFfZ#!@-0rP4UkPzOo3dABr`j+ zgMpz~w5_RbmFU{(V*mS))Wy2eB5lcTO%y>biu}%n)Zx(~#iOdsX;g(DKnFW+KY(F? zawRo<|KSeR;*6Z+UeQbXy-xPs?V{`jS(rL^qC+rqeg4srd1P2$b~5Ip$J&27)s*!e z5m}5G;Lk!%GR%@K7X0>Rmi9Sn+V@)h8xQG2^UV$=O0!Gf?4W`)!|kFp`*hCE*;)VQ zoHMqkGJc9hct*HorLFhumem}cNzK|0+0*Uw`eMHNI!q-- z+71RW1;DmEMH|AhrjJWg1R}L`SATIlhsSJe^20bub;Lc8!3vJuU}COkPTIFx6#!Fv zI}Fm8V^S(WAV&C5GHzv<%8uQ1RYEc4J}iiagv#?$XQ(_rUw^3B_*s8JC|Q-Z_1Sjw zJKoSfo-UjT-Ve+j2+pA3ozZL8bSotE7PYYS3~O5nm;%IHs{D=>4Yu11Y>)q4e+PQp zndWw;tDR{Fe@izG=DNokGO9!=K2gjulF%M)^=wBN+jZ9(WQ(qftt*(iJ{Xtko7sW) zzy$AA8|%hjivVt?sXTvJ+JZ3)i`@-2MDs^3APX>nQ5{crMaR& zS*-EY^aIE=)n+9$bPt+nB*n1&0m&lNI5fnCmsGV|@reuzcD74YTK?e_)WWl;pym?1@AZI^+yGv%Ch%!^mL`&ndFP>-#ep=)S%^Qp-z~q0~3Kp--h9r;S>BX~aHk?@` zmmFF|sa|!&5#62Kt_ya>Bi$Sx29I>}co;m=&E;Y6NH?E{!6V(A9tMwe^LiLO(lV_b z3Xim$Y=^=lHGA8^F!?RaG}Mf62gBsIFxODC%pDAq2Q%B`D_7P_Rimb(E3aJVRLe~n zcSt3^Eg65C((2}*eRl!tW9K@HY4taw{*5Vz%GJ8Tz6rJRsda-z7HXv@sxDTo%3qnP zSyAKq@!{p^@$RnrM1yqj9A~9i&H=E-ufPe@?riAM`sn+J0}b1PN!QzeCBJN9QwuA+;)v|*b#r(=2h7U%KBi9fqKJrfCJ6c_w=;k zS_r<{W3ryf+LI+KB3ofZ2UTnbvd&?`KQz}6*>h~`b#AITdE($4JuB-zrhHYm5v1-h zbrnF#&pI}-9An|(^bA-nEZ@#o@Z-Dq3Rw}oUUK0|6kku-`ArW|IYjnBJg^h9{ zRq%gVgEb1fSLsm7npN*yP13A-g=&&! zRRFF@npFX{CTUg$$eN^C74T}3W@P}YQKI{>M3n)iMv3mj7F7m-8YSAIHG2O2`Q`S0 z!%J1B(uU|u`?-!KydZmrUimi0g|eHP>QR3Vq3cklg-)8KOp7iwOPLnLZI&`EGTSU= zTDY}Y%CsfBW+~Ga;+myQTV89HGHubUVN0?{Bep*)MqRdQnDqYa7qc8EG8osi}Zh#Rlp;Vo)Vio0_iCZ`w>WAZDWr?`f4+O4ANIS z&Bq{pwd4LhNnfm0;udJ~{nc|x0&GqG@0)XF7|)B>_rG-v9qQQ{n*8<6(G4S5yiQl? zTbgV-0Y2LmI51NVEQ}&eu?n#4($oh5`f)lyKPL-_y*@?3^A-1Uu#4=`zoTo8W*@{4?dja}04vJ-s*QLq%6?t5T1GYJOzO%Txk_%qDB z%A(S|z^Hsp4P7LnL=D2DQ1O*v`tgmK4&xgc@zJenUTxDb@wb(dyMW#TPUgDfV09t7 zQHkq7-?c0d(!oao$0wnNN1sOZJl~!9x=mV=qc}|mm9DFH;_|S1XwJbIq)3` z4PWG=Dremj$zH%1lguMGV5%=HDB;iU@mZt+1Rf%x4$)wBgSb^_YO`-R8WulBZd{B^LBMU>i5J9+OE#K>Oc`wXv;e9 z56;9K+Op2ihJ7)IwySe7f7aEvCa2yj9zYmAC;2ALLYxzEud?Y1Yr`XfO^5T z+?4LuQD;q0>XNE*$&E~}tLIUtr|3Pzkq(3poPY!dlHT&&SvH8M;jl(>KMKL7&Qa3j z0%;zmZq|X8Lt^U%*q+PJklI&v&eFY(6RS#b1|DwKl*U*iC#~^wR)??b(>7h%<_ZzE z^_6LxU!$jM4$Obq93sPlJ<=~`V3Gh7;s=ehRJ9d)?nlV>U<)!hJCVr2VW@1dUgiv= zR5;v~es~vlLG+WTTL>Ba6ocGG0k(LTCMSe9v!ceVy#Gy7*NiBq=euA9)yF$UCEa!x z4vd1WNd%CO<8F%MZkpp^_fT2xrC9EzSw0&bD$D&8%l&_hmWPMR@*u_XV8_o?6Z{TS z{0`G9?(cO}-~wV8qs!|gLjQzp=dUJMR#{BERFPOrrNm;6MhdZ*Jyl68W`8}SXr8G% zE~ZsMp+DM0K_&QVf<9bNrKu?i7$#oKsUWgZjPCg`5~Gw3ny~&ty@6fDfSbmd5~?bt zDNN&1`|*E|>zk{Wt3R|KZyv8-e*btY{rqx&Cw=_o-*+FbrIU^<|EG5?%Qr7K;f?;O zBFncAC(_9rLhnMBm&@hpvUlqGGx_C7e!9Kx%%N@d6*+*uIf17JG|-sSaN(sk2fA^o z*#PR%SpAIZ%pq7IuOIuVAR1Znr53<93q-yrt{{I;f&c+||CB6K`k%C%n-FvYPoIDb z{Nm7A`nvZ{`u`7_Oj=%Qa!BmeHQppr^sf_XifDAEx@}r-7eD<9d_#BipWcPVICcGn zs(LWGUJ~VA3>77=fI%+Mh_ZF-9hS*UaBbb6nNA0~-i6|=-o@9iE<|G_Q)GcD%oO;9 z3Mqf-e1@G@%bk4cn2v!|ae*jf(UVJ533V9~+9{Xl{#kmS12o=mteMo!2sX;g)yHy8 zkXi6A{s9#H4`F{?Knb4-E4{f3Uy4Sa6b`*P@WCn4E~1W<>!ClaTC8W>wSWGJ3sXZi ze%nC4m4)6uB+FBi)h)7C8^CZy68}~r?<*W0^Xp~2fD|FJt}{a_mo3{4IuV`AAN~di Gzhql&g&KYU delta 3181 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 TCKnCU^m-wm%OCy^uo%{&q}D63 diff --git a/data/projects/demos/Thaledric-Armageddon.mmpz b/data/projects/demos/Thaledric-Armageddon.mmpz index 0e9d5f83fa9aa17ad0e6ece235c573a2357bf710..731ea55f7d52d44c3aab8204c082677dd519043b 100644 GIT binary patch delta 676 zcmV;V0$csor303w0|WpK35c--1JHlg{T<e-GDJZ_w>Tap>Cd2Pbx*HW}#4kH!*M&PQVfVk=X^@374>2G22CxO_PO(!=e} zMT(^I<|EoPM-59(_hnL_laGHYmPocH`tM>o?WONe9k47gY z_7FHPTDDYbb4cU;+*-Nb%U}NUD+nFSxBm05>DLhy*I#sf9cQ1P650M`)a`B?AS8c* zI<>OAzoI^^cX(G;xN!aVaj^bNcm4d=?dOLehAM)6<$-yOeGw*9l5co z=Ktsapf3w5ymd679rb^pMSpiQOS_#5dFJKrwA%3ILH>27 zSGk$d`f0-Gf2CQ7tBn`CYtPM6H={KG^SuL2g?f6YqG)+b@*j^idxJN)3+A0M@tp!l%!R6o|zqWAs)6GmT6V?@qEY6EmXX( zE_foTTN0S9SGR7WZu)RKPV`ORXFMdiQ~yH{E;{$Oo!i;@d+2}4c!O>yibL0qKRB@iC$53M{Aetp%6&9eAhxpE@g25V z#^5#^60VCkB6k77@IE3a#~D zwg2}gqmw{>G&(7{_>w+LFib%^`C!Dzm9*Pxc;K+>p1)T zl*slkqi%QG03rDc)Tx!_{T20Ty~De*!iDR?2d;IY#zaHNU**WB7Zc}QvHLYWW(jd@?+RAhCe0R8GnFc zhipNqui^hAnWF(fWBz~s5Bjp8!dssXE?FM*@icF(r#q8wvN!P7QJm)MqQAS@qPCq2 zxjEY<1{mHvDA?;%uW~b^^;6^gUunYUYU9Q3+H*6r9jyT0yK1`?6A-xaDYET>-s1bp` WfYYSotyaHh;NAve!OkdAl& diff --git a/data/projects/demos/Thomasso-AxeFromThe80s.mmpz b/data/projects/demos/Thomasso-AxeFromThe80s.mmpz index af68b8b8b114b9f7a6623f57d6637f27da47e4db..f7056d38c2217b78503cdc2228b41f319f31aad3 100644 GIT binary patch literal 15255 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 literal 15390 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 b7}hq4GUlki>}sDT|Mb}Wf#~?7mhJxmHE|BW diff --git a/data/projects/demos/TobyDox-Psycho.mmpz b/data/projects/demos/TobyDox-Psycho.mmpz index 09ec6b6a6b4bd4ca305cb54bafb657e3854c0258..c4fe7a1c428e416336a6ec65d2189e5ef8dcfcc8 100644 GIT binary patch literal 5787 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
Click to expand
-# paste here
+
 
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index feacb8fdb..f9a0ae192 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -7,8 +7,12 @@ assignees: '' --- +# Please search the issue tracker for existing feature requests before submitting your own. Delete this line to confirm no similar request has been posted yet. + ### Enhancement Summary #### Justification #### Mockup + + From 35daff9a841b39abea4f30febb4c9d497d87c190 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Tue, 29 Oct 2019 22:42:52 +0100 Subject: [PATCH 426/445] GitHub: Add Discord contact link to template chooser --- .github/ISSUE_TEMPLATE/config.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..2c51f276e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,4 @@ +contact_links: +- name: Get help on Discord + url: https://lmms.io/chat/ + about: Need help? Have a question? Reach out to other LMMS users on our Discord server! From 200d1c209ce39b1b186a66389b22a9340c51dcdd Mon Sep 17 00:00:00 2001 From: Noah Brecht Date: Sat, 20 Jul 2019 21:03:48 -0400 Subject: [PATCH 427/445] more depricated qt functions --- src/gui/AutomationPatternView.cpp | 2 +- src/gui/widgets/GroupBox.cpp | 2 +- src/tracks/BBTrack.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/AutomationPatternView.cpp b/src/gui/AutomationPatternView.cpp index 6879b5bbd..a9033f37f 100644 --- a/src/gui/AutomationPatternView.cpp +++ b/src/gui/AutomationPatternView.cpp @@ -366,7 +366,7 @@ void AutomationPatternView::paintEvent( QPaintEvent * ) } p.setRenderHints( QPainter::Antialiasing, false ); - p.resetMatrix(); + p.resetTransform(); // bar lines const int lineSize = 3; diff --git a/src/gui/widgets/GroupBox.cpp b/src/gui/widgets/GroupBox.cpp index 158390bb5..06b8e1c5c 100644 --- a/src/gui/widgets/GroupBox.cpp +++ b/src/gui/widgets/GroupBox.cpp @@ -90,7 +90,7 @@ void GroupBox::paintEvent( QPaintEvent * pe ) p.fillRect( 0, 0, width() - 1, height() - 1, p.background() ); // outer rect - p.setPen( p.background().color().dark( 150 ) ); + p.setPen( p.background().color().darker( 150 ) ); p.drawRect( 0, 0, width() - 1, height() - 1 ); // draw line below titlebar diff --git a/src/tracks/BBTrack.cpp b/src/tracks/BBTrack.cpp index 205a22087..779cd3c74 100644 --- a/src/tracks/BBTrack.cpp +++ b/src/tracks/BBTrack.cpp @@ -218,8 +218,8 @@ void BBTCOView::paintEvent( QPaintEvent * ) : ( m_bbTCO->m_useStyleColor ? painter.background().color() : m_bbTCO->colorObj() ) ); - lingrad.setColorAt( 0, c.light( 130 ) ); - lingrad.setColorAt( 1, c.light( 70 ) ); + lingrad.setColorAt( 0, c.lighter( 130 ) ); + lingrad.setColorAt( 1, c.lighter( 70 ) ); // paint a black rectangle under the pattern to prevent glitches with transparent backgrounds p.fillRect( rect(), QColor( 0, 0, 0 ) ); From 38f599b6e71f94fdc743c7f9bd2a95aa339aa0da Mon Sep 17 00:00:00 2001 From: Noah Brecht Date: Sat, 20 Jul 2019 21:08:49 -0400 Subject: [PATCH 428/445] setPath rather than operator= for qDir --- src/gui/dialogs/FileDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/dialogs/FileDialog.cpp b/src/gui/dialogs/FileDialog.cpp index 3ce10760a..54cc9d6e4 100644 --- a/src/gui/dialogs/FileDialog.cpp +++ b/src/gui/dialogs/FileDialog.cpp @@ -47,7 +47,7 @@ FileDialog::FileDialog( QWidget *parent, const QString &caption, // Find downloads directory QDir downloadDir( QDir::homePath() + "/Downloads" ); if ( ! downloadDir.exists() ) - downloadDir = QStandardPaths::writableLocation( QStandardPaths::DownloadLocation ); + downloadDir.setPath(QStandardPaths::writableLocation( QStandardPaths::DownloadLocation )); if ( downloadDir.exists() ) urls << QUrl::fromLocalFile( downloadDir.absolutePath() ); From 2c5bf2b9dd75d21c5a059d58de68a270666d533c Mon Sep 17 00:00:00 2001 From: Noah Brecht Date: Thu, 25 Jul 2019 11:01:29 -0400 Subject: [PATCH 429/445] lambdas instead of QSignalMapper --- src/gui/editors/PianoRoll.cpp | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 065234aa4..5d11088f3 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -36,7 +36,6 @@ #include #include #include -#include #ifndef __USE_XOPEN #define __USE_XOPEN @@ -204,20 +203,15 @@ PianoRoll::PianoRoll() : m_nemStr.push_back( tr( "Note Velocity" ) ); m_nemStr.push_back( tr( "Note Panning" ) ); - QSignalMapper * signalMapper = new QSignalMapper( this ); m_noteEditMenu = new QMenu( this ); m_noteEditMenu->clear(); for( int i = 0; i < m_nemStr.size(); ++i ) { QAction * act = new QAction( m_nemStr.at(i), this ); - connect( act, SIGNAL(triggered()), signalMapper, SLOT(map()) ); - signalMapper->setMapping( act, i ); + connect( act, &QAction::triggered, [this, i](){ changeNoteEditMode(i); } ); m_noteEditMenu->addAction( act ); } - connect( signalMapper, SIGNAL(mapped(int)), - this, SLOT(changeNoteEditMode(int)) ); - signalMapper = new QSignalMapper( this ); m_semiToneMarkerMenu = new QMenu( this ); QAction* markSemitoneAction = new QAction( tr("Mark/unmark current semitone"), this ); @@ -227,19 +221,12 @@ PianoRoll::PianoRoll() : QAction* unmarkAllAction = new QAction( tr("Unmark all"), this ); QAction* copyAllNotesAction = new QAction( tr("Select all notes on this key"), this); - connect( markSemitoneAction, SIGNAL(triggered()), signalMapper, SLOT(map()) ); - connect( markAllOctaveSemitonesAction, SIGNAL(triggered()), signalMapper, SLOT(map()) ); - connect( markScaleAction, SIGNAL(triggered()), signalMapper, SLOT(map()) ); - connect( markChordAction, SIGNAL(triggered()), signalMapper, SLOT(map()) ); - connect( unmarkAllAction, SIGNAL(triggered()), signalMapper, SLOT(map()) ); - connect( copyAllNotesAction, SIGNAL(triggered()), signalMapper, SLOT(map()) ); - - signalMapper->setMapping( markSemitoneAction, static_cast( stmaMarkCurrentSemiTone ) ); - signalMapper->setMapping( markAllOctaveSemitonesAction, static_cast( stmaMarkAllOctaveSemiTones ) ); - signalMapper->setMapping( markScaleAction, static_cast( stmaMarkCurrentScale ) ); - signalMapper->setMapping( markChordAction, static_cast( stmaMarkCurrentChord ) ); - signalMapper->setMapping( unmarkAllAction, static_cast( stmaUnmarkAll ) ); - signalMapper->setMapping( copyAllNotesAction, static_cast( stmaCopyAllNotesOnKey ) ); + connect( markSemitoneAction, &QAction::triggered, [this](){ markSemiTone(stmaMarkCurrentSemiTone); }); + connect( markAllOctaveSemitonesAction, &QAction::triggered, [this](){ markSemiTone(stmaMarkAllOctaveSemiTones); }); + connect( markScaleAction, &QAction::triggered, [this](){ markSemiTone(stmaMarkCurrentScale); }); + connect( markChordAction, &QAction::triggered, [this](){ markSemiTone(stmaMarkCurrentChord); }); + connect( unmarkAllAction, &QAction::triggered, [this](){ markSemiTone(stmaUnmarkAll); }); + connect( copyAllNotesAction, &QAction::triggered, [this](){ markSemiTone(stmaCopyAllNotesOnKey); }); markScaleAction->setEnabled( false ); markChordAction->setEnabled( false ); @@ -247,8 +234,6 @@ PianoRoll::PianoRoll() : connect( this, SIGNAL(semiToneMarkerMenuScaleSetEnabled(bool)), markScaleAction, SLOT(setEnabled(bool)) ); connect( this, SIGNAL(semiToneMarkerMenuChordSetEnabled(bool)), markChordAction, SLOT(setEnabled(bool)) ); - connect( signalMapper, SIGNAL(mapped(int)), this, SLOT(markSemiTone(int)) ); - m_semiToneMarkerMenu->addAction( markSemitoneAction ); m_semiToneMarkerMenu->addAction( markAllOctaveSemitonesAction ); m_semiToneMarkerMenu->addAction( markScaleAction ); From d9f1383ca9d5b1b2af89c415cab57363a4357d49 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Tue, 27 Aug 2019 15:19:42 +0200 Subject: [PATCH 430/445] Remove remaining usages of QSignalMapper --- include/PianoRoll.h | 1 - include/Track.h | 1 - src/tracks/InstrumentTrack.cpp | 11 +++++------ src/tracks/SampleTrack.cpp | 11 +++++------ 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/include/PianoRoll.h b/include/PianoRoll.h index f56d791f4..7c2c53d42 100644 --- a/include/PianoRoll.h +++ b/include/PianoRoll.h @@ -46,7 +46,6 @@ class QPixmap; class QScrollBar; class QString; class QMenu; -class QSignalMapper; class ComboBox; class NotePlayHandle; diff --git a/include/Track.h b/include/Track.h index 40b32a61a..525699548 100644 --- a/include/Track.h +++ b/include/Track.h @@ -29,7 +29,6 @@ #include #include #include -#include #include #include diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 730ab97bd..673996fa2 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -1239,6 +1239,7 @@ void InstrumentTrackView::muteChanged() +//FIXME: This is identical to SampleTrackView::createFxMenu QMenu * InstrumentTrackView::createFxMenu(QString title, QString newFxLabel) { int channelIndex = model()->effectChannelModel()->value(); @@ -1253,8 +1254,6 @@ QMenu * InstrumentTrackView::createFxMenu(QString title, QString newFxLabel) QMenu *fxMenu = new QMenu( title ); - QSignalMapper * fxMenuSignalMapper = new QSignalMapper(fxMenu); - fxMenu->addAction( newFxLabel, this, SLOT( createFxLine() ) ); fxMenu->addSeparator(); @@ -1264,14 +1263,14 @@ QMenu * InstrumentTrackView::createFxMenu(QString title, QString newFxLabel) if ( currentChannel != fxChannel ) { + auto index = currentChannel->m_channelIndex; 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); + fxMenu->addAction(label, [this, index](){ + assignFxLine(index); + }); } } - connect(fxMenuSignalMapper, SIGNAL(mapped(int)), this, SLOT(assignFxLine(int))); - return fxMenu; } diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 4b51ef6ec..ba04f909b 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -847,6 +847,7 @@ SampleTrackView::~SampleTrackView() +//FIXME: This is identical to InstrumentTrackView::createFxMenu QMenu * SampleTrackView::createFxMenu(QString title, QString newFxLabel) { int channelIndex = model()->effectChannelModel()->value(); @@ -861,8 +862,6 @@ QMenu * SampleTrackView::createFxMenu(QString title, QString newFxLabel) QMenu *fxMenu = new QMenu(title); - QSignalMapper * fxMenuSignalMapper = new QSignalMapper(fxMenu); - fxMenu->addAction(newFxLabel, this, SLOT(createFxLine())); fxMenu->addSeparator(); @@ -872,14 +871,14 @@ QMenu * SampleTrackView::createFxMenu(QString title, QString newFxLabel) if (currentChannel != fxChannel) { + const auto index = currentChannel->m_channelIndex; 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); + fxMenu->addAction(label, [this, index](){ + assignFxLine(index); + }); } } - connect(fxMenuSignalMapper, SIGNAL(mapped(int)), this, SLOT(assignFxLine(int))); - return fxMenu; } From b5b3b2e6a61d4eb97b6f5016069e56ff820c2b47 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Wed, 30 Oct 2019 11:13:18 +0100 Subject: [PATCH 431/445] CMake: Require Qt 5.6+ --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 22e241c92..2f310d27c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,7 +144,7 @@ CHECK_INCLUDE_FILES(locale.h LMMS_HAVE_LOCALE_H) LIST(APPEND CMAKE_PREFIX_PATH "${CMAKE_INSTALL_PREFIX}") -FIND_PACKAGE(Qt5 COMPONENTS Core Gui Widgets Xml REQUIRED) +FIND_PACKAGE(Qt5 5.6.0 COMPONENTS Core Gui Widgets Xml REQUIRED) FIND_PACKAGE(Qt5 COMPONENTS LinguistTools QUIET) INCLUDE_DIRECTORIES( From 400c8d8105b1ed3cb312d45c2c42f7b9b28da1c2 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Wed, 30 Oct 2019 12:12:53 +0100 Subject: [PATCH 432/445] Remove Travis MinGW builds We already run them on CircleCI with a newer Qt version. --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ab2a8ae85..f94aa0846 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,8 +11,6 @@ matrix: include: - env: TYPE=style - os: linux - - env: TARGET_OS=win32 - - env: TARGET_OS=win64 - env: TARGET_OS=debian-sid TARGET_DEPLOY=True git: depth: false From 9cb1f8e784b5000654f49504bae717ce1828f34c Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Thu, 31 Oct 2019 14:37:40 +0900 Subject: [PATCH 433/445] Change the docker tag for CircleCI Linux builds In response to https://github.com/LMMS/lmms-ci-docker/pull/7 --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c1a8ea7ff..0dc146486 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -113,7 +113,7 @@ jobs: - *save_cache linux.gcc: docker: - - image: lmmsci/linux.gcc:xenial + - image: lmmsci/linux.gcc:16.04 environment: <<: *common_environment steps: From 488c4ea6034da306ee14932131c4d6536bfbf7af Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Thu, 31 Oct 2019 15:14:52 +0900 Subject: [PATCH 434/445] CircleCI: support Qt from a PPA on /opt --- .circleci/config.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0dc146486..0ab2c51a0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -122,7 +122,10 @@ jobs: - *restore_cache - run: name: Configure - command: mkdir build && cd build && cmake .. $CMAKE_OPTS -DCMAKE_INSTALL_PREFIX=./install + command: | + source /opt/qt5*/bin/qt5*-env.sh || true + mkdir build && cd build + cmake .. $CMAKE_OPTS -DCMAKE_INSTALL_PREFIX=./install - run: name: Build command: cd build && make From 53e6b645c8e550156aa312a1b8b0d4b085bf7eac Mon Sep 17 00:00:00 2001 From: Alexandre Almeida Date: Thu, 31 Oct 2019 15:13:25 +0100 Subject: [PATCH 435/445] Use "bar" instead of "tact" Closes #4865 --- include/AutomationEditor.h | 6 +- include/BBTrackContainer.h | 4 +- include/MidiTime.h | 36 +++--- include/PianoRoll.h | 2 +- include/Song.h | 26 ++--- include/StepRecorderWidget.h | 6 +- include/TimeLineWidget.h | 18 +-- include/Track.h | 8 +- include/TrackContainerView.h | 22 ++-- include/lmms_basics.h | 2 +- plugins/MidiImport/MidiImport.cpp | 14 +-- plugins/carlabase/carla.cpp | 4 +- src/core/AutomationPattern.cpp | 2 +- src/core/BBTrackContainer.cpp | 25 ++-- src/core/Engine.cpp | 8 +- src/core/Mixer.cpp | 8 +- src/core/Song.cpp | 44 +++---- src/core/Track.cpp | 138 +++++++++++----------- src/core/TrackContainer.cpp | 7 +- src/core/midi/MidiTime.cpp | 52 ++++----- src/gui/AutomationPatternView.cpp | 12 +- src/gui/TimeLineWidget.cpp | 30 ++--- src/gui/TrackContainerView.cpp | 6 +- src/gui/editors/AutomationEditor.cpp | 94 +++++++-------- src/gui/editors/PianoRoll.cpp | 142 +++++++++++------------ src/gui/editors/SongEditor.cpp | 42 +++---- src/gui/widgets/StepRecorderWidget.cpp | 10 +- src/gui/widgets/TimeDisplayWidget.cpp | 10 +- src/tracks/AutomationTrack.cpp | 6 +- src/tracks/BBTrack.cpp | 10 +- src/tracks/InstrumentTrack.cpp | 2 +- src/tracks/Pattern.cpp | 64 +++++----- src/tracks/SampleTrack.cpp | 18 +-- tests/src/tracks/AutomationTrackTest.cpp | 4 +- 34 files changed, 439 insertions(+), 443 deletions(-) diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h index 968bb34be..e39eaddd7 100644 --- a/include/AutomationEditor.h +++ b/include/AutomationEditor.h @@ -176,8 +176,8 @@ private: static const int TOP_MARGIN = 16; static const int DEFAULT_Y_DELTA = 6; - static const int DEFAULT_STEPS_PER_TACT = 16; - static const int DEFAULT_PPT = 12 * DEFAULT_STEPS_PER_TACT; + static const int DEFAULT_STEPS_PER_BAR = 16; + static const int DEFAULT_PPB = 12 * DEFAULT_STEPS_PER_BAR; static const int VALUES_WIDTH = 64; @@ -230,7 +230,7 @@ private: float m_drawLastLevel; tick_t m_drawLastTick; - int m_ppt; + int m_ppb; int m_y_delta; bool m_y_auto; diff --git a/include/BBTrackContainer.h b/include/BBTrackContainer.h index 236325157..e4895aa87 100644 --- a/include/BBTrackContainer.h +++ b/include/BBTrackContainer.h @@ -48,8 +48,8 @@ public: return "bbtrackcontainer"; } - tact_t lengthOfBB( int _bb ) const; - inline tact_t lengthOfCurrentBB() + bar_t lengthOfBB( int _bb ) const; + inline bar_t lengthOfCurrentBB() { return lengthOfBB( currentBB() ); } diff --git a/include/MidiTime.h b/include/MidiTime.h index 0e8015e04..952b4b6d5 100644 --- a/include/MidiTime.h +++ b/include/MidiTime.h @@ -32,10 +32,10 @@ #include "lmms_export.h" #include "lmms_basics.h" -// note: 1 "Tact" = 1 Measure -const int DefaultTicksPerTact = 192; -const int DefaultStepsPerTact = 16; -const int DefaultBeatsPerTact = DefaultTicksPerTact / DefaultStepsPerTact; +// note: a bar was erroneously called "tact" in older versions of LMMS +const int DefaultTicksPerBar = 192; +const int DefaultStepsPerBar = 16; +const int DefaultBeatsPerBar = DefaultTicksPerBar / DefaultStepsPerBar; class MeterModel; @@ -60,19 +60,19 @@ private: class LMMS_EXPORT MidiTime { public: - MidiTime( const tact_t tact, const tick_t ticks ); + MidiTime( const bar_t bar, const tick_t ticks ); MidiTime( const tick_t ticks = 0 ); MidiTime quantize(float) const; - MidiTime toAbsoluteTact() const; + MidiTime toAbsoluteBar() const; MidiTime& operator+=( const MidiTime& time ); MidiTime& operator-=( const MidiTime& time ); - // return the tact, rounded down and 0-based - tact_t getTact() const; - // return the tact, rounded up and 0-based - tact_t nextFullTact() const; + // return the bar, rounded down and 0-based + bar_t getBar() const; + // return the bar, rounded up and 0-based + bar_t nextFullBar() const; void setTicks( tick_t ticks ); tick_t getTicks() const; @@ -90,21 +90,21 @@ public: // calculate number of frame that are needed this time f_cnt_t frames( const float framesPerTick ) const; - double getTimeInMilliseconds(bpm_t beatsPerMinute) const; + double getTimeInMilliseconds( bpm_t beatsPerMinute ) const; static MidiTime fromFrames( const f_cnt_t frames, const float framesPerTick ); - static tick_t ticksPerTact(); - static tick_t ticksPerTact( const TimeSig &sig ); - static int stepsPerTact(); - static void setTicksPerTact( tick_t tpt ); + static tick_t ticksPerBar(); + static tick_t ticksPerBar( const TimeSig &sig ); + static int stepsPerBar(); + static void setTicksPerBar( tick_t tpt ); static MidiTime stepPosition( int step ); - static double ticksToMilliseconds(tick_t ticks, bpm_t beatsPerMinute); - static double ticksToMilliseconds(double ticks, bpm_t beatsPerMinute); + static double ticksToMilliseconds( tick_t ticks, bpm_t beatsPerMinute ); + static double ticksToMilliseconds( double ticks, bpm_t beatsPerMinute ); private: tick_t m_ticks; - static tick_t s_ticksPerTact; + static tick_t s_ticksPerBar; } ; diff --git a/include/PianoRoll.h b/include/PianoRoll.h index 7c2c53d42..b600385c8 100644 --- a/include/PianoRoll.h +++ b/include/PianoRoll.h @@ -382,7 +382,7 @@ private: int m_oldNotesEditHeight; int m_notesEditHeight; - int m_ppt; // pixels per tact + int m_ppb; // pixels per bar int m_totalKeysToScroll; // remember these values to use them diff --git a/include/Song.h b/include/Song.h index 32ead7181..1e047caaa 100644 --- a/include/Song.h +++ b/include/Song.h @@ -45,7 +45,7 @@ class TimeLineWidget; const bpm_t MinTempo = 10; const bpm_t DefaultTempo = 140; const bpm_t MaxTempo = 999; -const tick_t MaxSongLength = 9999 * DefaultTicksPerTact; +const tick_t MaxSongLength = 9999 * DefaultTicksPerBar; class LMMS_EXPORT Song : public TrackContainer @@ -155,14 +155,14 @@ public: m_playPos[playMode].setTicks(ticks); } - inline int getTacts() const + inline int getBars() const { - return currentTact(); + return currentBar(); } - inline int ticksPerTact() const + inline int ticksPerBar() const { - return MidiTime::ticksPerTact(m_timeSigModel); + return MidiTime::ticksPerBar(m_timeSigModel); } // Returns the beat position inside the bar, 0-based @@ -254,7 +254,7 @@ public: } void updateLength(); - tact_t length() const + bar_t length() const { return m_length; } @@ -382,9 +382,9 @@ private: virtual ~Song(); - inline tact_t currentTact() const + inline bar_t currentBar() const { - return m_playPos[m_playMode].getTact(); + return m_playPos[m_playMode].getBar(); } inline tick_t currentTick() const @@ -415,7 +415,7 @@ private: IntModel m_tempoModel; MeterModel m_timeSigModel; - int m_oldTicksPerTact; + int m_oldTicksPerBar; IntModel m_masterVolumeModel; IntModel m_masterPitchModel; @@ -445,14 +445,14 @@ private: PlayModes m_playMode; PlayPos m_playPos[Mode_Count]; - tact_t m_length; + bar_t m_length; const Pattern* m_patternToPlay; bool m_loopPattern; double m_elapsedMilliSeconds[Mode_Count]; tick_t m_elapsedTicks; - tact_t m_elapsedTacts; + bar_t m_elapsedBars; VstSyncController m_vstSyncController; @@ -473,9 +473,9 @@ signals: void projectLoaded(); void playbackStateChanged(); void playbackPositionChanged(); - void lengthChanged( int tacts ); + void lengthChanged( int bars ); void tempoChanged( bpm_t newBPM ); - void timeSignatureChanged( int oldTicksPerTact, int ticksPerTact ); + void timeSignatureChanged( int oldTicksPerBar, int ticksPerBar ); void controllerAdded( Controller * ); void controllerRemoved( Controller * ); void updateSampleTracks(); diff --git a/include/StepRecorderWidget.h b/include/StepRecorderWidget.h index 0e4512169..cafce2b24 100644 --- a/include/StepRecorderWidget.h +++ b/include/StepRecorderWidget.h @@ -36,14 +36,14 @@ class StepRecorderWidget : public QWidget public: StepRecorderWidget( QWidget * parent, - const int ppt, + const int ppb, const int marginTop, const int marginBottom, const int marginLeft, const int marginRight); //API used by PianoRoll - void setPixelsPerTact(int ppt); + void setPixelsPerBar(int ppb); void setCurrentPosition(MidiTime currentPosition); void setBottomMargin(const int marginBottom); @@ -68,7 +68,7 @@ private: MidiTime m_curStepStartPos; MidiTime m_curStepEndPos; - int m_ppt; // pixels per tact + int m_ppb; // pixels per bar MidiTime m_currentPosition; // current position showed by on PianoRoll QColor m_colorLineStart; diff --git a/include/TimeLineWidget.h b/include/TimeLineWidget.h index 7629694ca..374a26418 100644 --- a/include/TimeLineWidget.h +++ b/include/TimeLineWidget.h @@ -72,15 +72,15 @@ public: } ; - TimeLineWidget(int xoff, int yoff, float ppt, Song::PlayPos & pos, + TimeLineWidget(int xoff, int yoff, float ppb, Song::PlayPos & pos, const MidiTime & begin, Song::PlayModes mode, QWidget * parent); virtual ~TimeLineWidget(); inline QColor const & getBarLineColor() const { return m_barLineColor; } - inline void setBarLineColor(QColor const & tactLineColor) { m_barLineColor = tactLineColor; } + inline void setBarLineColor(QColor const & barLineColor) { m_barLineColor = barLineColor; } inline QColor const & getBarNumberColor() const { return m_barNumberColor; } - inline void setBarNumberColor(QColor const & tactNumberColor) { m_barNumberColor = tactNumberColor; } + inline void setBarNumberColor(QColor const & barNumberColor) { m_barNumberColor = barNumberColor; } inline QColor const & getInactiveLoopColor() const { return m_inactiveLoopColor; } inline void setInactiveLoopColor(QColor const & inactiveLoopColor) { m_inactiveLoopColor = inactiveLoopColor; } @@ -135,18 +135,18 @@ public: m_loopPos[0] : m_loopPos[1]; } - inline void savePos( const MidiTime & _pos ) + inline void savePos( const MidiTime & pos ) { - m_savedPos = _pos; + m_savedPos = pos; } inline const MidiTime & savedPos() const { return m_savedPos; } - inline void setPixelsPerTact( float _ppt ) + inline void setPixelsPerBar( float ppb ) { - m_ppt = _ppt; + m_ppb = ppb; update(); } @@ -163,7 +163,7 @@ public: inline int markerX( const MidiTime & _t ) const { return m_xOffset + static_cast( ( _t - m_begin ) * - m_ppt / MidiTime::ticksPerTact() ); + m_ppb / MidiTime::ticksPerBar() ); } signals: @@ -214,7 +214,7 @@ private: int m_xOffset; int m_posMarkerX; - float m_ppt; + float m_ppb; Song::PlayPos & m_pos; const MidiTime & m_begin; const Song::PlayModes m_mode; diff --git a/include/Track.h b/include/Track.h index 525699548..4adf6378e 100644 --- a/include/Track.h +++ b/include/Track.h @@ -266,7 +266,7 @@ protected: selectableObject::resizeEvent( re ); } - float pixelsPerTact(); + float pixelsPerBar(); DataFile createTCODataFiles(const QVector & tcos) const; @@ -547,10 +547,10 @@ public: void createTCOsForBB( int bb ); - void insertTact( const MidiTime & pos ); - void removeTact( const MidiTime & pos ); + void insertBar( const MidiTime & pos ); + void removeBar( const MidiTime & pos ); - tact_t length() const; + bar_t length() const; inline TrackContainer* trackContainer() const diff --git a/include/TrackContainerView.h b/include/TrackContainerView.h index 094cbfff0..cf79a0a21 100644 --- a/include/TrackContainerView.h +++ b/include/TrackContainerView.h @@ -54,25 +54,25 @@ public: QScrollArea * contentWidget() { - return( m_scrollArea ); + return m_scrollArea; } inline const MidiTime & currentPosition() const { - return( m_currentPosition ); + return m_currentPosition; } virtual bool fixedTCOs() const { - return( false ); + return false; } - inline float pixelsPerTact() const + inline float pixelsPerBar() const { - return( m_ppt ); + return m_ppb; } - void setPixelsPerTact( int _ppt ); + void setPixelsPerBar( int ppb ); const TrackView * trackViewAt( const int _y ) const; @@ -80,12 +80,12 @@ public: inline bool rubberBandActive() const { - return( m_rubberBand->isEnabled() && m_rubberBand->isVisible() ); + return m_rubberBand->isEnabled() && m_rubberBand->isVisible(); } inline QVector selectedObjects() { - return( m_rubberBand->selectedObjects() ); + return m_rubberBand->selectedObjects(); } @@ -118,7 +118,7 @@ public: virtual QString nodeName() const { - return( "trackcontainerview" ); + return "trackcontainerview"; } @@ -139,7 +139,7 @@ public slots: protected: - static const int DEFAULT_PIXELS_PER_TACT = 16; + static const int DEFAULT_PIXELS_PER_BAR = 16; virtual void resizeEvent( QResizeEvent * ); @@ -176,7 +176,7 @@ private: scrollArea * m_scrollArea; QVBoxLayout * m_scrollLayout; - float m_ppt; + float m_ppb; RubberBand * m_rubberBand; diff --git a/include/lmms_basics.h b/include/lmms_basics.h index cca04e97d..961810856 100644 --- a/include/lmms_basics.h +++ b/include/lmms_basics.h @@ -35,7 +35,7 @@ #endif -typedef int32_t tact_t; +typedef int32_t bar_t; typedef int32_t tick_t; typedef uint8_t volume_t; typedef int8_t panning_t; diff --git a/plugins/MidiImport/MidiImport.cpp b/plugins/MidiImport/MidiImport.cpp index b8653fe18..b3d01e790 100644 --- a/plugins/MidiImport/MidiImport.cpp +++ b/plugins/MidiImport/MidiImport.cpp @@ -188,9 +188,9 @@ public: smfMidiCC & putValue( MidiTime time, AutomatableModel * objModel, float value ) { - if( !ap || time > lastPos + DefaultTicksPerTact ) + if( !ap || time > lastPos + DefaultTicksPerBar ) { - MidiTime pPos = MidiTime( time.getTact(), 0 ); + MidiTime pPos = MidiTime( time.getBar(), 0 ); ap = dynamic_cast( at->createTCO(0) ); ap->movePosition( pPos ); @@ -200,7 +200,7 @@ public: lastPos = time; time = time - ap->startPosition(); ap->putValue( time, value, false ); - ap->changeLength( MidiTime( time.getTact() + 1, 0 ) ); + ap->changeLength( MidiTime( time.getBar() + 1, 0 ) ); return *this; } @@ -267,9 +267,9 @@ public: void addNote( Note & n ) { - if( !p || n.pos() > lastEnd + DefaultTicksPerTact ) + if( !p || n.pos() > lastEnd + DefaultTicksPerBar ) { - MidiTime pPos = MidiTime( n.pos().getTact(), 0 ); + MidiTime pPos = MidiTime( n.pos().getBar(), 0 ); p = dynamic_cast( it->createTCO( 0 ) ); p->movePosition( pPos ); } @@ -325,8 +325,8 @@ bool MidiImport::readSMF( TrackContainer* tc ) timeSigDenominatorPat->addObject(&timeSigMM.denominatorModel()); // TODO: adjust these to Time.Sig changes - double beatsPerTact = 4; - double ticksPerBeat = DefaultTicksPerTact / beatsPerTact; + double beatsPerBar = 4; + double ticksPerBeat = DefaultTicksPerBar / beatsPerBar; // Time-sig changes Alg_time_sigs * timeSigs = &seq->time_sig; diff --git a/plugins/carlabase/carla.cpp b/plugins/carlabase/carla.cpp index 3df97ce40..ba2dd085c 100644 --- a/plugins/carlabase/carla.cpp +++ b/plugins/carlabase/carla.cpp @@ -324,10 +324,10 @@ void CarlaInstrument::play(sampleFrame* workingBuffer) fTimeInfo.playing = s->isPlaying(); fTimeInfo.frame = s->getPlayPos(s->playMode()).frames(Engine::framesPerTick()); fTimeInfo.usecs = s->getMilliseconds()*1000; - fTimeInfo.bbt.bar = s->getTacts() + 1; + fTimeInfo.bbt.bar = s->getBars() + 1; fTimeInfo.bbt.beat = s->getBeat() + 1; fTimeInfo.bbt.tick = s->getBeatTicks(); - fTimeInfo.bbt.barStartTick = ticksPerBeat*s->getTimeSigModel().getNumerator()*s->getTacts(); + fTimeInfo.bbt.barStartTick = ticksPerBeat*s->getTimeSigModel().getNumerator()*s->getBars(); fTimeInfo.bbt.beatsPerBar = s->getTimeSigModel().getNumerator(); fTimeInfo.bbt.beatType = s->getTimeSigModel().getDenominator(); fTimeInfo.bbt.ticksPerBeat = ticksPerBeat; diff --git a/src/core/AutomationPattern.cpp b/src/core/AutomationPattern.cpp index e36838d80..b38c704ef 100644 --- a/src/core/AutomationPattern.cpp +++ b/src/core/AutomationPattern.cpp @@ -180,7 +180,7 @@ MidiTime AutomationPattern::timeMapLength() const { if( m_timeMap.isEmpty() ) return 0; timeMap::const_iterator it = m_timeMap.end(); - return MidiTime( MidiTime( (it-1).key() ).nextFullTact(), 0 ); + return MidiTime( MidiTime( (it-1).key() ).nextFullBar(), 0 ); } diff --git a/src/core/BBTrackContainer.cpp b/src/core/BBTrackContainer.cpp index e349c7b02..ac4b6cb1a 100644 --- a/src/core/BBTrackContainer.cpp +++ b/src/core/BBTrackContainer.cpp @@ -62,7 +62,7 @@ bool BBTrackContainer::play( MidiTime _start, fpp_t _frames, return false; } - _start = _start % ( lengthOfBB( _tco_num ) * MidiTime::ticksPerTact() ); + _start = _start % ( lengthOfBB( _tco_num ) * MidiTime::ticksPerBar() ); TrackList tl = tracks(); for( TrackList::iterator it = tl.begin(); it != tl.end(); ++it ) @@ -90,9 +90,9 @@ void BBTrackContainer::updateAfterTrackAdd() -tact_t BBTrackContainer::lengthOfBB( int _bb ) const +bar_t BBTrackContainer::lengthOfBB( int _bb ) const { - MidiTime max_length = MidiTime::ticksPerTact(); + MidiTime max_length = MidiTime::ticksPerBar(); const TrackList & tl = tracks(); for (Track* t : tl) @@ -104,7 +104,7 @@ tact_t BBTrackContainer::lengthOfBB( int _bb ) const } } - return max_length.nextFullTact(); + return max_length.nextFullBar(); } @@ -124,7 +124,7 @@ void BBTrackContainer::removeBB( int _bb ) for( TrackList::iterator it = tl.begin(); it != tl.end(); ++it ) { delete ( *it )->getTCO( _bb ); - ( *it )->removeTact( _bb * DefaultTicksPerTact ); + ( *it )->removeBar( _bb * DefaultTicksPerBar ); } if( _bb <= currentBB() ) { @@ -151,7 +151,7 @@ void BBTrackContainer::swapBB( int _bb1, int _bb2 ) void BBTrackContainer::updateBBTrack( TrackContentObject * _tco ) { BBTrack * t = BBTrack::findBBTrack( _tco->startPosition() / - DefaultTicksPerTact ); + DefaultTicksPerBar ); if( t != NULL ) { t->dataChanged(); @@ -247,16 +247,13 @@ AutomatedValueMap BBTrackContainer::automatedValuesAt(MidiTime time, int tcoNum) Q_ASSERT(tcoNum >= 0); Q_ASSERT(time.getTicks() >= 0); - auto length_tacts = lengthOfBB(tcoNum); - auto length_ticks = length_tacts * MidiTime::ticksPerTact(); - if (time > length_ticks) { + auto length_bars = lengthOfBB(tcoNum); + auto length_ticks = length_bars * MidiTime::ticksPerBar(); + if (time > length_ticks) + { time = length_ticks; } - return TrackContainer::automatedValuesAt(time + (MidiTime::ticksPerTact() * tcoNum), tcoNum); + return TrackContainer::automatedValuesAt(time + (MidiTime::ticksPerBar() * tcoNum), tcoNum); } - - - - diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp index d2b4a9cc2..ce82310fa 100644 --- a/src/core/Engine.cpp +++ b/src/core/Engine.cpp @@ -105,10 +105,10 @@ void LmmsCore::destroy() delete ConfigManager::inst(); } -float LmmsCore::framesPerTick(sample_rate_t sample_rate) +float LmmsCore::framesPerTick(sample_rate_t sampleRate) { - return sample_rate * 60.0f * 4 / - DefaultTicksPerTact / s_song->getTempo(); + return sampleRate * 60.0f * 4 / + DefaultTicksPerBar / s_song->getTempo(); } @@ -117,7 +117,7 @@ float LmmsCore::framesPerTick(sample_rate_t sample_rate) void LmmsCore::updateFramesPerTick() { s_framesPerTick = s_mixer->processingSampleRate() * 60.0f * 4 / - DefaultTicksPerTact / s_song->getTempo(); + DefaultTicksPerBar / s_song->getTempo(); } diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index fd44b0459..3f22a22e1 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -361,12 +361,12 @@ const surroundSampleFrame * Mixer::renderNextBuffer() // Stop crash with metronome if empty project Engine::getSong()->countTracks() ) { - tick_t ticksPerTact = MidiTime::ticksPerTact(); - if ( p.getTicks() % (ticksPerTact / 1 ) == 0 ) + tick_t ticksPerBar = MidiTime::ticksPerBar(); + if ( p.getTicks() % ( ticksPerBar / 1 ) == 0 ) { addPlayHandle( new SamplePlayHandle( "misc/metronome02.ogg" ) ); } - else if ( p.getTicks() % (ticksPerTact / + else if ( p.getTicks() % ( ticksPerBar / song->getTimeSigModel().getNumerator() ) == 0 ) { addPlayHandle( new SamplePlayHandle( "misc/metronome01.ogg" ) ); @@ -1288,5 +1288,3 @@ void Mixer::fifoWriter::write( surroundSampleFrame * buffer ) m_mixer->m_doChangesMutex.unlock(); } - - diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 336aa3df2..78c9f422a 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -55,7 +55,7 @@ #include "PeakController.h" -tick_t MidiTime::s_ticksPerTact = DefaultTicksPerTact; +tick_t MidiTime::s_ticksPerBar = DefaultTicksPerBar; @@ -66,7 +66,7 @@ Song::Song() : this ) ) ), m_tempoModel( DefaultTempo, MinTempo, MaxTempo, this, tr( "Tempo" ) ), m_timeSigModel( this ), - m_oldTicksPerTact( DefaultTicksPerTact ), + m_oldTicksPerBar( DefaultTicksPerBar ), m_masterVolumeModel( 100, 0, 200, this, tr( "Master volume" ) ), m_masterPitchModel( 0, -12, 12, this, tr( "Master pitch" ) ), m_fileName(), @@ -86,7 +86,7 @@ Song::Song() : m_patternToPlay( NULL ), m_loopPattern( false ), m_elapsedTicks( 0 ), - m_elapsedTacts( 0 ), + m_elapsedBars( 0 ), m_loopRenderCount(1), m_loopRenderRemaining(1) { @@ -162,10 +162,10 @@ void Song::setTempo() void Song::setTimeSignature() { - MidiTime::setTicksPerTact( ticksPerTact() ); - emit timeSignatureChanged( m_oldTicksPerTact, ticksPerTact() ); + MidiTime::setTicksPerBar( ticksPerBar() ); + emit timeSignatureChanged( m_oldTicksPerBar, ticksPerBar() ); emit dataChanged(); - m_oldTicksPerTact = ticksPerTact(); + m_oldTicksPerBar = ticksPerBar(); m_vstSyncController.setTimeSignature( getTimeSigModel().getNumerator(), getTimeSigModel().getDenominator() ); @@ -286,20 +286,20 @@ void Song::processNextBuffer() int ticks = m_playPos[m_playMode].getTicks() + ( int )( currentFrame / framesPerTick ); - // did we play a whole tact? - if( ticks >= MidiTime::ticksPerTact() ) + // did we play a whole bar? + if( ticks >= MidiTime::ticksPerBar() ) { // per default we just continue playing even if // there's no more stuff to play // (song-play-mode) - int maxTact = m_playPos[m_playMode].getTact() + int maxBar = m_playPos[m_playMode].getBar() + 2; - // then decide whether to go over to next tact - // or to loop back to first tact + // then decide whether to go over to next bar + // or to loop back to first bar if( m_playMode == Mode_PlayBB ) { - maxTact = Engine::getBBTrackContainer() + maxBar = Engine::getBBTrackContainer() ->lengthOfCurrentBB(); } else if( m_playMode == Mode_PlayPattern && @@ -307,17 +307,17 @@ void Song::processNextBuffer() tl != NULL && tl->loopPointsEnabled() == false ) { - maxTact = m_patternToPlay->length() - .getTact(); + maxBar = m_patternToPlay->length() + .getBar(); } // end of played object reached? - if( m_playPos[m_playMode].getTact() + 1 - >= maxTact ) + if( m_playPos[m_playMode].getBar() + 1 + >= maxBar ) { // then start from beginning and keep // offset - ticks %= ( maxTact * MidiTime::ticksPerTact() ); + ticks %= ( maxBar * MidiTime::ticksPerBar() ); // wrap milli second counter setToTimeByTicks(ticks); @@ -407,8 +407,8 @@ void Song::processNextBuffer() m_playPos[m_playMode].setCurrentFrame( framesToPlay + currentFrame ); m_elapsedMilliSeconds[m_playMode] += MidiTime::ticksToMilliseconds(framesToPlay / framesPerTick, getTempo()); - m_elapsedTacts = m_playPos[Mode_PlaySong].getTact(); - m_elapsedTicks = ( m_playPos[Mode_PlaySong].getTicks() % ticksPerTact() ) / 48; + m_elapsedBars = m_playPos[Mode_PlaySong].getBar(); + m_elapsedTicks = ( m_playPos[Mode_PlaySong].getTicks() % ticksPerBar() ) / 48; } } @@ -619,7 +619,7 @@ void Song::updateLength() continue; } - const tact_t cur = ( *it )->length(); + const bar_t cur = ( *it )->length(); if( cur > m_length ) { m_length = cur; @@ -805,7 +805,7 @@ void Song::insertBar() for( TrackList::const_iterator it = tracks().begin(); it != tracks().end(); ++it ) { - ( *it )->insertTact( m_playPos[Mode_PlaySong] ); + ( *it )->insertBar( m_playPos[Mode_PlaySong] ); } m_tracksMutex.unlock(); } @@ -819,7 +819,7 @@ void Song::removeBar() for( TrackList::const_iterator it = tracks().begin(); it != tracks().end(); ++it ) { - ( *it )->removeTact( m_playPos[Mode_PlaySong] ); + ( *it )->removeBar( m_playPos[Mode_PlaySong] ); } m_tracksMutex.unlock(); } diff --git a/src/core/Track.cpp b/src/core/Track.cpp index fe66ab4a5..dedfcbc27 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -489,8 +489,8 @@ void TrackContentObjectView::updateLength() else { setFixedWidth( - static_cast( m_tco->length() * pixelsPerTact() / - MidiTime::ticksPerTact() ) + 1 /*+ + static_cast( m_tco->length() * pixelsPerBar() / + MidiTime::ticksPerBar() ) + 1 /*+ TCO_BORDER_WIDTH * 2-1*/ ); } m_trackView->trackContainerView()->update(); @@ -528,6 +528,7 @@ void TrackContentObjectView::dragEnterEvent( QDragEnterEvent * dee ) { TrackContentWidget * tcw = getTrackView()->getTrackContentWidget(); MidiTime tcoPos = MidiTime( m_tco->startPosition() ); + if( tcw->canPasteSelection( tcoPos, dee ) == false ) { dee->ignore(); @@ -567,6 +568,7 @@ void TrackContentObjectView::dropEvent( QDropEvent * de ) { TrackContentWidget * tcw = getTrackView()->getTrackContentWidget(); MidiTime tcoPos = MidiTime( m_tco->startPosition() ); + if( tcw->pasteSelection( tcoPos, de ) == true ) { de->accept(); @@ -656,7 +658,7 @@ DataFile TrackContentObjectView::createTCODataFiles( // initialTrackIndex is the index of the track that was touched metadata.setAttribute( "initialTrackIndex", initialTrackIndex ); metadata.setAttribute( "trackContainerId", tc->id() ); - // grabbedTCOPos is the pos of the tact containing the TCO we grabbed + // grabbedTCOPos is the pos of the bar containing the TCO we grabbed metadata.setAttribute( "grabbedTCOPos", m_tco->startPosition() ); dataFile.content().appendChild( metadata ); @@ -770,23 +772,23 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) { s_textFloat->setTitle( tr( "Current position" ) ); s_textFloat->setText( QString( "%1:%2" ). - arg( m_tco->startPosition().getTact() + 1 ). + arg( m_tco->startPosition().getBar() + 1 ). arg( m_tco->startPosition().getTicks() % - MidiTime::ticksPerTact() ) ); + MidiTime::ticksPerBar() ) ); } else if( m_action == Resize || m_action == ResizeLeft ) { s_textFloat->setTitle( tr( "Current length" ) ); s_textFloat->setText( tr( "%1:%2 (%3:%4 to %5:%6)" ). - arg( m_tco->length().getTact() ). + arg( m_tco->length().getBar() ). arg( m_tco->length().getTicks() % - MidiTime::ticksPerTact() ). - arg( m_tco->startPosition().getTact() + 1 ). + MidiTime::ticksPerBar() ). + arg( m_tco->startPosition().getBar() + 1 ). arg( m_tco->startPosition().getTicks() % - MidiTime::ticksPerTact() ). - arg( m_tco->endPosition().getTact() + 1 ). + MidiTime::ticksPerBar() ). + arg( m_tco->endPosition().getBar() + 1 ). arg( m_tco->endPosition().getTicks() % - MidiTime::ticksPerTact() ) ); + MidiTime::ticksPerBar() ) ); } // s_textFloat->reparent( this ); // setup text-float as if TCO was already moved/resized @@ -893,7 +895,7 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) m_hint = NULL; } - const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); + const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); if( m_action == Move ) { MidiTime newPos = draggedTCOPos( me ); @@ -903,9 +905,9 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) m_tco->movePosition( newPos ); m_trackView->getTrackContentWidget()->changePosition(); s_textFloat->setText( QString( "%1:%2" ). - arg( newPos.getTact() + 1 ). + arg( newPos.getBar() + 1 ). arg( newPos.getTicks() % - MidiTime::ticksPerTact() ) ); + MidiTime::ticksPerBar() ) ); s_textFloat->moveGlobal( this, QPoint( width() + 2, height() + 2 ) ); } else if( m_action == MoveSelection ) @@ -945,12 +947,12 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) const bool unquantized = (me->modifiers() & Qt::ControlModifier) || (me->modifiers() & Qt::AltModifier); const float snapSize = gui->songEditor()->m_editor->getSnapSize(); // Length in ticks of one snap increment - const MidiTime snapLength = MidiTime( (int)(snapSize * MidiTime::ticksPerTact()) ); + const MidiTime snapLength = MidiTime( (int)(snapSize * MidiTime::ticksPerBar()) ); if( m_action == Resize ) { // The clip's new length - MidiTime l = static_cast( me->x() * MidiTime::ticksPerTact() / ppt ); + MidiTime l = static_cast( me->x() * MidiTime::ticksPerBar() / ppb ); if ( unquantized ) { // We want to preserve this adjusted offset, @@ -985,8 +987,8 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) const int x = mapToParent( me->pos() ).x() - m_initialMousePos.x(); MidiTime t = qMax( 0, (int) - m_trackView->trackContainerView()->currentPosition()+ - static_cast( x * MidiTime::ticksPerTact() / ppt ) ); + m_trackView->trackContainerView()->currentPosition() + + static_cast( x * MidiTime::ticksPerBar() / ppb ) ); if( unquantized ) { // We want to preserve this adjusted offset, @@ -1023,15 +1025,15 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) } } s_textFloat->setText( tr( "%1:%2 (%3:%4 to %5:%6)" ). - arg( m_tco->length().getTact() ). + arg( m_tco->length().getBar() ). arg( m_tco->length().getTicks() % - MidiTime::ticksPerTact() ). - arg( m_tco->startPosition().getTact() + 1 ). + MidiTime::ticksPerBar() ). + arg( m_tco->startPosition().getBar() + 1 ). arg( m_tco->startPosition().getTicks() % - MidiTime::ticksPerTact() ). - arg( m_tco->endPosition().getTact() + 1 ). + MidiTime::ticksPerBar() ). + arg( m_tco->endPosition().getBar() + 1 ). arg( m_tco->endPosition().getTicks() % - MidiTime::ticksPerTact() ) ); + MidiTime::ticksPerBar() ) ); s_textFloat->moveGlobal( this, QPoint( width() + 2, height() + 2) ); } else @@ -1127,13 +1129,13 @@ void TrackContentObjectView::contextMenuEvent( QContextMenuEvent * cme ) -/*! \brief How many pixels a tact (bar) takes for this trackContentObjectView. +/*! \brief How many pixels a bar takes for this trackContentObjectView. * - * \return the number of pixels per tact (bar). + * \return the number of pixels per bar. */ -float TrackContentObjectView::pixelsPerTact() +float TrackContentObjectView::pixelsPerBar() { - return m_trackView->trackContainerView()->pixelsPerTact(); + return m_trackView->trackContainerView()->pixelsPerBar(); } @@ -1181,11 +1183,11 @@ bool TrackContentObjectView::mouseMovedDistance( QMouseEvent * me, int distance */ MidiTime TrackContentObjectView::draggedTCOPos( QMouseEvent * me ) { - //Pixels per tact - const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); + //Pixels per bar + const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); // The pixel distance that the mouse has moved const int mouseOff = mapToGlobal(me->pos()).x() - m_initialMouseGlobalPos.x(); - MidiTime newPos = m_initialTCOPos + mouseOff * MidiTime::ticksPerTact() / ppt; + MidiTime newPos = m_initialTCOPos + mouseOff * MidiTime::ticksPerBar() / ppb; MidiTime offset = newPos - m_initialTCOPos; // If the user is holding alt, or pressed ctrl after beginning the drag, don't quantize if ( me->button() != Qt::NoButton @@ -1264,13 +1266,13 @@ TrackContentWidget::~TrackContentWidget() void TrackContentWidget::updateBackground() { - const int tactsPerBar = 4; const TrackContainerView * tcv = m_trackView->trackContainerView(); - // Assume even-pixels-per-tact. Makes sense, should be like this anyways - int ppt = static_cast( tcv->pixelsPerTact() ); + // Assume even-pixels-per-bar. Makes sense, should be like this anyways + int ppb = static_cast( tcv->pixelsPerBar() ); - int w = ppt * tactsPerBar; + // alternate between a darker and a lighter color every 4 bars + int w = ppb * 4; int h = height(); m_background = QPixmap( w * 2, height() ); QPainter pmp( &m_background ); @@ -1281,13 +1283,13 @@ void TrackContentWidget::updateBackground() // draw lines // vertical lines pmp.setPen( QPen( gridColor(), 1 ) ); - for( float x = 0; x < w * 2; x += ppt ) + for( float x = 0; x < w * 2; x += ppb ) { pmp.drawLine( QLineF( x, 0.0, x, h ) ); } pmp.setPen( QPen( embossColor(), 1 ) ); - for( float x = 1.0; x < w * 2; x += ppt ) + for( float x = 1.0; x < w * 2; x += ppb ) { pmp.drawLine( QLineF( x, 0.0, x, h ) ); } @@ -1382,7 +1384,7 @@ void TrackContentWidget::changePosition( const MidiTime & newPos ) it != m_tcoViews.end(); ++it ) { if( ( *it )->getTrackContentObject()-> - startPosition().getTact() == curBB ) + startPosition().getBar() == curBB ) { ( *it )->move( 0, ( *it )->y() ); ( *it )->raise(); @@ -1398,7 +1400,7 @@ void TrackContentWidget::changePosition( const MidiTime & newPos ) it != m_tcoViews.end(); ++it ) { if( ( *it )->getTrackContentObject()-> - startPosition().getTact() != curBB ) + startPosition().getBar() != curBB ) { ( *it )->hide(); } @@ -1415,7 +1417,7 @@ void TrackContentWidget::changePosition( const MidiTime & newPos ) const int begin = pos; const int end = endPosition( pos ); - const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); + const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); setUpdatesEnabled( false ); for( tcoViewVector::iterator it = m_tcoViews.begin(); @@ -1432,8 +1434,8 @@ void TrackContentWidget::changePosition( const MidiTime & newPos ) ( te >= begin && te <= end ) || ( ts <= begin && te >= end ) ) { - tcov->move( static_cast( ( ts - begin ) * ppt / - MidiTime::ticksPerTact() ), + tcov->move( static_cast( ( ts - begin ) * ppb / + MidiTime::ticksPerBar() ), tcov->y() ); if( !tcov->isVisible() ) { @@ -1454,7 +1456,7 @@ void TrackContentWidget::changePosition( const MidiTime & newPos ) -/*! \brief Return the position of the trackContentWidget in Tacts. +/*! \brief Return the position of the trackContentWidget in bars. * * \param mouseX the mouse's current X position in pixels. */ @@ -1463,8 +1465,8 @@ MidiTime TrackContentWidget::getPosition( int mouseX ) TrackContainerView * tv = m_trackView->trackContainerView(); return MidiTime( tv->currentPosition() + mouseX * - MidiTime::ticksPerTact() / - static_cast( tv->pixelsPerTact() ) ); + MidiTime::ticksPerBar() / + static_cast( tv->pixelsPerBar() ) ); } @@ -1477,7 +1479,7 @@ MidiTime TrackContentWidget::getPosition( int mouseX ) void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee ) { MidiTime tcoPos = getPosition( dee->pos().x() ); - if( canPasteSelection( tcoPos, dee ) == false ) + if( canPasteSelection( tcoPos, dee ) == false ) { dee->ignore(); } @@ -1518,7 +1520,7 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QDropEvent* d QDomElement metadata = dataFile.content().firstChildElement( "copyMetadata" ); QDomAttr tcoPosAttr = metadata.attributeNode( "grabbedTCOPos" ); MidiTime grabbedTCOPos = tcoPosAttr.value().toInt(); - MidiTime grabbedTCOTact = MidiTime( grabbedTCOPos.getTact(), 0 ); + MidiTime grabbedTCOBar = MidiTime( grabbedTCOPos.getBar(), 0 ); // Extract the track index that was originally clicked QDomAttr tiAttr = metadata.attributeNode( "initialTrackIndex" ); @@ -1528,10 +1530,10 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QDropEvent* d const TrackContainer::TrackList tracks = t->trackContainer()->tracks(); const int currentTrackIndex = tracks.indexOf( t ); - // Don't paste if we're on the same tact + // Don't paste if we're on the same bar auto sourceTrackContainerId = metadata.attributeNode( "trackContainerId" ).value().toUInt(); if( de->source() && sourceTrackContainerId == t->trackContainer()->id() && - tcoPos == grabbedTCOTact && currentTrackIndex == initialTrackIndex ) + tcoPos == grabbedTCOBar && currentTrackIndex == initialTrackIndex ) { return false; } @@ -1596,7 +1598,7 @@ bool TrackContentWidget::pasteSelection( MidiTime tcoPos, QDropEvent * de ) QDomAttr tcoPosAttr = metadata.attributeNode( "grabbedTCOPos" ); MidiTime grabbedTCOPos = tcoPosAttr.value().toInt(); - // Snap the mouse position to the beginning of the dropped tact, in ticks + // Snap the mouse position to the beginning of the dropped bar, in ticks const TrackContainer::TrackList tracks = getTrack()->trackContainer()->tracks(); const int currentTrackIndex = tracks.indexOf( getTrack() ); @@ -1631,7 +1633,7 @@ bool TrackContentWidget::pasteSelection( MidiTime tcoPos, QDropEvent * de ) // The new position is the old position plus the offset. MidiTime pos = tcoElement.attributeNode( "pos" ).value().toInt() + offset; // If we land on ourselves, offset by one snap - MidiTime shift = MidiTime::ticksPerTact() * gui->songEditor()->m_editor->getSnapSize(); + MidiTime shift = MidiTime::ticksPerBar() * gui->songEditor()->m_editor->getSnapSize(); if (offset == 0) { pos += shift; } TrackContentObject * tco = t->createTCO( pos ); @@ -1695,8 +1697,8 @@ void TrackContentWidget::mousePressEvent( QMouseEvent * me ) so.at( i )->setSelected( false); } getTrack()->addJournalCheckPoint(); - const MidiTime pos = getPosition( me->x() ).getTact() * - MidiTime::ticksPerTact(); + const MidiTime pos = getPosition( me->x() ).getBar() * + MidiTime::ticksPerBar(); TrackContentObject * tco = getTrack()->createTCO( pos ); tco->saveJournallingState( false ); @@ -1714,15 +1716,15 @@ void TrackContentWidget::mousePressEvent( QMouseEvent * me ) */ void TrackContentWidget::paintEvent( QPaintEvent * pe ) { - // Assume even-pixels-per-tact. Makes sense, should be like this anyways + // Assume even-pixels-per-bar. Makes sense, should be like this anyways const TrackContainerView * tcv = m_trackView->trackContainerView(); - int ppt = static_cast( tcv->pixelsPerTact() ); + int ppb = static_cast( tcv->pixelsPerBar() ); QPainter p( this ); // Don't draw background on BB-Editor if( m_trackView->trackContainerView() != gui->getBBEditor()->trackContainerView() ) { p.drawTiledPixmap( rect(), m_background, QPoint( - tcv->currentPosition().getTact() * ppt, 0 ) ); + tcv->currentPosition().getBar() * ppb, 0 ) ); } } @@ -1755,15 +1757,15 @@ Track * TrackContentWidget::getTrack() -/*! \brief Return the end position of the trackContentWidget in Tacts. +/*! \brief Return the end position of the trackContentWidget in Bars. * * \param posStart the starting position of the Widget (from getPosition()) */ MidiTime TrackContentWidget::endPosition( const MidiTime & posStart ) { - const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); + const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); const int w = width(); - return posStart + static_cast( w * MidiTime::ticksPerTact() / ppt ); + return posStart + static_cast( w * MidiTime::ticksPerBar() / ppb ); } @@ -2417,7 +2419,7 @@ TrackContentObject * Track::getTCO( int tcoNum ) } printf( "called Track::getTCO( %d ), " "but TCO %d doesn't exist\n", tcoNum, tcoNum ); - return createTCO( tcoNum * MidiTime::ticksPerTact() ); + return createTCO( tcoNum * MidiTime::ticksPerBar() ); } @@ -2525,17 +2527,17 @@ void Track::createTCOsForBB( int bb ) * in ascending order by TCO time, once we hit a TCO that was earlier * than the insert time, we could fall out of the loop early. */ -void Track::insertTact( const MidiTime & pos ) +void Track::insertBar( const MidiTime & pos ) { // we'll increase the position of every TCO, positioned behind pos, by - // one tact + // one bar for( tcoVector::iterator it = m_trackContentObjects.begin(); it != m_trackContentObjects.end(); ++it ) { if( ( *it )->startPosition() >= pos ) { ( *it )->movePosition( (*it)->startPosition() + - MidiTime::ticksPerTact() ); + MidiTime::ticksPerBar() ); } } } @@ -2547,17 +2549,17 @@ void Track::insertTact( const MidiTime & pos ) * * \param pos The time at which we want to remove the bar. */ -void Track::removeTact( const MidiTime & pos ) +void Track::removeBar( const MidiTime & pos ) { // we'll decrease the position of every TCO, positioned behind pos, by - // one tact + // one bar for( tcoVector::iterator it = m_trackContentObjects.begin(); it != m_trackContentObjects.end(); ++it ) { if( ( *it )->startPosition() >= pos ) { ( *it )->movePosition( qMax( ( *it )->startPosition() - - MidiTime::ticksPerTact(), 0 ) ); + MidiTime::ticksPerBar(), 0 ) ); } } } @@ -2571,7 +2573,7 @@ void Track::removeTact( const MidiTime & pos ) * keeping track of the latest time found in ticks. Then we return * that in bars by dividing by the number of ticks per bar. */ -tact_t Track::length() const +bar_t Track::length() const { // find last end-position tick_t last = 0; @@ -2591,7 +2593,7 @@ tact_t Track::length() const } } - return last / MidiTime::ticksPerTact(); + return last / MidiTime::ticksPerBar(); } diff --git a/src/core/TrackContainer.cpp b/src/core/TrackContainer.cpp index edea9aa14..95dd46f29 100644 --- a/src/core/TrackContainer.cpp +++ b/src/core/TrackContainer.cpp @@ -313,7 +313,7 @@ AutomatedValueMap TrackContainer::automatedValuesFromTracks(const TrackList &tra MidiTime bbTime = time - tco->startPosition(); bbTime = std::min(bbTime, tco->length()); - bbTime = bbTime % (bbContainer->lengthOfBB(bbIndex) * MidiTime::ticksPerTact()); + bbTime = bbTime % (bbContainer->lengthOfBB(bbIndex) * MidiTime::ticksPerBar()); auto bbValues = bbContainer->automatedValuesAt(bbTime, bbIndex); for (auto it=bbValues.begin(); it != bbValues.end(); it++) @@ -344,8 +344,3 @@ DummyTrackContainer::DummyTrackContainer() : m_dummyInstrumentTrack->setJournalling( false ); } - - - - - diff --git a/src/core/midi/MidiTime.cpp b/src/core/midi/MidiTime.cpp index 82ed642ba..4e718a1d8 100644 --- a/src/core/midi/MidiTime.cpp +++ b/src/core/midi/MidiTime.cpp @@ -53,8 +53,8 @@ int TimeSig::denominator() const -MidiTime::MidiTime( const tact_t tact, const tick_t ticks ) : - m_ticks( tact * s_ticksPerTact + ticks ) +MidiTime::MidiTime( const bar_t bar, const tick_t ticks ) : + m_ticks( bar * s_ticksPerBar + ticks ) { } @@ -66,7 +66,7 @@ MidiTime::MidiTime( const tick_t ticks ) : MidiTime MidiTime::quantize(float bars) const { //The intervals we should snap to, our new position should be a factor of this - int interval = s_ticksPerTact * bars; + int interval = s_ticksPerBar * bars; //The lower position we could snap to int lowPos = m_ticks / interval; //Offset from the lower position @@ -78,9 +78,9 @@ MidiTime MidiTime::quantize(float bars) const } -MidiTime MidiTime::toAbsoluteTact() const +MidiTime MidiTime::toAbsoluteBar() const { - return getTact() * s_ticksPerTact; + return getBar() * s_ticksPerBar; } @@ -98,15 +98,15 @@ MidiTime& MidiTime::operator-=( const MidiTime& time ) } -tact_t MidiTime::getTact() const +bar_t MidiTime::getBar() const { - return m_ticks / s_ticksPerTact; + return m_ticks / s_ticksPerBar; } -tact_t MidiTime::nextFullTact() const +bar_t MidiTime::nextFullBar() const { - return (m_ticks + (s_ticksPerTact-1)) / s_ticksPerTact; + return ( m_ticks + ( s_ticksPerBar - 1 ) ) / s_ticksPerBar; } @@ -131,23 +131,23 @@ MidiTime::operator int() const tick_t MidiTime::ticksPerBeat( const TimeSig &sig ) const { // (number of ticks per bar) divided by (number of beats per bar) - return ticksPerTact(sig) / sig.numerator(); + return ticksPerBar(sig) / sig.numerator(); } tick_t MidiTime::getTickWithinBar( const TimeSig &sig ) const { - return m_ticks % ticksPerTact(sig); + return m_ticks % ticksPerBar( sig ); } tick_t MidiTime::getBeatWithinBar( const TimeSig &sig ) const { - return getTickWithinBar(sig) / ticksPerBeat(sig); + return getTickWithinBar( sig ) / ticksPerBeat( sig ); } tick_t MidiTime::getTickWithinBeat( const TimeSig &sig ) const { - return getTickWithinBar(sig) % ticksPerBeat(sig); + return getTickWithinBar( sig ) % ticksPerBeat( sig ); } @@ -160,9 +160,9 @@ f_cnt_t MidiTime::frames( const float framesPerTick ) const return 0; } -double MidiTime::getTimeInMilliseconds(bpm_t beatsPerMinute) const +double MidiTime::getTimeInMilliseconds( bpm_t beatsPerMinute ) const { - return ticksToMilliseconds(getTicks(), beatsPerMinute); + return ticksToMilliseconds( getTicks(), beatsPerMinute ); } MidiTime MidiTime::fromFrames( const f_cnt_t frames, const float framesPerTick ) @@ -171,39 +171,39 @@ MidiTime MidiTime::fromFrames( const f_cnt_t frames, const float framesPerTick ) } -tick_t MidiTime::ticksPerTact() +tick_t MidiTime::ticksPerBar() { - return s_ticksPerTact; + return s_ticksPerBar; } -tick_t MidiTime::ticksPerTact( const TimeSig &sig ) +tick_t MidiTime::ticksPerBar( const TimeSig &sig ) { - return DefaultTicksPerTact * sig.numerator() / sig.denominator(); + return DefaultTicksPerBar * sig.numerator() / sig.denominator(); } -int MidiTime::stepsPerTact() +int MidiTime::stepsPerBar() { - int steps = ticksPerTact() / DefaultBeatsPerTact; + int steps = ticksPerBar() / DefaultBeatsPerBar; return qMax( 1, steps ); } -void MidiTime::setTicksPerTact( tick_t tpt ) +void MidiTime::setTicksPerBar( tick_t tpb ) { - s_ticksPerTact = tpt; + s_ticksPerBar = tpb; } MidiTime MidiTime::stepPosition( int step ) { - return step * ticksPerTact() / stepsPerTact(); + return step * ticksPerBar() / stepsPerBar(); } -double MidiTime::ticksToMilliseconds(tick_t ticks, bpm_t beatsPerMinute) +double MidiTime::ticksToMilliseconds( tick_t ticks, bpm_t beatsPerMinute ) { - return MidiTime::ticksToMilliseconds(static_cast(ticks), beatsPerMinute); + return MidiTime::ticksToMilliseconds( static_cast(ticks), beatsPerMinute ); } double MidiTime::ticksToMilliseconds(double ticks, bpm_t beatsPerMinute) diff --git a/src/gui/AutomationPatternView.cpp b/src/gui/AutomationPatternView.cpp index a9033f37f..130d51a0e 100644 --- a/src/gui/AutomationPatternView.cpp +++ b/src/gui/AutomationPatternView.cpp @@ -278,10 +278,10 @@ void AutomationPatternView::paintEvent( QPaintEvent * ) p.fillRect( rect(), c ); } - const float ppt = fixedTCOs() ? + const float ppb = fixedTCOs() ? ( parentWidget()->width() - 2 * TCO_BORDER_WIDTH ) - / (float) m_pat->timeMapLength().getTact() : - pixelsPerTact(); + / (float) m_pat->timeMapLength().getBar() : + pixelsPerBar(); const int x_base = TCO_BORDER_WIDTH; @@ -290,7 +290,7 @@ void AutomationPatternView::paintEvent( QPaintEvent * ) const float y_scale = max - min; const float h = ( height() - 2 * TCO_BORDER_WIDTH ) / y_scale; - const float ppTick = ppt / MidiTime::ticksPerTact(); + const float ppTick = ppb / MidiTime::ticksPerBar(); p.translate( 0.0f, max * height() / y_scale - TCO_BORDER_WIDTH ); p.scale( 1.0f, -h ); @@ -372,9 +372,9 @@ void AutomationPatternView::paintEvent( QPaintEvent * ) const int lineSize = 3; p.setPen( c.darker( 300 ) ); - for( tact_t t = 1; t < width() - TCO_BORDER_WIDTH; ++t ) + for( bar_t t = 1; t < width() - TCO_BORDER_WIDTH; ++t ) { - const int tx = x_base + static_cast( ppt * t ) - 2; + const int tx = x_base + static_cast( ppb * t ) - 2; p.drawLine( tx, TCO_BORDER_WIDTH, tx, TCO_BORDER_WIDTH + lineSize ); p.drawLine( tx, rect().bottom() - ( lineSize + TCO_BORDER_WIDTH ), tx, rect().bottom() - TCO_BORDER_WIDTH ); diff --git a/src/gui/TimeLineWidget.cpp b/src/gui/TimeLineWidget.cpp index dfa7e388f..bd196de7f 100644 --- a/src/gui/TimeLineWidget.cpp +++ b/src/gui/TimeLineWidget.cpp @@ -42,7 +42,7 @@ QPixmap * TimeLineWidget::s_posMarkerPixmap = NULL; -TimeLineWidget::TimeLineWidget( const int xoff, const int yoff, const float ppt, +TimeLineWidget::TimeLineWidget( const int xoff, const int yoff, const float ppb, Song::PlayPos & pos, const MidiTime & begin, Song::PlayModes mode, QWidget * parent ) : QWidget( parent ), @@ -61,7 +61,7 @@ TimeLineWidget::TimeLineWidget( const int xoff, const int yoff, const float ppt, m_changedPosition( true ), m_xOffset( xoff ), m_posMarkerX( 0 ), - m_ppt( ppt ), + m_ppb( ppb ), m_pos( pos ), m_begin( begin ), m_mode( mode ), @@ -71,7 +71,7 @@ TimeLineWidget::TimeLineWidget( const int xoff, const int yoff, const float ppt, m_moveXOff( 0 ) { m_loopPos[0] = 0; - m_loopPos[1] = DefaultTicksPerTact; + m_loopPos[1] = DefaultTicksPerBar; if( s_posMarkerPixmap == NULL ) { @@ -247,18 +247,18 @@ void TimeLineWidget::paintEvent( QPaintEvent * ) QColor const & barLineColor = getBarLineColor(); QColor const & barNumberColor = getBarNumberColor(); - tact_t barNumber = m_begin.getTact(); + bar_t barNumber = m_begin.getBar(); int const x = m_xOffset + s_posMarkerPixmap->width() / 2 - - ( ( static_cast( m_begin * m_ppt ) / MidiTime::ticksPerTact() ) % static_cast( m_ppt ) ); + ( ( static_cast( m_begin * m_ppb ) / MidiTime::ticksPerBar() ) % static_cast( m_ppb ) ); - for( int i = 0; x + i * m_ppt < width(); ++i ) + for( int i = 0; x + i * m_ppb < width(); ++i ) { ++barNumber; if( ( barNumber - 1 ) % qMax( 1, qRound( 1.0f / 3.0f * - MidiTime::ticksPerTact() / m_ppt ) ) == 0 ) + MidiTime::ticksPerBar() / m_ppb ) ) == 0 ) { - const int cx = x + qRound( i * m_ppt ); + const int cx = x + qRound( i * m_ppb ); p.setPen( barLineColor ); p.drawLine( cx, 5, cx, height() - 6 ); @@ -313,7 +313,7 @@ void TimeLineWidget::mousePressEvent( QMouseEvent* event ) else if( event->button() == Qt::RightButton ) { m_moveXOff = s_posMarkerPixmap->width() / 2; - const MidiTime t = m_begin + static_cast( qMax( event->x() - m_xOffset - m_moveXOff, 0 ) * MidiTime::ticksPerTact() / m_ppt ); + const MidiTime t = m_begin + static_cast( qMax( event->x() - m_xOffset - m_moveXOff, 0 ) * MidiTime::ticksPerBar() / m_ppb ); const MidiTime loopMid = ( m_loopPos[0] + m_loopPos[1] ) / 2; if( t < loopMid ) @@ -349,7 +349,7 @@ void TimeLineWidget::mousePressEvent( QMouseEvent* event ) void TimeLineWidget::mouseMoveEvent( QMouseEvent* event ) { parentWidget()->update(); // essential for widgets that this timeline had taken their mouse move event from. - const MidiTime t = m_begin + static_cast( qMax( event->x() - m_xOffset - m_moveXOff, 0 ) * MidiTime::ticksPerTact() / m_ppt ); + const MidiTime t = m_begin + static_cast( qMax( event->x() - m_xOffset - m_moveXOff, 0 ) * MidiTime::ticksPerBar() / m_ppb ); switch( m_action ) { @@ -387,10 +387,14 @@ void TimeLineWidget::mouseMoveEvent( QMouseEvent* event ) { // Note, swap 1 and 0 below and the behavior "skips" the other // marking instead of pushing it. - if( m_action == MoveLoopBegin ) - m_loopPos[0] -= MidiTime::ticksPerTact(); + if( m_action == MoveLoopBegin ) + { + m_loopPos[0] -= MidiTime::ticksPerBar(); + } else - m_loopPos[1] += MidiTime::ticksPerTact(); + { + m_loopPos[1] += MidiTime::ticksPerBar(); + } } update(); break; diff --git a/src/gui/TrackContainerView.cpp b/src/gui/TrackContainerView.cpp index bc3205730..9b51c76f2 100644 --- a/src/gui/TrackContainerView.cpp +++ b/src/gui/TrackContainerView.cpp @@ -54,7 +54,7 @@ TrackContainerView::TrackContainerView( TrackContainer * _tc ) : m_tc( _tc ), m_trackViews(), m_scrollArea( new scrollArea( this ) ), - m_ppt( DEFAULT_PIXELS_PER_TACT ), + m_ppb( DEFAULT_PIXELS_PER_BAR ), m_rubberBand( new RubberBand( m_scrollArea ) ) { m_tc->setHook( this ); @@ -305,9 +305,9 @@ bool TrackContainerView::allowRubberband() const -void TrackContainerView::setPixelsPerTact( int _ppt ) +void TrackContainerView::setPixelsPerBar( int ppb ) { - m_ppt = _ppt; + m_ppb = ppb; // tell all TrackContentWidgets to update their background tile pixmap for( trackViewList::Iterator it = m_trackViews.begin(); diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index bb00a1bd1..bf56e3039 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -92,7 +92,7 @@ AutomationEditor::AutomationEditor() : m_moveStartTick( 0 ), m_drawLastLevel( 0.0f ), m_drawLastTick( 0 ), - m_ppt( DEFAULT_PPT ), + m_ppb( DEFAULT_PPB ), m_y_delta( DEFAULT_Y_DELTA ), m_y_auto( true ), m_editMode( DRAW ), @@ -149,7 +149,7 @@ AutomationEditor::AutomationEditor() : } // add time-line - m_timeLine = new TimeLineWidget( VALUES_WIDTH, 0, m_ppt, + m_timeLine = new TimeLineWidget( VALUES_WIDTH, 0, m_ppb, Engine::getSong()->getPlayPos( Song::Mode_PlayAutomationPattern ), m_currentPosition, @@ -514,7 +514,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent ) x -= VALUES_WIDTH; // get tick in which the user clicked - int pos_ticks = x * MidiTime::ticksPerTact() / m_ppt + + int pos_ticks = x * MidiTime::ticksPerBar() / m_ppb + m_currentPosition; // get time map of current pattern @@ -531,7 +531,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent ) if( pos_ticks >= it.key() && ( it+1==time_map.end() || pos_ticks <= (it+1).key() ) && - ( pos_ticks<= it.key() + MidiTime::ticksPerTact() *4 / m_ppt ) && + ( pos_ticks<= it.key() + MidiTime::ticksPerBar() *4 / m_ppb ) && ( level == it.value() || mouseEvent->button() == Qt::RightButton ) ) { break; @@ -583,7 +583,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent ) int aligned_x = (int)( (float)( ( it.key() - m_currentPosition ) * - m_ppt ) / MidiTime::ticksPerTact() ); + m_ppb ) / MidiTime::ticksPerBar() ); m_moveXOffset = x - aligned_x - 1; // set move-cursor QCursor c( Qt::SizeAllCursor ); @@ -740,7 +740,7 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent ) x -= m_moveXOffset; } - int pos_ticks = x * MidiTime::ticksPerTact() / m_ppt + + int pos_ticks = x * MidiTime::ticksPerBar() / m_ppb + m_currentPosition; if( mouseEvent->buttons() & Qt::LeftButton && m_editMode == DRAW ) { @@ -872,7 +872,7 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent ) } // get tick in which the cursor is posated - int pos_ticks = x * MidiTime::ticksPerTact() / m_ppt + + int pos_ticks = x * MidiTime::ticksPerBar() / m_ppb + m_currentPosition; m_selectedTick = pos_ticks - m_selectStartTick; @@ -893,7 +893,7 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent ) // move selection + selected values // do horizontal move-stuff - int pos_ticks = x * MidiTime::ticksPerTact() / m_ppt + + int pos_ticks = x * MidiTime::ticksPerBar() / m_ppb + m_currentPosition; int ticks_diff = pos_ticks - m_moveStartTick; @@ -918,8 +918,8 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent ) } m_selectStartTick += ticks_diff; - int tact_diff = ticks_diff / MidiTime::ticksPerTact(); - ticks_diff = ticks_diff % MidiTime::ticksPerTact(); + int bar_diff = ticks_diff / MidiTime::ticksPerBar(); + ticks_diff = ticks_diff % MidiTime::ticksPerBar(); // do vertical move-stuff @@ -967,24 +967,24 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent ) MidiTime new_value_pos; if( it.key() ) { - int value_tact = + int value_bar = ( it.key() / - MidiTime::ticksPerTact() ) - + tact_diff; + MidiTime::ticksPerBar() ) + + bar_diff; int value_ticks = ( it.key() % - MidiTime::ticksPerTact() ) + MidiTime::ticksPerBar() ) + ticks_diff; // ensure value_ticks range - if( value_ticks / MidiTime::ticksPerTact() ) + if( value_ticks / MidiTime::ticksPerBar() ) { - value_tact += value_ticks - / MidiTime::ticksPerTact(); + value_bar += value_ticks + / MidiTime::ticksPerBar(); value_ticks %= - MidiTime::ticksPerTact(); + MidiTime::ticksPerBar(); } m_pattern->removeValue( it.key() ); - new_value_pos = MidiTime( value_tact, + new_value_pos = MidiTime( value_bar, value_ticks ); } new_selValuesForMove[ @@ -1032,7 +1032,7 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent ) } // get tick in which the cursor is posated - int pos_ticks = x * MidiTime::ticksPerTact() / m_ppt + + int pos_ticks = x * MidiTime::ticksPerBar() / m_ppb + m_currentPosition; m_selectedTick = pos_ticks - @@ -1116,7 +1116,7 @@ inline void AutomationEditor::drawAutomationPoint( QPainter & p, timeMap::iterat { int x = xCoordOfTick( it.key() ); int y = yCoordOfLevel( it.value() ); - const int outerRadius = qBound( 3, ( m_ppt * AutomationPattern::quantization() ) / 576, 5 ); // man, getting this calculation right took forever + const int outerRadius = qBound( 3, ( m_ppb * AutomationPattern::quantization() ) / 576, 5 ); // man, getting this calculation right took forever p.setPen( QPen( vertexColor().lighter( 200 ) ) ); p.setBrush( QBrush( vertexColor() ) ); p.drawEllipse( x - outerRadius, y - outerRadius, outerRadius * 2, outerRadius * 2 ); @@ -1288,20 +1288,20 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) / static_cast( Engine::getSong()->getTimeSigModel().getDenominator() ); float zoomFactor = m_zoomXLevels[m_zoomingXModel.value()]; //the bars which disappears at the left side by scrolling - int leftBars = m_currentPosition * zoomFactor / MidiTime::ticksPerTact(); + int leftBars = m_currentPosition * zoomFactor / MidiTime::ticksPerBar(); //iterates the visible bars and draw the shading on uneven bars - for( int x = VALUES_WIDTH, barCount = leftBars; x < width() + m_currentPosition * zoomFactor / timeSignature; x += m_ppt, ++barCount ) + for( int x = VALUES_WIDTH, barCount = leftBars; x < width() + m_currentPosition * zoomFactor / timeSignature; x += m_ppb, ++barCount ) { if( ( barCount + leftBars ) % 2 != 0 ) { - p.fillRect( x - m_currentPosition * zoomFactor / timeSignature, TOP_MARGIN, m_ppt, + p.fillRect( x - m_currentPosition * zoomFactor / timeSignature, TOP_MARGIN, m_ppb, height() - ( SCROLLBAR_SIZE + TOP_MARGIN ), backgroundShade() ); } } // Draw the beat grid - int ticksPerBeat = DefaultTicksPerTact / + int ticksPerBeat = DefaultTicksPerBar / Engine::getSong()->getTimeSigModel().getDenominator(); for( tick = m_currentPosition - m_currentPosition % ticksPerBeat, @@ -1314,10 +1314,10 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) } // and finally bars - for( tick = m_currentPosition - m_currentPosition % MidiTime::ticksPerTact(), + for( tick = m_currentPosition - m_currentPosition % MidiTime::ticksPerBar(), x = xCoordOfTick( tick ); x<=width(); - tick += MidiTime::ticksPerTact(), x = xCoordOfTick( tick ) ) + tick += MidiTime::ticksPerBar(), x = xCoordOfTick( tick ) ) { p.setPen( barLineColor() ); p.drawLine( x, grid_bottom, x, x_line_end ); @@ -1452,9 +1452,9 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) } // now draw selection-frame - int x = ( sel_pos_start - m_currentPosition ) * m_ppt / - MidiTime::ticksPerTact(); - int w = ( sel_pos_end - sel_pos_start ) * m_ppt / MidiTime::ticksPerTact(); + int x = ( sel_pos_start - m_currentPosition ) * m_ppb / + MidiTime::ticksPerBar(); + int w = ( sel_pos_end - sel_pos_start ) * m_ppb / MidiTime::ticksPerBar(); int y, h; if( m_y_auto ) { @@ -1526,7 +1526,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) int AutomationEditor::xCoordOfTick(int tick ) { return VALUES_WIDTH + ( ( tick - m_currentPosition ) - * m_ppt / MidiTime::ticksPerTact() ); + * m_ppb / MidiTime::ticksPerBar() ); } @@ -1687,11 +1687,11 @@ void AutomationEditor::wheelEvent(QWheelEvent * we ) } x = qBound( 0, x, m_zoomingXModel.size() - 1 ); - int mouseX = (we->x() - VALUES_WIDTH)* MidiTime::ticksPerTact(); + int mouseX = (we->x() - VALUES_WIDTH)* MidiTime::ticksPerBar(); // ticks based on the mouse x-position where the scroll wheel was used - int ticks = mouseX / m_ppt; + int ticks = mouseX / m_ppb; // what would be the ticks in the new zoom level on the very same mouse x - int newTicks = mouseX / (DEFAULT_PPT * m_zoomXLevels[x]); + int newTicks = mouseX / (DEFAULT_PPB * m_zoomXLevels[x]); // scroll so the tick "selected" by the mouse x doesn't move on the screen m_leftRightScroll->setValue(m_leftRightScroll->value() + ticks - newTicks); @@ -1958,7 +1958,7 @@ void AutomationEditor::getSelectedValues( timeMap & selected_values ) ++it ) { //TODO: Add constant - tick_t len_ticks = MidiTime::ticksPerTact() / 16; + tick_t len_ticks = MidiTime::ticksPerBar() / 16; float level = it.value(); tick_t pos_ticks = it.key(); @@ -2095,17 +2095,17 @@ void AutomationEditor::updatePosition(const MidiTime & t ) m_scrollBack == true ) { const int w = width() - VALUES_WIDTH; - if( t > m_currentPosition + w * MidiTime::ticksPerTact() / m_ppt ) + if( t > m_currentPosition + w * MidiTime::ticksPerBar() / m_ppb ) { - m_leftRightScroll->setValue( t.getTact() * - MidiTime::ticksPerTact() ); + m_leftRightScroll->setValue( t.getBar() * + MidiTime::ticksPerBar() ); } else if( t < m_currentPosition ) { - MidiTime t_ = qMax( t - w * MidiTime::ticksPerTact() * - MidiTime::ticksPerTact() / m_ppt, 0 ); - m_leftRightScroll->setValue( t_.getTact() * - MidiTime::ticksPerTact() ); + MidiTime t_ = qMax( t - w * MidiTime::ticksPerBar() * + MidiTime::ticksPerBar() / m_ppb, 0 ); + m_leftRightScroll->setValue( t_.getBar() * + MidiTime::ticksPerBar() ); } m_scrollBack = false; } @@ -2116,11 +2116,11 @@ void AutomationEditor::updatePosition(const MidiTime & t ) void AutomationEditor::zoomingXChanged() { - m_ppt = m_zoomXLevels[m_zoomingXModel.value()] * DEFAULT_PPT; + m_ppb = m_zoomXLevels[m_zoomingXModel.value()] * DEFAULT_PPB; - assert( m_ppt > 0 ); + assert( m_ppb > 0 ); - m_timeLine->setPixelsPerTact( m_ppt ); + m_timeLine->setPixelsPerBar( m_ppb ); update(); } @@ -2159,9 +2159,9 @@ void AutomationEditor::setQuantization() } else { - quantization = DefaultTicksPerTact; + quantization = DefaultTicksPerBar; } - quantization = DefaultTicksPerTact / quantization; + quantization = DefaultTicksPerBar / quantization; AutomationPattern::setQuantization( quantization ); update(); diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 5d11088f3..183735450 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -139,7 +139,7 @@ PianoRoll::PianoRollKeyTypes PianoRoll::prKeyOrder[] = } ; -const int DEFAULT_PR_PPT = KEY_LINE_HEIGHT * DefaultStepsPerTact; +const int DEFAULT_PR_PPB = KEY_LINE_HEIGHT * DefaultStepsPerBar; const QVector PianoRoll::m_zoomLevels = { 0.125f, 0.25f, 0.5f, 1.0f, 2.0f, 4.0f, 8.0f }; @@ -168,8 +168,8 @@ PianoRoll::PianoRoll() : m_lastMouseY( 0 ), m_oldNotesEditHeight( 100 ), m_notesEditHeight( 100 ), - m_ppt( DEFAULT_PR_PPT ), - m_lenOfNewNotes( MidiTime( 0, DefaultTicksPerTact/4 ) ), + m_ppb( DEFAULT_PR_PPB ), + m_lenOfNewNotes( MidiTime( 0, DefaultTicksPerBar/4 ) ), m_lastNoteVolume( DefaultVolume ), m_lastNotePanning( DefaultPanning ), m_startKey( INITIAL_START_KEY ), @@ -178,7 +178,7 @@ 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_stepRecorderWidget(this, DEFAULT_PR_PPB, 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 ), @@ -302,7 +302,7 @@ PianoRoll::PianoRoll() : setAttribute( Qt::WA_OpaquePaintEvent, true ); // add time-line - m_timeLine = new TimeLineWidget( WHITE_KEY_WIDTH, 0, m_ppt, + m_timeLine = new TimeLineWidget( WHITE_KEY_WIDTH, 0, m_ppb, Engine::getSong()->getPlayPos( Song::Mode_PlayPattern ), m_currentPosition, @@ -759,28 +759,28 @@ void PianoRoll::selectRegionFromPixels( int xStart, int xEnd ) xEnd -= WHITE_KEY_WIDTH; // select an area of notes - int pos_ticks = xStart * MidiTime::ticksPerTact() / m_ppt + + int posTicks = xStart * MidiTime::ticksPerBar() / m_ppb + m_currentPosition; - int key_num = 0; - m_selectStartTick = pos_ticks; + int keyNum = 0; + m_selectStartTick = posTicks; m_selectedTick = 0; - m_selectStartKey = key_num; + m_selectStartKey = keyNum; m_selectedKeys = 1; // change size of selection // get tick in which the cursor is posated - pos_ticks = xEnd * MidiTime::ticksPerTact() / m_ppt + + posTicks = xEnd * MidiTime::ticksPerBar() / m_ppb + m_currentPosition; - key_num = 120; + keyNum = 120; - m_selectedTick = pos_ticks - m_selectStartTick; + m_selectedTick = posTicks - m_selectStartTick; if( (int) m_selectStartTick + m_selectedTick < 0 ) { m_selectedTick = -static_cast( m_selectStartTick ); } - m_selectedKeys = key_num - m_selectStartKey; - if( key_num <= m_selectStartKey ) + m_selectedKeys = keyNum - m_selectStartKey; + if( keyNum <= m_selectStartKey ) { --m_selectedKeys; } @@ -1033,7 +1033,7 @@ void PianoRoll::drawDetuningInfo( QPainter & _p, const Note * _n, int _x, for( timeMap::ConstIterator it = map.begin(); it != map.end(); ++it ) { int pos_ticks = it.key(); - int pos_x = _x + pos_ticks * m_ppt / MidiTime::ticksPerTact(); + int pos_x = _x + pos_ticks * m_ppb / MidiTime::ticksPerBar(); const float level = it.value(); @@ -1268,7 +1268,7 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke) // Move selected notes by one bar to the left if (hasValidPattern()) { - shiftPos( direction * MidiTime::ticksPerTact() ); + shiftPos( direction * MidiTime::ticksPerBar() ); } } else if( ke->modifiers() & Qt::ShiftModifier && m_action == ActionNone) @@ -1572,7 +1572,7 @@ void PianoRoll::mousePressEvent(QMouseEvent * me ) x -= WHITE_KEY_WIDTH; // get tick in which the user clicked - int pos_ticks = x * MidiTime::ticksPerTact() / m_ppt + + int pos_ticks = x * MidiTime::ticksPerBar() / m_ppb + m_currentPosition; @@ -1602,7 +1602,7 @@ void PianoRoll::mousePressEvent(QMouseEvent * me ) || ( edit_note && pos_ticks <= note->pos() + - NOTE_EDIT_LINE_WIDTH * MidiTime::ticksPerTact() / m_ppt ) + NOTE_EDIT_LINE_WIDTH * MidiTime::ticksPerBar() / m_ppb ) ) ) { @@ -1746,8 +1746,8 @@ void PianoRoll::mousePressEvent(QMouseEvent * me ) // clicked at the "tail" of the note? - if( pos_ticks * m_ppt / MidiTime::ticksPerTact() > - m_currentNote->endPos() * m_ppt / MidiTime::ticksPerTact() - RESIZE_AREA_WIDTH + if( pos_ticks * m_ppb / MidiTime::ticksPerBar() > + m_currentNote->endPos() * m_ppb / MidiTime::ticksPerBar() - RESIZE_AREA_WIDTH && m_currentNote->length() > 0 ) { m_pattern->addJournalCheckPoint(); @@ -1902,10 +1902,10 @@ void PianoRoll::mouseDoubleClickEvent(QMouseEvent * me ) int pixel_range = 4; int x = me->x() - WHITE_KEY_WIDTH; const int ticks_start = ( x-pixel_range/2 ) * - MidiTime::ticksPerTact() / m_ppt + m_currentPosition; + MidiTime::ticksPerBar() / m_ppb + m_currentPosition; const int ticks_end = ( x+pixel_range/2 ) * - MidiTime::ticksPerTact() / m_ppt + m_currentPosition; - const int ticks_middle = x * MidiTime::ticksPerTact() / m_ppt + m_currentPosition; + MidiTime::ticksPerBar() / m_ppb + m_currentPosition; + const int ticks_middle = x * MidiTime::ticksPerBar() / m_ppb + m_currentPosition; // go through notes to figure out which one we want to change bool altPressed = me->modifiers() & Qt::AltModifier; @@ -2300,9 +2300,9 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) // convert to ticks so that we can check which notes // are in the range int ticks_start = ( x-pixel_range/2 ) * - MidiTime::ticksPerTact() / m_ppt + m_currentPosition; + MidiTime::ticksPerBar() / m_ppb + m_currentPosition; int ticks_end = ( x+pixel_range/2 ) * - MidiTime::ticksPerTact() / m_ppt + m_currentPosition; + MidiTime::ticksPerBar() / m_ppb + m_currentPosition; // get note-vector of current pattern const NoteVector & notes = m_pattern->notes(); @@ -2398,8 +2398,8 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) // set move- or resize-cursor // get tick in which the cursor is posated - int pos_ticks = ( x * MidiTime::ticksPerTact() ) / - m_ppt + m_currentPosition; + int pos_ticks = ( x * MidiTime::ticksPerBar() ) / + m_ppb + m_currentPosition; // get note-vector of current pattern const NoteVector & notes = m_pattern->notes(); @@ -2431,7 +2431,7 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) Note *note = *it; // x coordinate of the right edge of the note int noteRightX = ( note->pos() + note->length() - - m_currentPosition) * m_ppt/MidiTime::ticksPerTact(); + m_currentPosition) * m_ppb/MidiTime::ticksPerBar(); // cursor at the "tail" of the note? bool atTail = note->length() > 0 && x > noteRightX - RESIZE_AREA_WIDTH; @@ -2470,7 +2470,7 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) // change size of selection // get tick in which the cursor is posated - int pos_ticks = x * MidiTime::ticksPerTact() / m_ppt + + int pos_ticks = x * MidiTime::ticksPerBar() / m_ppb + m_currentPosition; m_selectedTick = pos_ticks - m_selectStartTick; @@ -2492,7 +2492,7 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) // any key if in erase mode // get tick in which the user clicked - int pos_ticks = x * MidiTime::ticksPerTact() / m_ppt + + int pos_ticks = x * MidiTime::ticksPerBar() / m_ppb + m_currentPosition; @@ -2523,8 +2523,8 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) ( edit_note && pos_ticks <= note->pos() + NOTE_EDIT_LINE_WIDTH * - MidiTime::ticksPerTact() / - m_ppt ) + MidiTime::ticksPerBar() / + m_ppb ) ) ) { @@ -2573,7 +2573,7 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) } // get tick in which the cursor is posated - int pos_ticks = x * MidiTime::ticksPerTact()/ m_ppt + + int pos_ticks = x * MidiTime::ticksPerBar()/ m_ppb + m_currentPosition; m_selectedTick = pos_ticks - @@ -2634,7 +2634,7 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl ) // convert pixels to ticks and keys int off_x = x - m_moveStartX; - int off_ticks = off_x * MidiTime::ticksPerTact() / m_ppt; + int off_ticks = off_x * MidiTime::ticksPerBar() / m_ppb; int off_key = getKey( y ) - getKey( m_moveStartY ); // handle scroll changes while dragging @@ -2818,10 +2818,10 @@ void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl ) Engine::getSong()->setModified(); } -int PianoRoll::xCoordOfTick(int tick ) +int PianoRoll::xCoordOfTick( int tick ) { return WHITE_KEY_WIDTH + ( ( tick - m_currentPosition ) - * m_ppt / MidiTime::ticksPerTact() ); + * m_ppb / MidiTime::ticksPerBar() ); } void PianoRoll::paintEvent(QPaintEvent * pe ) @@ -3118,20 +3118,20 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) / static_cast( Engine::getSong()->getTimeSigModel().getDenominator() ); float zoomFactor = m_zoomLevels[m_zoomingModel.value()]; //the bars which disappears at the left side by scrolling - int leftBars = m_currentPosition * zoomFactor / MidiTime::ticksPerTact(); + int leftBars = m_currentPosition * zoomFactor / MidiTime::ticksPerBar(); //iterates the visible bars and draw the shading on uneven bars - for( int x = WHITE_KEY_WIDTH, barCount = leftBars; x < width() + m_currentPosition * zoomFactor / timeSignature; x += m_ppt, ++barCount ) + for( int x = WHITE_KEY_WIDTH, barCount = leftBars; x < width() + m_currentPosition * zoomFactor / timeSignature; x += m_ppb, ++barCount ) { if( ( barCount + leftBars ) % 2 != 0 ) { - p.fillRect( x - m_currentPosition * zoomFactor / timeSignature, PR_TOP_MARGIN, m_ppt, + p.fillRect( x - m_currentPosition * zoomFactor / timeSignature, PR_TOP_MARGIN, m_ppb, height() - ( PR_BOTTOM_MARGIN + PR_TOP_MARGIN ), backgroundShade() ); } } // Draw the vertical beat lines - int ticksPerBeat = DefaultTicksPerTact / + int ticksPerBeat = DefaultTicksPerBar / Engine::getSong()->getTimeSigModel().getDenominator(); for( tick = m_currentPosition - m_currentPosition % ticksPerBeat, @@ -3143,9 +3143,9 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) } // Draw the vertical bar lines - for( tick = m_currentPosition - m_currentPosition % MidiTime::ticksPerTact(), + for( tick = m_currentPosition - m_currentPosition % MidiTime::ticksPerBar(), x = xCoordOfTick( tick ); x <= width(); - tick += MidiTime::ticksPerTact(), x = xCoordOfTick( tick ) ) + tick += MidiTime::ticksPerBar(), x = xCoordOfTick( tick ) ) { p.setPen( barLineColor() ); p.drawLine( x, PR_TOP_MARGIN, x, height() - PR_BOTTOM_MARGIN ); @@ -3217,9 +3217,9 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) int pos_ticks = note->pos(); - int note_width = len_ticks * m_ppt / MidiTime::ticksPerTact(); + int note_width = len_ticks * m_ppb / MidiTime::ticksPerBar(); const int x = ( pos_ticks - m_currentPosition ) * - m_ppt / MidiTime::ticksPerTact(); + m_ppb / MidiTime::ticksPerBar(); // skip this note if not in visible area at all if( !( x + note_width >= 0 && x <= width() - WHITE_KEY_WIDTH ) ) { @@ -3259,9 +3259,9 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) int pos_ticks = note->pos(); - int note_width = len_ticks * m_ppt / MidiTime::ticksPerTact(); + int note_width = len_ticks * m_ppb / MidiTime::ticksPerBar(); const int x = ( pos_ticks - m_currentPosition ) * - m_ppt / MidiTime::ticksPerTact(); + m_ppb / MidiTime::ticksPerBar(); // skip this note if not in visible area at all if( !( x + note_width >= 0 && x <= width() - WHITE_KEY_WIDTH ) ) { @@ -3347,9 +3347,9 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) int pos_ticks = note->pos(); - int note_width = len_ticks * m_ppt / MidiTime::ticksPerTact(); + int note_width = len_ticks * m_ppb / MidiTime::ticksPerBar(); const int x = ( pos_ticks - m_currentPosition ) * - m_ppt / MidiTime::ticksPerTact(); + m_ppb / MidiTime::ticksPerBar(); // skip this note if not in visible area at all if( !( x + note_width >= 0 && x <= width() - WHITE_KEY_WIDTH ) ) { @@ -3389,10 +3389,10 @@ void PianoRoll::paintEvent(QPaintEvent * pe ) m_notesEditHeight - PR_BOTTOM_MARGIN ); // now draw selection-frame - int x = ( ( sel_pos_start - m_currentPosition ) * m_ppt ) / - MidiTime::ticksPerTact(); - int w = ( ( ( sel_pos_end - m_currentPosition ) * m_ppt ) / - MidiTime::ticksPerTact() ) - x; + int x = ( ( sel_pos_start - m_currentPosition ) * m_ppb ) / + MidiTime::ticksPerBar(); + int w = ( ( ( sel_pos_end - m_currentPosition ) * m_ppb ) / + MidiTime::ticksPerBar() ) - x; int y = (int) y_base - sel_key_start * KEY_LINE_HEIGHT; int h = (int) y_base - sel_key_end * KEY_LINE_HEIGHT - y; p.setPen( selectedNoteColor() ); @@ -3508,9 +3508,9 @@ void PianoRoll::wheelEvent(QWheelEvent * we ) int pixel_range = 8; int x = we->x() - WHITE_KEY_WIDTH; int ticks_start = ( x - pixel_range / 2 ) * - MidiTime::ticksPerTact() / m_ppt + m_currentPosition; + MidiTime::ticksPerBar() / m_ppb + m_currentPosition; int ticks_end = ( x + pixel_range / 2 ) * - MidiTime::ticksPerTact() / m_ppt + m_currentPosition; + MidiTime::ticksPerBar() / m_ppb + m_currentPosition; // When alt is pressed we only edit the note under the cursor bool altPressed = we->modifiers() & Qt::AltModifier; @@ -3611,11 +3611,11 @@ void PianoRoll::wheelEvent(QWheelEvent * we ) } z = qBound( 0, z, m_zoomingModel.size() - 1 ); - int x = (we->x() - WHITE_KEY_WIDTH)* MidiTime::ticksPerTact(); + int x = (we->x() - WHITE_KEY_WIDTH)* MidiTime::ticksPerBar(); // ticks based on the mouse x-position where the scroll wheel was used - int ticks = x / m_ppt; + int ticks = x / m_ppb; // what would be the ticks in the new zoom level on the very same mouse x - int newTicks = x / (DEFAULT_PR_PPT * m_zoomLevels[z]); + int newTicks = x / (DEFAULT_PR_PPB * m_zoomLevels[z]); // scroll so the tick "selected" by the mouse x doesn't move on the screen m_leftRightScroll->setValue(m_leftRightScroll->value() + ticks - newTicks); // update combobox with zooming-factor @@ -4039,7 +4039,7 @@ void PianoRoll::copyToClipboard( const NoteVector & notes ) const QDomElement note_list = dataFile.createElement( "note-list" ); dataFile.content().appendChild( note_list ); - MidiTime start_pos( notes.front()->pos().getTact(), 0 ); + MidiTime start_pos( notes.front()->pos().getBar(), 0 ); for( const Note *note : notes ) { Note clip_note( *note ); @@ -4200,15 +4200,15 @@ void PianoRoll::deleteSelectedNotes() void PianoRoll::autoScroll( const MidiTime & t ) { const int w = width() - WHITE_KEY_WIDTH; - if( t > m_currentPosition + w * MidiTime::ticksPerTact() / m_ppt ) + if( t > m_currentPosition + w * MidiTime::ticksPerBar() / m_ppb ) { - m_leftRightScroll->setValue( t.getTact() * MidiTime::ticksPerTact() ); + m_leftRightScroll->setValue( t.getBar() * MidiTime::ticksPerBar() ); } else if( t < m_currentPosition ) { - MidiTime t2 = qMax( t - w * MidiTime::ticksPerTact() * - MidiTime::ticksPerTact() / m_ppt, (tick_t) 0 ); - m_leftRightScroll->setValue( t2.getTact() * MidiTime::ticksPerTact() ); + MidiTime t2 = qMax( t - w * MidiTime::ticksPerBar() * + MidiTime::ticksPerBar() / m_ppb, (tick_t) 0 ); + m_leftRightScroll->setValue( t2.getBar() * MidiTime::ticksPerBar() ); } m_scrollBack = false; } @@ -4262,12 +4262,12 @@ void PianoRoll::updatePositionStepRecording( const MidiTime & t ) void PianoRoll::zoomingChanged() { - m_ppt = m_zoomLevels[m_zoomingModel.value()] * DEFAULT_PR_PPT; + m_ppb = m_zoomLevels[m_zoomingModel.value()] * DEFAULT_PR_PPB; - assert( m_ppt > 0 ); + assert( m_ppb > 0 ); - m_timeLine->setPixelsPerTact( m_ppt ); - m_stepRecorderWidget.setPixelsPerTact( m_ppt ); + m_timeLine->setPixelsPerBar( m_ppb ); + m_stepRecorderWidget.setPixelsPerBar( m_ppb ); update(); } @@ -4297,12 +4297,12 @@ int PianoRoll::quantization() const } else { - return DefaultTicksPerTact / 16; + return DefaultTicksPerBar / 16; } } QString text = m_quantizeModel.currentText(); - return DefaultTicksPerTact / text.right( text.length() - 2 ).toInt(); + return DefaultTicksPerBar / text.right( text.length() - 2 ).toInt(); } @@ -4370,7 +4370,7 @@ MidiTime PianoRoll::newNoteLen() const } QString text = m_noteLenModel.currentText(); - return DefaultTicksPerTact / text.right( text.length() - 2 ).toInt(); + return DefaultTicksPerBar / text.right( text.length() - 2 ).toInt(); } @@ -4398,7 +4398,7 @@ Note * PianoRoll::noteUnderMouse() int key_num = getKey( pos.y() ); int pos_ticks = ( pos.x() - WHITE_KEY_WIDTH ) * - MidiTime::ticksPerTact() / m_ppt + m_currentPosition; + MidiTime::ticksPerBar() / m_ppb + m_currentPosition; // loop through whole note-vector... for( Note* const& note : m_pattern->notes() ) diff --git a/src/gui/editors/SongEditor.cpp b/src/gui/editors/SongEditor.cpp index a077840d0..2c2485d00 100644 --- a/src/gui/editors/SongEditor.cpp +++ b/src/gui/editors/SongEditor.cpp @@ -95,7 +95,7 @@ SongEditor::SongEditor( Song * song ) : m_zoomingModel->setParent(this); m_snappingModel->setParent(this); m_timeLine = new TimeLineWidget( m_trackHeadWidth, 32, - pixelsPerTact(), + pixelsPerBar(), m_song->m_playPos[Song::Mode_PlaySong], m_currentPosition, Song::Mode_PlaySong, this ); @@ -374,7 +374,7 @@ void SongEditor::selectRegionFromPixels(int xStart, int xEnd) //calculate the song position where the mouse was clicked m_rubberbandStartMidipos = MidiTime((xStart - m_trackHeadWidth) - / pixelsPerTact() * MidiTime::ticksPerTact()) + / pixelsPerBar() * MidiTime::ticksPerBar()) + m_currentPosition; m_rubberBandStartTrackview = 0; } @@ -409,7 +409,7 @@ void SongEditor::updateRubberband() } //take care of the scrollbar position - int hs = (m_leftRightScroll->value() - m_scrollPos.x()) * pixelsPerTact(); + int hs = (m_leftRightScroll->value() - m_scrollPos.x()) * pixelsPerBar(); int vs = contentWidget()->verticalScrollBar()->value() - m_scrollPos.y(); //the adjusted origin point @@ -425,7 +425,7 @@ void SongEditor::updateRubberband() //the miditime the mouse is hover MidiTime rubberbandMidipos = MidiTime((qMin(m_mousePos.x(), width()) - m_trackHeadWidth) - / pixelsPerTact() * MidiTime::ticksPerTact()) + / pixelsPerBar() * MidiTime::ticksPerBar()) + m_currentPosition; //are tcos in the rect of selection? @@ -485,7 +485,7 @@ void SongEditor::keyPressEvent( QKeyEvent * ke ) } else if( ke->key() == Qt::Key_Left ) { - tick_t t = m_song->currentTick() - MidiTime::ticksPerTact(); + tick_t t = m_song->currentTick() - MidiTime::ticksPerBar(); if( t >= 0 ) { m_song->setPlayPos( t, Song::Mode_PlaySong ); @@ -493,7 +493,7 @@ void SongEditor::keyPressEvent( QKeyEvent * ke ) } else if( ke->key() == Qt::Key_Right ) { - tick_t t = m_song->currentTick() + MidiTime::ticksPerTact(); + tick_t t = m_song->currentTick() + MidiTime::ticksPerBar(); if( t < MaxSongLength ) { m_song->setPlayPos( t, Song::Mode_PlaySong ); @@ -549,20 +549,20 @@ void SongEditor::wheelEvent( QWheelEvent * we ) z = qBound( 0, z, m_zoomingModel->size() - 1 ); - int x = (we->x() - m_trackHeadWidth); - // tact based on the mouse x-position where the scroll wheel was used - int tact= x / pixelsPerTact(); - // what would be the tact in the new zoom level on the very same mouse x - int newTact = x / DEFAULT_PIXELS_PER_TACT / m_zoomLevels[z]; - // scroll so the tact "selected" by the mouse x doesn't move on the screen - m_leftRightScroll->setValue(m_leftRightScroll->value() + tact - newTact); + int x = we->x() - m_trackHeadWidth; + // bar based on the mouse x-position where the scroll wheel was used + int bar = x / pixelsPerBar(); + // what would be the bar in the new zoom level on the very same mouse x + int newBar = x / DEFAULT_PIXELS_PER_BAR / m_zoomLevels[z]; + // scroll so the bar "selected" by the mouse x doesn't move on the screen + m_leftRightScroll->setValue(m_leftRightScroll->value() + bar - newBar); // update combobox with zooming-factor m_zoomingModel->setValue( z ); // update timeline m_song->m_playPos[Song::Mode_PlaySong].m_timeLine-> - setPixelsPerTact( pixelsPerTact() ); + setPixelsPerBar( pixelsPerBar() ); // and make sure, all TCO's are resized and relocated realignTracks(); } @@ -614,7 +614,7 @@ void SongEditor::mousePressEvent(QMouseEvent *me) //the trackView(index) and the miditime where the mouse was clicked m_rubberBandStartTrackview = trackIndexFromSelectionPoint(me->y()); m_rubberbandStartMidipos = MidiTime((me->x() - m_trackHeadWidth) - / pixelsPerTact() * MidiTime::ticksPerTact()) + / pixelsPerBar() * MidiTime::ticksPerBar()) + m_currentPosition; } QWidget::mousePressEvent(me); @@ -791,14 +791,14 @@ void SongEditor::updatePosition( const MidiTime & t ) const int w = width() - widgetWidth - trackOpWidth - contentWidget()->verticalScrollBar()->width(); // width of right scrollbar - if( t > m_currentPosition + w * MidiTime::ticksPerTact() / - pixelsPerTact() ) + if( t > m_currentPosition + w * MidiTime::ticksPerBar() / + pixelsPerBar() ) { - animateScroll( m_leftRightScroll, t.getTact(), m_smoothScroll ); + animateScroll( m_leftRightScroll, t.getBar(), m_smoothScroll ); } else if( t < m_currentPosition ) { - animateScroll( m_leftRightScroll, t.getTact(), m_smoothScroll ); + animateScroll( m_leftRightScroll, t.getBar(), m_smoothScroll ); } m_scrollBack = false; } @@ -831,10 +831,10 @@ void SongEditor::updatePositionLine() void SongEditor::zoomingChanged() { - setPixelsPerTact( m_zoomLevels[m_zoomingModel->value()] * DEFAULT_PIXELS_PER_TACT ); + setPixelsPerBar( m_zoomLevels[m_zoomingModel->value()] * DEFAULT_PIXELS_PER_BAR ); m_song->m_playPos[Song::Mode_PlaySong].m_timeLine-> - setPixelsPerTact( pixelsPerTact() ); + setPixelsPerBar( pixelsPerBar() ); realignTracks(); updateRubberband(); } diff --git a/src/gui/widgets/StepRecorderWidget.cpp b/src/gui/widgets/StepRecorderWidget.cpp index f59e235fc..a546c2a2c 100644 --- a/src/gui/widgets/StepRecorderWidget.cpp +++ b/src/gui/widgets/StepRecorderWidget.cpp @@ -26,7 +26,7 @@ StepRecorderWidget::StepRecorderWidget( QWidget * parent, - const int ppt, + const int ppb, const int marginTop, const int marginBottom, const int marginLeft, @@ -42,15 +42,15 @@ StepRecorderWidget::StepRecorderWidget( m_colorLineStart = baseColor.darker(120); setAttribute(Qt::WA_NoSystemBackground, true); - setPixelsPerTact(ppt); + setPixelsPerBar(ppb); m_top = m_marginTop; m_left = m_marginLeft; } -void StepRecorderWidget::setPixelsPerTact(int ppt) +void StepRecorderWidget::setPixelsPerBar(int ppb) { - m_ppt = ppt; + m_ppb = ppb; } void StepRecorderWidget::setCurrentPosition(MidiTime currentPosition) @@ -125,7 +125,7 @@ void StepRecorderWidget::paintEvent(QPaintEvent * pe) int StepRecorderWidget::xCoordOfTick(int tick) { - return m_marginLeft + ((tick - m_currentPosition) * m_ppt / MidiTime::ticksPerTact()); + return m_marginLeft + ((tick - m_currentPosition) * m_ppb / MidiTime::ticksPerBar()); } diff --git a/src/gui/widgets/TimeDisplayWidget.cpp b/src/gui/widgets/TimeDisplayWidget.cpp index e9a831193..01604a9dc 100644 --- a/src/gui/widgets/TimeDisplayWidget.cpp +++ b/src/gui/widgets/TimeDisplayWidget.cpp @@ -100,11 +100,11 @@ void TimeDisplayWidget::updateTime() case BarsTicks: int tick; tick = s->getPlayPos().getTicks(); - m_majorLCD.setValue((int)(tick / s->ticksPerTact()) + 1); - m_minorLCD.setValue((tick % s->ticksPerTact()) / - (s->ticksPerTact() / s->getTimeSigModel().getNumerator() ) +1); - m_milliSecondsLCD.setValue((tick % s->ticksPerTact()) % - (s->ticksPerTact() / s->getTimeSigModel().getNumerator())); + m_majorLCD.setValue((int)(tick / s->ticksPerBar()) + 1); + m_minorLCD.setValue((tick % s->ticksPerBar()) / + (s->ticksPerBar() / s->getTimeSigModel().getNumerator() ) +1); + m_milliSecondsLCD.setValue((tick % s->ticksPerBar()) % + (s->ticksPerBar() / s->getTimeSigModel().getNumerator())); break; default: break; diff --git a/src/tracks/AutomationTrack.cpp b/src/tracks/AutomationTrack.cpp index 11c919f0e..430f54a56 100644 --- a/src/tracks/AutomationTrack.cpp +++ b/src/tracks/AutomationTrack.cpp @@ -121,9 +121,9 @@ void AutomationTrackView::dropEvent( QDropEvent * _de ) currentPosition() + ( _de->pos().x() - getTrackContentWidget()->x() ) * - MidiTime::ticksPerTact() / - static_cast( trackContainerView()->pixelsPerTact() ) ) - .toAbsoluteTact(); + MidiTime::ticksPerBar() / + static_cast( trackContainerView()->pixelsPerBar() ) ) + .toAbsoluteBar(); if( pos.getTicks() < 0 ) { diff --git a/src/tracks/BBTrack.cpp b/src/tracks/BBTrack.cpp index 779cd3c74..a779e2ea4 100644 --- a/src/tracks/BBTrack.cpp +++ b/src/tracks/BBTrack.cpp @@ -51,7 +51,7 @@ BBTCO::BBTCO( Track * _track ) : m_color( 128, 128, 128 ), m_useStyleColor( true ) { - tact_t t = Engine::getBBTrackContainer()->lengthOfBB( bbTrackIndex() ); + bar_t t = Engine::getBBTrackContainer()->lengthOfBB( bbTrackIndex() ); if( t > 0 ) { saveJournallingState( false ); @@ -237,12 +237,12 @@ void BBTCOView::paintEvent( QPaintEvent * ) const int lineSize = 3; p.setPen( c.darker( 200 ) ); - tact_t t = Engine::getBBTrackContainer()->lengthOfBB( m_bbTCO->bbTrackIndex() ); - if( m_bbTCO->length() > MidiTime::ticksPerTact() && t > 0 ) + bar_t t = Engine::getBBTrackContainer()->lengthOfBB( m_bbTCO->bbTrackIndex() ); + if( m_bbTCO->length() > MidiTime::ticksPerBar() && t > 0 ) { - for( int x = static_cast( t * pixelsPerTact() ); + for( int x = static_cast( t * pixelsPerBar() ); x < width() - 2; - x += static_cast( t * pixelsPerTact() ) ) + x += static_cast( t * pixelsPerBar() ) ) { p.drawLine( x, TCO_BORDER_WIDTH, x, TCO_BORDER_WIDTH + lineSize ); p.drawLine( x, rect().bottom() - ( TCO_BORDER_WIDTH + lineSize ), diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 673996fa2..b44d1b4fa 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -677,7 +677,7 @@ bool InstrumentTrack::play( const MidiTime & _start, const fpp_t _frames, if( cur_start > 0 ) { - // skip notes which are posated before start-tact + // skip notes which are posated before start-bar while( nit != notes.end() && ( *nit )->pos() < cur_start ) { ++nit; diff --git a/src/tracks/Pattern.cpp b/src/tracks/Pattern.cpp index 32baf0b14..125e84a1f 100644 --- a/src/tracks/Pattern.cpp +++ b/src/tracks/Pattern.cpp @@ -56,7 +56,7 @@ Pattern::Pattern( InstrumentTrack * _instrument_track ) : TrackContentObject( _instrument_track ), m_instrumentTrack( _instrument_track ), m_patternType( BeatPattern ), - m_steps( MidiTime::stepsPerTact() ) + m_steps( MidiTime::stepsPerBar() ) { setName( _instrument_track->name() ); if( _instrument_track->trackContainer() @@ -161,7 +161,7 @@ void Pattern::updateLength() return; } - tick_t max_length = MidiTime::ticksPerTact(); + tick_t max_length = MidiTime::ticksPerBar(); for( NoteVector::ConstIterator it = m_notes.begin(); it != m_notes.end(); ++it ) @@ -172,8 +172,8 @@ void Pattern::updateLength() ( *it )->endPos() ); } } - changeLength( MidiTime( max_length ).nextFullTact() * - MidiTime::ticksPerTact() ); + changeLength( MidiTime( max_length ).nextFullBar() * + MidiTime::ticksPerBar() ); updateBBTrack(); } @@ -182,7 +182,7 @@ void Pattern::updateLength() MidiTime Pattern::beatPatternLength() const { - tick_t max_length = MidiTime::ticksPerTact(); + tick_t max_length = MidiTime::ticksPerBar(); for( NoteVector::ConstIterator it = m_notes.begin(); it != m_notes.end(); ++it ) @@ -194,13 +194,13 @@ MidiTime Pattern::beatPatternLength() const } } - if( m_steps != MidiTime::stepsPerTact() ) + if( m_steps != MidiTime::stepsPerBar() ) { - max_length = m_steps * MidiTime::ticksPerTact() / - MidiTime::stepsPerTact(); + max_length = m_steps * MidiTime::ticksPerBar() / + MidiTime::stepsPerBar(); } - return MidiTime( max_length ).nextFullTact() * MidiTime::ticksPerTact(); + return MidiTime( max_length ).nextFullBar() * MidiTime::ticksPerBar(); } @@ -298,7 +298,7 @@ void Pattern::clearNotes() Note * Pattern::addStepNote( int step ) { - return addNote( Note( MidiTime( -DefaultTicksPerTact ), + return addNote( Note( MidiTime( -DefaultTicksPerBar ), MidiTime::stepPosition( step ) ), false ); } @@ -417,7 +417,7 @@ void Pattern::loadSettings( const QDomElement & _this ) m_steps = _this.attribute( "steps" ).toInt(); if( m_steps == 0 ) { - m_steps = MidiTime::stepsPerTact(); + m_steps = MidiTime::stepsPerBar(); } checkType(); @@ -466,7 +466,7 @@ void Pattern::clear() void Pattern::addSteps() { - m_steps += MidiTime::stepsPerTact(); + m_steps += MidiTime::stepsPerBar(); updateLength(); emit dataChanged(); } @@ -497,7 +497,7 @@ void Pattern::cloneSteps() void Pattern::removeSteps() { - int n = MidiTime::stepsPerTact(); + int n = MidiTime::stepsPerBar(); if( n < m_steps ) { for( int i = m_steps - n; i < m_steps; ++i ) @@ -555,19 +555,19 @@ bool Pattern::empty() void Pattern::changeTimeSignature() { - MidiTime last_pos = MidiTime::ticksPerTact() - 1; + MidiTime last_pos = MidiTime::ticksPerBar() - 1; for( NoteVector::ConstIterator cit = m_notes.begin(); cit != m_notes.end(); ++cit ) { if( ( *cit )->length() < 0 && ( *cit )->pos() > last_pos ) { - last_pos = ( *cit )->pos()+MidiTime::ticksPerTact() / - MidiTime::stepsPerTact(); + last_pos = ( *cit )->pos()+MidiTime::ticksPerBar() / + MidiTime::stepsPerBar(); } } - last_pos = last_pos.nextFullTact() * MidiTime::ticksPerTact(); - m_steps = qMax( MidiTime::stepsPerTact(), - last_pos.getTact() * MidiTime::stepsPerTact() ); + last_pos = last_pos.nextFullBar() * MidiTime::ticksPerBar(); + m_steps = qMax( MidiTime::stepsPerBar(), + last_pos.getBar() * MidiTime::stepsPerBar() ); updateLength(); } @@ -715,7 +715,7 @@ void PatternView::mousePressEvent( QMouseEvent * _me ) { if( _me->button() == Qt::LeftButton && m_pat->m_patternType == Pattern::BeatPattern && - ( fixedTCOs() || pixelsPerTact() >= 96 ) && + ( fixedTCOs() || pixelsPerBar() >= 96 ) && _me->y() > height() - s_stepBtnOff->height() ) // when mouse button is pressed in beat/bassline -mode @@ -785,7 +785,7 @@ void PatternView::mouseDoubleClickEvent(QMouseEvent *_me) void PatternView::wheelEvent( QWheelEvent * _we ) { if( m_pat->m_patternType == Pattern::BeatPattern && - ( fixedTCOs() || pixelsPerTact() >= 96 ) && + ( fixedTCOs() || pixelsPerBar() >= 96 ) && _we->y() > height() - s_stepBtnOff->height() ) { // get the step number that was wheeled on and @@ -902,14 +902,14 @@ void PatternView::paintEvent( QPaintEvent * ) textBoxHeight = fontMetrics.height() + 2 * textTop; } - // Compute pixels per tact + // Compute pixels per bar const int baseWidth = fixedTCOs() ? parentWidget()->width() - 2 * TCO_BORDER_WIDTH : width() - TCO_BORDER_WIDTH; - const float pixelsPerTact = baseWidth / (float) m_pat->length().getTact(); + const float pixelsPerBar = baseWidth / (float) m_pat->length().getBar(); - // Length of one tact/beat in the [0,1] x [0,1] coordinate system - const float tactLength = 1. / m_pat->length().getTact(); - const float tickLength = tactLength / MidiTime::ticksPerTact(); + // Length of one bar/beat in the [0,1] x [0,1] coordinate system + const float barLength = 1. / m_pat->length().getBar(); + const float tickLength = barLength / MidiTime::ticksPerBar(); const int x_base = TCO_BORDER_WIDTH; @@ -1029,7 +1029,7 @@ void PatternView::paintEvent( QPaintEvent * ) } // beat pattern paint event - else if( beatPattern && ( fixedTCOs() || pixelsPerTact >= 96 ) ) + else if( beatPattern && ( fixedTCOs() || pixelsPerBar >= 96 ) ) { QPixmap stepon0; QPixmap stepon200; @@ -1097,14 +1097,14 @@ void PatternView::paintEvent( QPaintEvent * ) const int lineSize = 3; p.setPen( c.darker( 200 ) ); - for( tact_t t = 1; t < m_pat->length().getTact(); ++t ) + for( bar_t t = 1; t < m_pat->length().getBar(); ++t ) { - p.drawLine( x_base + static_cast( pixelsPerTact * t ) - 1, + p.drawLine( x_base + static_cast( pixelsPerBar * t ) - 1, TCO_BORDER_WIDTH, x_base + static_cast( - pixelsPerTact * t ) - 1, TCO_BORDER_WIDTH + lineSize ); - p.drawLine( x_base + static_cast( pixelsPerTact * t ) - 1, + pixelsPerBar * t ) - 1, TCO_BORDER_WIDTH + lineSize ); + p.drawLine( x_base + static_cast( pixelsPerBar * t ) - 1, rect().bottom() - ( lineSize + TCO_BORDER_WIDTH ), - x_base + static_cast( pixelsPerTact * t ) - 1, + x_base + static_cast( pixelsPerBar * t ) - 1, rect().bottom() - TCO_BORDER_WIDTH ); } diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index ba04f909b..72f63bb05 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -157,7 +157,7 @@ void SampleTCO::setSampleFile( const QString & _sf ) { //When creating an empty sample pattern make it a bar long float nom = Engine::getSong()->getTimeSigModel().getNumerator(); float den = Engine::getSong()->getTimeSigModel().getDenominator(); - length = DefaultTicksPerTact * ( nom / den ); + length = DefaultTicksPerBar * ( nom / den ); } else { //Otherwise set it to the sample's length @@ -521,18 +521,18 @@ void SampleTCOView::paintEvent( QPaintEvent * pe ) p.setPen( !muted ? painter.pen().brush().color() : mutedColor() ); const int spacing = TCO_BORDER_WIDTH + 1; - const float ppt = fixedTCOs() ? + const float ppb = fixedTCOs() ? ( parentWidget()->width() - 2 * TCO_BORDER_WIDTH ) - / (float) m_tco->length().getTact() : - pixelsPerTact(); + / (float) m_tco->length().getBar() : + pixelsPerBar(); float nom = Engine::getSong()->getTimeSigModel().getNumerator(); float den = Engine::getSong()->getTimeSigModel().getDenominator(); - float ticksPerTact = DefaultTicksPerTact * nom / den; + float ticksPerBar = DefaultTicksPerBar * nom / den; - float offset = m_tco->startTimeOffset() / ticksPerTact * pixelsPerTact(); + float offset = m_tco->startTimeOffset() / ticksPerBar * pixelsPerBar(); QRect r = QRect( TCO_BORDER_WIDTH + offset, spacing, - qMax( static_cast( m_tco->sampleLength() * ppt / ticksPerTact ), 1 ), rect().bottom() - 2 * spacing ); + qMax( static_cast( m_tco->sampleLength() * ppb / ticksPerBar ), 1 ), rect().bottom() - 2 * spacing ); m_tco->m_sampleBuffer->visualize( p, r, pe->rect() ); QFileInfo fileInfo(m_tco->m_sampleBuffer->audioFile()); @@ -928,8 +928,8 @@ void SampleTrackView::dropEvent(QDropEvent *de) MidiTime tcoPos = trackContainerView()->fixedTCOs() ? MidiTime(0) - : MidiTime(((xPos - trackHeadWidth) / trackContainerView()->pixelsPerTact() - * MidiTime::ticksPerTact()) + trackContainerView()->currentPosition() + : MidiTime(((xPos - trackHeadWidth) / trackContainerView()->pixelsPerBar() + * MidiTime::ticksPerBar()) + trackContainerView()->currentPosition() ).quantize(1.0); SampleTCO * sTco = static_cast(getTrack()->createTCO(tcoPos)); diff --git a/tests/src/tracks/AutomationTrackTest.cpp b/tests/src/tracks/AutomationTrackTest.cpp index f9f77fac4..291ae293e 100644 --- a/tests/src/tracks/AutomationTrackTest.cpp +++ b/tests/src/tracks/AutomationTrackTest.cpp @@ -186,12 +186,12 @@ private slots: QVERIFY(! bbContainer->automatedValuesAt(5, bbTrack2.index()).size()); BBTCO tco(&bbTrack); - tco.changeLength(MidiTime::ticksPerTact() * 2); + tco.changeLength(MidiTime::ticksPerBar() * 2); tco.movePosition(0); QCOMPARE(song->automatedValuesAt(0)[&model], 0.0f); QCOMPARE(song->automatedValuesAt(5)[&model], 0.5f); - QCOMPARE(song->automatedValuesAt(MidiTime::ticksPerTact() + 5)[&model], 0.5f); + QCOMPARE(song->automatedValuesAt(MidiTime::ticksPerBar() + 5)[&model], 0.5f); } void testGlobalAutomation() From 46f5433732654d8090cc75ee21f3a00f93910439 Mon Sep 17 00:00:00 2001 From: Alexandre Almeida Date: Sun, 27 Oct 2019 08:45:58 -0300 Subject: [PATCH 436/445] New BARS_PER_GROUP constant --- src/core/Track.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index dedfcbc27..5c61dc5ab 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -73,6 +73,10 @@ */ const int RESIZE_GRIP_WIDTH = 4; +/*! Alternate between a darker and a lighter background color every 4 bars + */ +const int BARS_PER_GROUP = 4; + /*! A pointer for that text bubble used when moving segments, etc. * @@ -1271,8 +1275,7 @@ void TrackContentWidget::updateBackground() // Assume even-pixels-per-bar. Makes sense, should be like this anyways int ppb = static_cast( tcv->pixelsPerBar() ); - // alternate between a darker and a lighter color every 4 bars - int w = ppb * 4; + int w = ppb * BARS_PER_GROUP; int h = height(); m_background = QPixmap( w * 2, height() ); QPainter pmp( &m_background ); From dac59a5fa056048ccc4655b06102406ac7c502ac Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Thu, 31 Oct 2019 19:05:33 +0000 Subject: [PATCH 437/445] C++11 inheritance updates Add `override` and remove `virtual` where applicable --- include/AudioAlsa.h | 8 +-- include/AudioAlsaSetupWidget.h | 2 +- include/AudioDummy.h | 10 +-- include/AudioFileMP3.h | 2 +- include/AudioFileOgg.h | 2 +- include/AudioFileWave.h | 2 +- include/AudioOss.h | 10 +-- include/AudioPort.h | 4 +- include/AudioPulseAudio.h | 10 +-- include/AudioSampleRecorder.h | 2 +- include/AudioSdl.h | 10 +-- include/AudioSndio.h | 10 +-- include/AutomatableButton.h | 10 +-- include/AutomatableModel.h | 6 +- include/AutomatableModelView.h | 2 +- include/AutomatableSlider.h | 10 +-- include/AutomationEditor.h | 34 +++++----- include/AutomationPattern.h | 8 +-- include/AutomationPatternView.h | 12 ++-- include/AutomationTrack.h | 16 ++--- include/BBEditor.h | 14 ++-- include/BBTrack.h | 30 ++++---- include/BBTrackContainer.h | 4 +- include/CPULoadWidget.h | 2 +- include/ComboBox.h | 8 +-- include/Controller.h | 6 +- include/ControllerConnection.h | 6 +- include/ControllerDialog.h | 2 +- include/ControllerRackView.h | 8 +-- include/ControllerView.h | 6 +- include/DetuningHelper.h | 6 +- include/DummyEffect.h | 14 ++-- include/DummyInstrument.h | 10 +-- include/DummyPlugin.h | 8 +-- include/Editor.h | 6 +- include/Effect.h | 8 +-- include/EffectChain.h | 6 +- include/EffectControlDialog.h | 2 +- include/EffectRackView.h | 2 +- include/EffectView.h | 6 +- include/EnvelopeAndLfoParameters.h | 6 +- include/EnvelopeAndLfoView.h | 10 +-- include/ExportFilter.h | 6 +- include/ExportProjectDialog.h | 6 +- include/FadeButton.h | 4 +- include/Fader.h | 14 ++-- include/FileBrowser.h | 10 +-- include/FxLine.h | 10 +-- include/FxLineLcdSpinBox.h | 4 +- include/FxMixer.h | 10 +-- include/FxMixerView.h | 8 +-- include/Graph.h | 14 ++-- include/GroupBox.h | 6 +- include/ImportFilter.h | 6 +- include/InlineAutomation.h | 4 +- include/Instrument.h | 2 +- include/InstrumentFunctionViews.h | 4 +- include/InstrumentFunctions.h | 12 ++-- include/InstrumentMidiIOView.h | 2 +- include/InstrumentPlayHandle.h | 6 +- include/InstrumentSoundShaping.h | 6 +- include/InstrumentSoundShapingView.h | 2 +- include/InstrumentTrack.h | 38 +++++------ include/JournallingObject.h | 4 +- include/Knob.h | 22 +++--- include/LadspaControl.h | 6 +- include/LcdSpinBox.h | 14 ++-- include/LcdWidget.h | 2 +- include/LedCheckbox.h | 2 +- include/LfoController.h | 14 ++-- include/LmmsStyle.h | 8 +-- include/MainApplication.h | 2 +- include/MainWindow.h | 10 +-- include/MeterDialog.h | 2 +- include/MidiAlsaRaw.h | 4 +- include/MidiAlsaSeq.h | 24 +++---- include/MidiClient.h | 4 +- include/MidiController.h | 14 ++-- include/MidiDummy.h | 2 +- include/MidiOss.h | 4 +- include/MidiPort.h | 6 +- include/MidiPortMenu.h | 2 +- include/MidiSndio.h | 4 +- include/Mixer.h | 2 +- include/MixerWorkerThread.h | 2 +- include/NStateButton.h | 2 +- include/Note.h | 6 +- include/NotePlayHandle.h | 10 +-- include/Pattern.h | 20 +++--- include/PeakController.h | 16 ++--- include/PianoRoll.h | 42 ++++++------ include/PianoView.h | 20 +++--- include/PixmapButton.h | 10 +-- include/PlayHandle.h | 4 +- include/Plugin.h | 2 +- include/PresetPreviewPlayHandle.h | 8 +-- include/ProjectNotes.h | 8 +-- include/ProjectRenderer.h | 2 +- include/RemotePlugin.h | 4 +- include/RenameDialog.h | 4 +- include/RowTableView.h | 4 +- include/Rubberband.h | 2 +- include/SamplePlayHandle.h | 8 +-- include/SampleRecordHandle.h | 6 +- include/SampleTrack.h | 54 +++++++-------- include/SendButtonIndicator.h | 2 +- include/SetupDialog.h | 2 +- include/SideBarWidget.h | 6 +- include/Song.h | 6 +- include/SongEditor.h | 38 +++++------ include/StepRecorderWidget.h | 2 +- include/SubWindow.h | 8 +-- include/TabWidget.h | 14 ++-- include/TempoSyncKnob.h | 4 +- include/TempoSyncKnobModel.h | 2 +- include/TextFloat.h | 4 +- include/TimeDisplayWidget.h | 2 +- include/TimeLineWidget.h | 14 ++-- include/Track.h | 68 +++++++++---------- include/TrackContainer.h | 6 +- include/TrackContainerView.h | 17 +++-- include/TrackLabelButton.h | 14 ++-- include/TrackRenameLineEdit.h | 2 +- include/VisualizationWidget.h | 4 +- plugins/VstEffect/VstEffectControlDialog.h | 4 +- .../peak_controller_effect.h | 4 +- .../peak_controller_effect_controls.h | 10 +-- plugins/vst_base/VstPlugin.h | 10 +-- src/core/PresetPreviewPlayHandle.cpp | 2 +- src/gui/ControllerConnectionDialog.cpp | 2 +- src/gui/FxMixerView.cpp | 2 +- src/gui/RowTableView.cpp | 4 +- src/gui/widgets/SideBar.cpp | 4 +- 133 files changed, 578 insertions(+), 579 deletions(-) diff --git a/include/AudioAlsa.h b/include/AudioAlsa.h index 77938e164..b1aa9647a 100644 --- a/include/AudioAlsa.h +++ b/include/AudioAlsa.h @@ -80,10 +80,10 @@ public: static DeviceInfoCollection getAvailableDevices(); private: - virtual void startProcessing(); - virtual void stopProcessing(); - virtual void applyQualitySettings(); - virtual void run(); + void startProcessing() override; + void stopProcessing() override; + void applyQualitySettings() override; + void run() override; int setHWParams( const ch_cnt_t _channels, snd_pcm_access_t _access ); int setSWParams(); diff --git a/include/AudioAlsaSetupWidget.h b/include/AudioAlsaSetupWidget.h index f087d2fd7..db88558a7 100644 --- a/include/AudioAlsaSetupWidget.h +++ b/include/AudioAlsaSetupWidget.h @@ -46,7 +46,7 @@ public: AudioAlsaSetupWidget( QWidget * _parent ); virtual ~AudioAlsaSetupWidget(); - virtual void saveSettings(); + void saveSettings() override; public slots: void onCurrentIndexChanged(int index); diff --git a/include/AudioDummy.h b/include/AudioDummy.h index 5094caddc..0772c69eb 100644 --- a/include/AudioDummy.h +++ b/include/AudioDummy.h @@ -64,11 +64,11 @@ public: { } - virtual void saveSettings() + void saveSettings() override { } - virtual void show() + void show() override { parentWidget()->hide(); QWidget::show(); @@ -78,17 +78,17 @@ public: private: - virtual void startProcessing() + void startProcessing() override { start(); } - virtual void stopProcessing() + void stopProcessing() override { stopProcessingThread( this ); } - virtual void run() + void run() override { MicroTimer timer; while( true ) diff --git a/include/AudioFileMP3.h b/include/AudioFileMP3.h index 497208e20..057fd13a4 100644 --- a/include/AudioFileMP3.h +++ b/include/AudioFileMP3.h @@ -58,7 +58,7 @@ public: protected: virtual void writeBuffer( const surroundSampleFrame * /* _buf*/, const fpp_t /*_frames*/, - const float /*_master_gain*/ ); + const float /*_master_gain*/ ) override; private: void flushRemainingBuffers(); diff --git a/include/AudioFileOgg.h b/include/AudioFileOgg.h index 656a7174e..8082f3767 100644 --- a/include/AudioFileOgg.h +++ b/include/AudioFileOgg.h @@ -59,7 +59,7 @@ public: private: virtual void writeBuffer( const surroundSampleFrame * _ab, const fpp_t _frames, - const float _master_gain ); + const float _master_gain ) override; bool startEncoding(); void finishEncoding(); diff --git a/include/AudioFileWave.h b/include/AudioFileWave.h index 4d2778bad..7c8d54964 100644 --- a/include/AudioFileWave.h +++ b/include/AudioFileWave.h @@ -56,7 +56,7 @@ public: private: virtual void writeBuffer( const surroundSampleFrame * _ab, const fpp_t _frames, - float _master_gain ); + float _master_gain ) override; bool startEncoding(); void finishEncoding(); diff --git a/include/AudioOss.h b/include/AudioOss.h index bacfd9597..9e4787ff2 100644 --- a/include/AudioOss.h +++ b/include/AudioOss.h @@ -60,7 +60,7 @@ public: setupWidget( QWidget * _parent ); virtual ~setupWidget(); - virtual void saveSettings(); + void saveSettings() override; private: QLineEdit * m_device; @@ -70,10 +70,10 @@ public: private: - virtual void startProcessing(); - virtual void stopProcessing(); - virtual void applyQualitySettings(); - virtual void run(); + void startProcessing() override; + void stopProcessing() override; + void applyQualitySettings() override; + void run() override; int m_audioFD; diff --git a/include/AudioPort.h b/include/AudioPort.h index 2842c6a17..146bbd192 100644 --- a/include/AudioPort.h +++ b/include/AudioPort.h @@ -100,8 +100,8 @@ public: bool processEffects(); // ThreadableJob stuff - virtual void doProcessing(); - virtual bool requiresProcessing() const + void doProcessing() override; + bool requiresProcessing() const override { return true; } diff --git a/include/AudioPulseAudio.h b/include/AudioPulseAudio.h index 496746691..e65180a74 100644 --- a/include/AudioPulseAudio.h +++ b/include/AudioPulseAudio.h @@ -62,7 +62,7 @@ public: setupWidget( QWidget * _parent ); virtual ~setupWidget(); - virtual void saveSettings(); + void saveSettings() override; private: QLineEdit * m_device; @@ -80,10 +80,10 @@ public: private: - virtual void startProcessing(); - virtual void stopProcessing(); - virtual void applyQualitySettings(); - virtual void run(); + void startProcessing() override; + void stopProcessing() override; + void applyQualitySettings() override; + void run() override; volatile bool m_quit; diff --git a/include/AudioSampleRecorder.h b/include/AudioSampleRecorder.h index 69ac19490..0a82d2d96 100644 --- a/include/AudioSampleRecorder.h +++ b/include/AudioSampleRecorder.h @@ -48,7 +48,7 @@ public: private: virtual void writeBuffer( const surroundSampleFrame * _ab, const fpp_t _frames, - const float _master_gain ); + const float _master_gain ) override; typedef QList > BufferList; BufferList m_buffers; diff --git a/include/AudioSdl.h b/include/AudioSdl.h index fd8c544c2..93f23abed 100644 --- a/include/AudioSdl.h +++ b/include/AudioSdl.h @@ -60,9 +60,9 @@ public: { public: setupWidget( QWidget * _parent ); - virtual ~setupWidget(); + ~setupWidget() override; - virtual void saveSettings(); + void saveSettings() override; private: QLineEdit * m_device; @@ -71,9 +71,9 @@ public: private: - virtual void startProcessing(); - virtual void stopProcessing(); - virtual void applyQualitySettings(); + void startProcessing() override; + void stopProcessing() override; + void applyQualitySettings() override; static void sdlAudioCallback( void * _udata, Uint8 * _buf, int _len ); void sdlAudioCallback( Uint8 * _buf, int _len ); diff --git a/include/AudioSndio.h b/include/AudioSndio.h index d2bc5c074..f8cf56848 100644 --- a/include/AudioSndio.h +++ b/include/AudioSndio.h @@ -58,7 +58,7 @@ public: setupWidget( QWidget * _parent ); virtual ~setupWidget(); - virtual void saveSettings( void ); + void saveSettings( void ) override; private: QLineEdit * m_device; @@ -66,10 +66,10 @@ public: } ; private: - virtual void startProcessing( void ); - virtual void stopProcessing( void ); - virtual void applyQualitySettings( void ); - virtual void run( void ); + void startProcessing( void ) override; + void stopProcessing( void ) override; + void applyQualitySettings( void ) override; + void run( void ) override; struct sio_hdl *m_hdl; struct sio_par m_par; diff --git a/include/AutomatableButton.h b/include/AutomatableButton.h index 4b5065542..d7859a10c 100644 --- a/include/AutomatableButton.h +++ b/include/AutomatableButton.h @@ -48,7 +48,7 @@ public: model()->setJournalling( _on ); } - virtual void modelChanged(); + void modelChanged() override; public slots: @@ -62,9 +62,9 @@ public slots: protected: - virtual void contextMenuEvent( QContextMenuEvent * _me ); - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void mouseReleaseEvent( QMouseEvent * _me ); + void contextMenuEvent( QContextMenuEvent * _me ) override; + void mousePressEvent( QMouseEvent * _me ) override; + void mouseReleaseEvent( QMouseEvent * _me ) override; private: @@ -92,7 +92,7 @@ public: void activateButton( AutomatableButton * _btn ); - virtual void modelChanged(); + void modelChanged() override; private slots: diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h index 3e0b6143d..6d8000804 100644 --- a/include/AutomatableModel.h +++ b/include/AutomatableModel.h @@ -255,7 +255,7 @@ public: specified DOM element using as attribute/node name */ virtual void loadSettings( const QDomElement& element, const QString& name ); - virtual QString nodeName() const + QString nodeName() const override { return "automatablemodel"; } @@ -337,12 +337,12 @@ private: static bool mustQuoteName(const QString &name); - virtual void saveSettings( QDomDocument& doc, QDomElement& element ) + void saveSettings( QDomDocument& doc, QDomElement& element ) override { saveSettings( doc, element, "value" ); } - virtual void loadSettings( const QDomElement& element ) + void loadSettings( const QDomElement& element ) override { loadSettings( element, "value" ); } diff --git a/include/AutomatableModelView.h b/include/AutomatableModelView.h index 964ffdc5d..1bcbd97d6 100644 --- a/include/AutomatableModelView.h +++ b/include/AutomatableModelView.h @@ -49,7 +49,7 @@ public: return castModel(); } - virtual void setModel( Model* model, bool isOldModelValid = true ); + void setModel( Model* model, bool isOldModelValid = true ) override; template inline T value() const diff --git a/include/AutomatableSlider.h b/include/AutomatableSlider.h index f58d4a059..b51ef1e3f 100644 --- a/include/AutomatableSlider.h +++ b/include/AutomatableSlider.h @@ -51,12 +51,12 @@ signals: protected: - virtual void contextMenuEvent( QContextMenuEvent * _me ); - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void mouseReleaseEvent( QMouseEvent * _me ); - virtual void wheelEvent( QWheelEvent * _me ); + void contextMenuEvent( QContextMenuEvent * _me ) override; + void mousePressEvent( QMouseEvent * _me ) override; + void mouseReleaseEvent( QMouseEvent * _me ) override; + void wheelEvent( QWheelEvent * _me ) override; - virtual void modelChanged(); + void modelChanged() override; private: diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h index e39eaddd7..60b894f1f 100644 --- a/include/AutomationEditor.h +++ b/include/AutomationEditor.h @@ -73,9 +73,9 @@ public: return m_pattern != nullptr; } - virtual void saveSettings(QDomDocument & doc, QDomElement & parent); - virtual void loadSettings(const QDomElement & parent); - QString nodeName() const + void saveSettings(QDomDocument & doc, QDomElement & parent) override; + void loadSettings(const QDomElement & parent) override; + QString nodeName() const override { return "automationeditor"; } @@ -114,14 +114,14 @@ public slots: protected: typedef AutomationPattern::timeMap timeMap; - virtual void keyPressEvent(QKeyEvent * ke); - virtual void leaveEvent(QEvent * e); - virtual void mousePressEvent(QMouseEvent * mouseEvent); - virtual void mouseReleaseEvent(QMouseEvent * mouseEvent); - virtual void mouseMoveEvent(QMouseEvent * mouseEvent); - virtual void paintEvent(QPaintEvent * pe); - virtual void resizeEvent(QResizeEvent * re); - virtual void wheelEvent(QWheelEvent * we); + void keyPressEvent(QKeyEvent * ke) override; + void leaveEvent(QEvent * e) override; + void mousePressEvent(QMouseEvent * mouseEvent) override; + void mouseReleaseEvent(QMouseEvent * mouseEvent) override; + void mouseMoveEvent(QMouseEvent * mouseEvent) override; + void paintEvent(QPaintEvent * pe) override; + void resizeEvent(QResizeEvent * re) override; + void wheelEvent(QWheelEvent * we) override; float getLevel( int y ); int xCoordOfTick( int tick ); @@ -282,14 +282,14 @@ public: void setCurrentPattern(AutomationPattern* pattern); const AutomationPattern* currentPattern(); - virtual void dropEvent( QDropEvent * _de ); - virtual void dragEnterEvent( QDragEnterEvent * _dee ); + void dropEvent( QDropEvent * _de ) override; + void dragEnterEvent( QDragEnterEvent * _dee ) override; void open(AutomationPattern* pattern); AutomationEditor* m_editor; - QSize sizeHint() const; + QSize sizeHint() const override; public slots: void clearCurrentPattern(); @@ -298,11 +298,11 @@ signals: void currentPatternChanged(); protected: - virtual void focusInEvent(QFocusEvent * event); + void focusInEvent(QFocusEvent * event) override; protected slots: - void play(); - void stop(); + void play() override; + void stop() override; private slots: void updateWindowTitle(); diff --git a/include/AutomationPattern.h b/include/AutomationPattern.h index 070b6c669..cad9d0a1d 100644 --- a/include/AutomationPattern.h +++ b/include/AutomationPattern.h @@ -140,13 +140,13 @@ public: const QString name() const; // settings-management - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; + void loadSettings( const QDomElement & _this ) override; static const QString classNodeName() { return "automationpattern"; } - QString nodeName() const { return classNodeName(); } + QString nodeName() const override { return classNodeName(); } - virtual TrackContentObjectView * createView( TrackView * _tv ); + TrackContentObjectView * createView( TrackView * _tv ) override; static bool isAutomated( const AutomatableModel * _m ); diff --git a/include/AutomationPatternView.h b/include/AutomationPatternView.h index 45aa9ef2a..3f019483a 100644 --- a/include/AutomationPatternView.h +++ b/include/AutomationPatternView.h @@ -44,7 +44,7 @@ public: public slots: /// Opens this view's pattern in the global automation editor void openInAutomationEditor(); - virtual void update(); + void update() override; protected slots: @@ -56,11 +56,11 @@ protected slots: void flipX(); protected: - virtual void constructContextMenu( QMenu * ); - virtual void mouseDoubleClickEvent(QMouseEvent * me ); - virtual void paintEvent( QPaintEvent * pe ); - virtual void dragEnterEvent( QDragEnterEvent * _dee ); - virtual void dropEvent( QDropEvent * _de ); + void constructContextMenu( QMenu * ) override; + void mouseDoubleClickEvent(QMouseEvent * me ) override; + void paintEvent( QPaintEvent * pe ) override; + void dragEnterEvent( QDragEnterEvent * _dee ) override; + void dropEvent( QDropEvent * _de ) override; private: diff --git a/include/AutomationTrack.h b/include/AutomationTrack.h index 195c21e9d..92a50dd04 100644 --- a/include/AutomationTrack.h +++ b/include/AutomationTrack.h @@ -38,19 +38,19 @@ public: virtual ~AutomationTrack() = default; virtual bool play( const MidiTime & _start, const fpp_t _frames, - const f_cnt_t _frame_base, int _tco_num = -1 ); + const f_cnt_t _frame_base, int _tco_num = -1 ) override; - virtual QString nodeName() const + QString nodeName() const override { return "automationtrack"; } - virtual TrackView * createView( TrackContainerView* ); - virtual TrackContentObject * createTCO( const MidiTime & _pos ); + TrackView * createView( TrackContainerView* ) override; + TrackContentObject * createTCO( const MidiTime & _pos ) override; virtual void saveTrackSpecificSettings( QDomDocument & _doc, - QDomElement & _parent ); - virtual void loadTrackSpecificSettings( const QDomElement & _this ); + QDomElement & _parent ) override; + void loadTrackSpecificSettings( const QDomElement & _this ) override; private: friend class AutomationTrackView; @@ -65,8 +65,8 @@ public: AutomationTrackView( AutomationTrack* at, TrackContainerView* tcv ); virtual ~AutomationTrackView() = default; - virtual void dragEnterEvent( QDragEnterEvent * _dee ); - virtual void dropEvent( QDropEvent * _de ); + void dragEnterEvent( QDragEnterEvent * _dee ) override; + void dropEvent( QDropEvent * _de ) override; } ; diff --git a/include/BBEditor.h b/include/BBEditor.h index 59b7142f4..ed54beaf1 100644 --- a/include/BBEditor.h +++ b/include/BBEditor.h @@ -42,7 +42,7 @@ public: BBEditor( BBTrackContainer * _tc ); ~BBEditor(); - QSize sizeHint() const; + QSize sizeHint() const override; const BBTrackContainerView* trackContainerView() const { return m_trackContainerView; @@ -54,8 +54,8 @@ public: void removeBBView( int bb ); public slots: - void play(); - void stop(); + void play() override; + void stop() override; private: BBTrackContainerView* m_trackContainerView; @@ -70,15 +70,15 @@ class BBTrackContainerView : public TrackContainerView public: BBTrackContainerView(BBTrackContainer* tc); - bool fixedTCOs() const + bool fixedTCOs() const override { return true; } void removeBBView(int bb); - void saveSettings(QDomDocument& doc, QDomElement& element); - void loadSettings(const QDomElement& element); + void saveSettings(QDomDocument& doc, QDomElement& element) override; + void loadSettings(const QDomElement& element) override; public slots: void addSteps(); @@ -88,7 +88,7 @@ public slots: void addAutomationTrack(); protected slots: - void dropEvent(QDropEvent * de ); + void dropEvent(QDropEvent * de ) override; void updatePosition(); private: diff --git a/include/BBTrack.h b/include/BBTrack.h index a906b54d2..70195f28d 100644 --- a/include/BBTrack.h +++ b/include/BBTrack.h @@ -43,9 +43,9 @@ public: BBTCO( Track * _track ); virtual ~BBTCO() = default; - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); - inline virtual QString nodeName() const + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; + void loadSettings( const QDomElement & _this ) override; + inline QString nodeName() const override { return( "bbtco" ); } @@ -72,7 +72,7 @@ public: int bbTrackIndex(); - virtual TrackContentObjectView * createView( TrackView * _tv ); + TrackContentObjectView * createView( TrackView * _tv ) override; private: QColor m_color; @@ -99,7 +99,7 @@ public: void setColor( QColor _new_color ); public slots: - virtual void update(); + void update() override; protected slots: void openInBBEditor(); @@ -110,9 +110,9 @@ protected slots: protected: - virtual void paintEvent( QPaintEvent * pe ); - virtual void mouseDoubleClickEvent( QMouseEvent * _me ); - virtual void constructContextMenu( QMenu * ); + void paintEvent( QPaintEvent * pe ) override; + void mouseDoubleClickEvent( QMouseEvent * _me ) override; + void constructContextMenu( QMenu * ) override; private: @@ -133,13 +133,13 @@ public: virtual ~BBTrack(); virtual bool play( const MidiTime & _start, const fpp_t _frames, - const f_cnt_t _frame_base, int _tco_num = -1 ); - virtual TrackView * createView( TrackContainerView* tcv ); - virtual TrackContentObject * createTCO( const MidiTime & _pos ); + const f_cnt_t _frame_base, int _tco_num = -1 ) override; + TrackView * createView( TrackContainerView* tcv ) override; + TrackContentObject * createTCO( const MidiTime & _pos ) override; virtual void saveTrackSpecificSettings( QDomDocument & _doc, - QDomElement & _parent ); - virtual void loadTrackSpecificSettings( const QDomElement & _this ); + QDomElement & _parent ) override; + void loadTrackSpecificSettings( const QDomElement & _this ) override; static BBTrack * findBBTrack( int _bb_num ); static void swapBBTracks( Track * _track1, Track * _track2 ); @@ -184,7 +184,7 @@ public: } protected: - inline virtual QString nodeName() const + inline QString nodeName() const override { return( "bbtrack" ); } @@ -211,7 +211,7 @@ public: BBTrackView( BBTrack* bbt, TrackContainerView* tcv ); virtual ~BBTrackView(); - virtual bool close(); + bool close() override; const BBTrack * getBBTrack() const { diff --git a/include/BBTrackContainer.h b/include/BBTrackContainer.h index e4895aa87..17d6eb5fe 100644 --- a/include/BBTrackContainer.h +++ b/include/BBTrackContainer.h @@ -41,9 +41,9 @@ public: virtual bool play( MidiTime _start, const fpp_t _frames, const f_cnt_t _frame_base, int _tco_num = -1 ); - virtual void updateAfterTrackAdd() override; + void updateAfterTrackAdd() override; - inline virtual QString nodeName() const override + inline QString nodeName() const override { return "bbtrackcontainer"; } diff --git a/include/CPULoadWidget.h b/include/CPULoadWidget.h index 610403f57..2bc41283b 100644 --- a/include/CPULoadWidget.h +++ b/include/CPULoadWidget.h @@ -43,7 +43,7 @@ public: protected: - virtual void paintEvent( QPaintEvent * _ev ); + void paintEvent( QPaintEvent * _ev ) override; protected slots: diff --git a/include/ComboBox.h b/include/ComboBox.h index 927c87620..d530c9d92 100644 --- a/include/ComboBox.h +++ b/include/ComboBox.h @@ -57,10 +57,10 @@ public slots: protected: - virtual void contextMenuEvent( QContextMenuEvent* event ); - virtual void mousePressEvent( QMouseEvent* event ); - virtual void paintEvent( QPaintEvent* event ); - virtual void wheelEvent( QWheelEvent* event ); + void contextMenuEvent( QContextMenuEvent* event ) override; + void mousePressEvent( QMouseEvent* event ) override; + void paintEvent( QPaintEvent* event ) override; + void wheelEvent( QWheelEvent* event ) override; private: diff --git a/include/Controller.h b/include/Controller.h index f1e71ad8f..b60349463 100644 --- a/include/Controller.h +++ b/include/Controller.h @@ -101,9 +101,9 @@ public: } - virtual void saveSettings( QDomDocument & _doc, QDomElement & _this ); - virtual void loadSettings( const QDomElement & _this ); - virtual QString nodeName() const; + void saveSettings( QDomDocument & _doc, QDomElement & _this ) override; + void loadSettings( const QDomElement & _this ) override; + QString nodeName() const override; static Controller * create( ControllerTypes _tt, Model * _parent ); static Controller * create( const QDomElement & _this, diff --git a/include/ControllerConnection.h b/include/ControllerConnection.h index 5c4d5f20e..e57cd4db2 100644 --- a/include/ControllerConnection.h +++ b/include/ControllerConnection.h @@ -85,15 +85,15 @@ public: static void finalizeConnections(); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _this ); - virtual void loadSettings( const QDomElement & _this ); + void saveSettings( QDomDocument & _doc, QDomElement & _this ) override; + void loadSettings( const QDomElement & _this ) override; static inline const QString classNodeName() { return "connection"; } - virtual QString nodeName() const + QString nodeName() const override { return classNodeName(); } diff --git a/include/ControllerDialog.h b/include/ControllerDialog.h index 58a0a94b2..05e8f3bfe 100644 --- a/include/ControllerDialog.h +++ b/include/ControllerDialog.h @@ -47,7 +47,7 @@ signals: protected: - virtual void closeEvent( QCloseEvent * _ce ); + void closeEvent( QCloseEvent * _ce ) override; } ; diff --git a/include/ControllerRackView.h b/include/ControllerRackView.h index cb393f5ca..9ef2d9b7f 100644 --- a/include/ControllerRackView.h +++ b/include/ControllerRackView.h @@ -47,10 +47,10 @@ public: ControllerRackView(); virtual ~ControllerRackView(); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; + void loadSettings( const QDomElement & _this ) override; - inline virtual QString nodeName() const + inline QString nodeName() const override { return "ControllerRackView"; } @@ -62,7 +62,7 @@ public slots: void onControllerRemoved( Controller * ); protected: - virtual void closeEvent( QCloseEvent * _ce ); + void closeEvent( QCloseEvent * _ce ) override; private slots: void addController(); diff --git a/include/ControllerView.h b/include/ControllerView.h index 4b215feca..d1284845e 100644 --- a/include/ControllerView.h +++ b/include/ControllerView.h @@ -68,9 +68,9 @@ signals: protected: - virtual void contextMenuEvent( QContextMenuEvent * _me ); - virtual void modelChanged(); - virtual void mouseDoubleClickEvent( QMouseEvent * event ); + void contextMenuEvent( QContextMenuEvent * _me ) override; + void modelChanged() override; + void mouseDoubleClickEvent( QMouseEvent * event ) override; private: diff --git a/include/DetuningHelper.h b/include/DetuningHelper.h index de0acc826..2157b6ba8 100644 --- a/include/DetuningHelper.h +++ b/include/DetuningHelper.h @@ -43,17 +43,17 @@ public: { } - virtual float defaultValue() const + float defaultValue() const override { return 0; } - virtual QString displayName() const + QString displayName() const override { return tr( "Note detuning" ); } - inline virtual QString nodeName() const + inline QString nodeName() const override { return "detuning"; } diff --git a/include/DummyEffect.h b/include/DummyEffect.h index 4f770af3c..5509131be 100644 --- a/include/DummyEffect.h +++ b/include/DummyEffect.h @@ -53,25 +53,25 @@ public: { } - virtual int controlCount() + int controlCount() override { return 0; } - virtual void saveSettings( QDomDocument &, QDomElement & ) + void saveSettings( QDomDocument &, QDomElement & ) override { } - virtual void loadSettings( const QDomElement & ) + void loadSettings( const QDomElement & ) override { } - virtual QString nodeName() const + QString nodeName() const override { return "DummyControls"; } - virtual EffectControlDialog * createView() + EffectControlDialog * createView() override { return new DummyEffectControlDialog( this ); } @@ -95,12 +95,12 @@ public: { } - virtual EffectControls * controls() + EffectControls * controls() override { return &m_controls; } - bool processAudioBuffer( sampleFrame *, const fpp_t ) + bool processAudioBuffer( sampleFrame *, const fpp_t ) override { return false; } diff --git a/include/DummyInstrument.h b/include/DummyInstrument.h index 87083f262..a37b089ae 100644 --- a/include/DummyInstrument.h +++ b/include/DummyInstrument.h @@ -47,26 +47,26 @@ public: { } - virtual void playNote( NotePlayHandle *, sampleFrame * buffer ) + void playNote( NotePlayHandle *, sampleFrame * buffer ) override { memset( buffer, 0, sizeof( sampleFrame ) * Engine::mixer()->framesPerPeriod() ); } - virtual void saveSettings( QDomDocument &, QDomElement & ) + void saveSettings( QDomDocument &, QDomElement & ) override { } - virtual void loadSettings( const QDomElement & ) + void loadSettings( const QDomElement & ) override { } - virtual QString nodeName() const + QString nodeName() const override { return "dummyinstrument"; } - virtual PluginView * instantiateView( QWidget * _parent ) + PluginView * instantiateView( QWidget * _parent ) override { return new InstrumentViewFixedSize( this, _parent ); } diff --git a/include/DummyPlugin.h b/include/DummyPlugin.h index 49475a2ac..ec26da0a3 100644 --- a/include/DummyPlugin.h +++ b/include/DummyPlugin.h @@ -42,22 +42,22 @@ public: { } - virtual void saveSettings( QDomDocument &, QDomElement & ) + void saveSettings( QDomDocument &, QDomElement & ) override { } - virtual void loadSettings( const QDomElement & ) + void loadSettings( const QDomElement & ) override { } - virtual QString nodeName() const + QString nodeName() const override { return "DummyPlugin"; } protected: - virtual PluginView * instantiateView( QWidget * _parent ) + PluginView * instantiateView( QWidget * _parent ) override { return new PluginView( this, _parent ); } diff --git a/include/Editor.h b/include/Editor.h index 26b70ec87..1c80e9f2f 100644 --- a/include/Editor.h +++ b/include/Editor.h @@ -47,7 +47,7 @@ protected: DropToolBar * addDropToolBar(Qt::ToolBarArea whereToAdd, QString const & windowTitle); DropToolBar * addDropToolBar(QWidget * parent, Qt::ToolBarArea whereToAdd, QString const & windowTitle); - virtual void closeEvent( QCloseEvent * _ce ); + void closeEvent( QCloseEvent * _ce ) override; protected slots: virtual void play() {} virtual void record() {} @@ -92,8 +92,8 @@ signals: void dropped(QDropEvent* event); protected: - void dragEnterEvent(QDragEnterEvent* event); - void dropEvent(QDropEvent* event); + void dragEnterEvent(QDragEnterEvent* event) override; + void dropEvent(QDropEvent* event) override; }; diff --git a/include/Effect.h b/include/Effect.h index 4dc50e8a4..3874aa602 100644 --- a/include/Effect.h +++ b/include/Effect.h @@ -47,10 +47,10 @@ public: const Descriptor::SubPluginFeatures::Key * _key ); virtual ~Effect(); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; + void loadSettings( const QDomElement & _this ) override; - inline virtual QString nodeName() const + inline QString nodeName() const override { return "effect"; } @@ -170,7 +170,7 @@ protected: */ void checkGate( double _out_sum ); - virtual PluginView * instantiateView( QWidget * ); + PluginView * instantiateView( QWidget * ) override; // some effects might not be capable of higher sample-rates so they can // sample it down before processing and back after processing diff --git a/include/EffectChain.h b/include/EffectChain.h index bc1e7df8c..9ebc4d534 100644 --- a/include/EffectChain.h +++ b/include/EffectChain.h @@ -40,10 +40,10 @@ public: EffectChain( Model * _parent ); virtual ~EffectChain(); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; + void loadSettings( const QDomElement & _this ) override; - inline virtual QString nodeName() const + inline QString nodeName() const override { return "fxchain"; } diff --git a/include/EffectControlDialog.h b/include/EffectControlDialog.h index c0a60cfa6..4a59489da 100644 --- a/include/EffectControlDialog.h +++ b/include/EffectControlDialog.h @@ -48,7 +48,7 @@ signals: protected: - virtual void closeEvent( QCloseEvent * _ce ); + void closeEvent( QCloseEvent * _ce ) override; EffectControls * m_effectControls; diff --git a/include/EffectRackView.h b/include/EffectRackView.h index 0cfc04e15..698bad7fb 100644 --- a/include/EffectRackView.h +++ b/include/EffectRackView.h @@ -60,7 +60,7 @@ private slots: private: - virtual void modelChanged(); + void modelChanged() override; inline EffectChain* fxChain() { diff --git a/include/EffectView.h b/include/EffectView.h index 71a0e7128..6e994dd7e 100644 --- a/include/EffectView.h +++ b/include/EffectView.h @@ -73,9 +73,9 @@ signals: protected: - virtual void contextMenuEvent( QContextMenuEvent * _me ); - virtual void paintEvent( QPaintEvent * _pe ); - virtual void modelChanged(); + void contextMenuEvent( QContextMenuEvent * _me ) override; + void paintEvent( QPaintEvent * _pe ) override; + void modelChanged() override; private: diff --git a/include/EnvelopeAndLfoParameters.h b/include/EnvelopeAndLfoParameters.h index 4824062f3..0f691adb0 100644 --- a/include/EnvelopeAndLfoParameters.h +++ b/include/EnvelopeAndLfoParameters.h @@ -91,9 +91,9 @@ public: } - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); - virtual QString nodeName() const + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; + void loadSettings( const QDomElement & _this ) override; + QString nodeName() const override { return "el"; } diff --git a/include/EnvelopeAndLfoView.h b/include/EnvelopeAndLfoView.h index 817b0a6ee..f6d4fd0a8 100644 --- a/include/EnvelopeAndLfoView.h +++ b/include/EnvelopeAndLfoView.h @@ -52,12 +52,12 @@ public: protected: - virtual void modelChanged(); + void modelChanged() override; - virtual void dragEnterEvent( QDragEnterEvent * _dee ); - virtual void dropEvent( QDropEvent * _de ); - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void paintEvent( QPaintEvent * _pe ); + void dragEnterEvent( QDragEnterEvent * _dee ) override; + void dropEvent( QDropEvent * _de ) override; + void mousePressEvent( QMouseEvent * _me ) override; + void paintEvent( QPaintEvent * _pe ) override; protected slots: diff --git a/include/ExportFilter.h b/include/ExportFilter.h index 950bacbcd..3124b477b 100644 --- a/include/ExportFilter.h +++ b/include/ExportFilter.h @@ -44,15 +44,15 @@ public: int tempo, int masterPitch, const QString &filename ) = 0; protected: - virtual void saveSettings( QDomDocument &, QDomElement & ) + void saveSettings( QDomDocument &, QDomElement & ) override { } - virtual void loadSettings( const QDomElement & ) + void loadSettings( const QDomElement & ) override { } - virtual QString nodeName() const + QString nodeName() const override { return "import_filter"; } diff --git a/include/ExportProjectDialog.h b/include/ExportProjectDialog.h index 0eedb9722..06c1e3011 100644 --- a/include/ExportProjectDialog.h +++ b/include/ExportProjectDialog.h @@ -41,14 +41,14 @@ public: ExportProjectDialog( const QString & _file_name, QWidget * _parent, bool multi_export ); protected: - virtual void reject( void ); - virtual void closeEvent( QCloseEvent * _ce ); + void reject( void ) override; + void closeEvent( QCloseEvent * _ce ) override; private slots: void startBtnClicked( void ); void updateTitleBar( int ); - void accept(); + void accept() override; void startExport(); void onFileFormatChanged(int); diff --git a/include/FadeButton.h b/include/FadeButton.h index 8f56a77b2..09a4c6457 100644 --- a/include/FadeButton.h +++ b/include/FadeButton.h @@ -50,8 +50,8 @@ public slots: protected: - virtual void customEvent( QEvent * ); - virtual void paintEvent( QPaintEvent * _pe ); + void customEvent( QEvent * ) override; + void paintEvent( QPaintEvent * _pe ) override; private: diff --git a/include/Fader.h b/include/Fader.h index 018f66e0c..207215445 100644 --- a/include/Fader.h +++ b/include/Fader.h @@ -109,13 +109,13 @@ public: } private: - virtual void contextMenuEvent( QContextMenuEvent * _me ); - virtual void mousePressEvent( QMouseEvent *ev ); - virtual void mouseDoubleClickEvent( QMouseEvent* mouseEvent ); - virtual void mouseMoveEvent( QMouseEvent *ev ); - virtual void mouseReleaseEvent( QMouseEvent * _me ); - virtual void wheelEvent( QWheelEvent *ev ); - virtual void paintEvent( QPaintEvent *ev ); + void contextMenuEvent( QContextMenuEvent * _me ) override; + void mousePressEvent( QMouseEvent *ev ) override; + void mouseDoubleClickEvent( QMouseEvent* mouseEvent ) override; + void mouseMoveEvent( QMouseEvent *ev ) override; + void mouseReleaseEvent( QMouseEvent * _me ) override; + void wheelEvent( QWheelEvent *ev ) override; + void paintEvent( QPaintEvent *ev ) override; inline bool clips(float const & value) const { return value >= 1.0f; } diff --git a/include/FileBrowser.h b/include/FileBrowser.h index 4b92dd549..9b56a8dbd 100644 --- a/include/FileBrowser.h +++ b/include/FileBrowser.h @@ -61,7 +61,7 @@ private slots: void giveFocusToFilter(); private: - virtual void keyPressEvent( QKeyEvent * ke ); + void keyPressEvent( QKeyEvent * ke ) override; void addItems( const QString & path ); @@ -93,10 +93,10 @@ public: protected: - virtual void contextMenuEvent( QContextMenuEvent * e ); - virtual void mousePressEvent( QMouseEvent * me ); - virtual void mouseMoveEvent( QMouseEvent * me ); - virtual void mouseReleaseEvent( QMouseEvent * me ); + void contextMenuEvent( QContextMenuEvent * e ) override; + void mousePressEvent( QMouseEvent * me ) override; + void mouseMoveEvent( QMouseEvent * me ) override; + void mouseReleaseEvent( QMouseEvent * me ) override; private: diff --git a/include/FxLine.h b/include/FxLine.h index ef8313e74..c16dcd5f5 100644 --- a/include/FxLine.h +++ b/include/FxLine.h @@ -51,10 +51,10 @@ public: FxLine( QWidget * _parent, FxMixerView * _mv, int _channelIndex); ~FxLine(); - virtual void paintEvent( QPaintEvent * ); - virtual void mousePressEvent( QMouseEvent * ); - virtual void mouseDoubleClickEvent( QMouseEvent * ); - virtual void contextMenuEvent( QContextMenuEvent * ); + void paintEvent( QPaintEvent * ) override; + void mousePressEvent( QMouseEvent * ) override; + void mouseDoubleClickEvent( QMouseEvent * ) override; + void contextMenuEvent( QContextMenuEvent * ) override; inline int channelIndex() { return m_channelIndex; } void setChannelIndex(int index); @@ -79,7 +79,7 @@ public: static const int FxLineHeight; - bool eventFilter (QObject *dist, QEvent *event); + bool eventFilter (QObject *dist, QEvent *event) override; private: void drawFxLine( QPainter* p, const FxLine *fxLine, bool isActive, bool sendToThis, bool receiveFromThis ); diff --git a/include/FxLineLcdSpinBox.h b/include/FxLineLcdSpinBox.h index fa001b2bb..eeb104c5c 100644 --- a/include/FxLineLcdSpinBox.h +++ b/include/FxLineLcdSpinBox.h @@ -42,8 +42,8 @@ public: void setTrackView(TrackView * tv); protected: - virtual void mouseDoubleClickEvent(QMouseEvent* event); - virtual void contextMenuEvent(QContextMenuEvent* event); + void mouseDoubleClickEvent(QMouseEvent* event) override; + void contextMenuEvent(QContextMenuEvent* event) override; private: TrackView * m_tv; diff --git a/include/FxMixer.h b/include/FxMixer.h index 2c7ef3c5a..68b69d9bc 100644 --- a/include/FxMixer.h +++ b/include/FxMixer.h @@ -67,7 +67,7 @@ class FxChannel : public ThreadableJob // pointers to other channels that send to this one FxRouteVector m_receives; - virtual bool requiresProcessing() const { return true; } + bool requiresProcessing() const override { return true; } void unmuteForSolo(); @@ -76,7 +76,7 @@ class FxChannel : public ThreadableJob void processed(); private: - virtual void doProcessing(); + void doProcessing() override; }; @@ -133,10 +133,10 @@ public: void prepareMasterMix(); void masterMix( sampleFrame * _buf ); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; + void loadSettings( const QDomElement & _this ) override; - virtual QString nodeName() const + QString nodeName() const override { return "fxmixer"; } diff --git a/include/FxMixerView.h b/include/FxMixerView.h index 9b07637ed..a7662321a 100644 --- a/include/FxMixerView.h +++ b/include/FxMixerView.h @@ -64,10 +64,10 @@ public: FxMixerView(); virtual ~FxMixerView(); - virtual void keyPressEvent(QKeyEvent * e); + void keyPressEvent(QKeyEvent * e) override; - virtual void saveSettings( QDomDocument & _doc, QDomElement & _this ); - virtual void loadSettings( const QDomElement & _this ); + void saveSettings( QDomDocument & _doc, QDomElement & _this ) override; + void loadSettings( const QDomElement & _this ) override; inline FxLine * currentFxLine() { @@ -110,7 +110,7 @@ public slots: int addNewChannel(); protected: - virtual void closeEvent( QCloseEvent * _ce ); + void closeEvent( QCloseEvent * _ce ) override; private slots: void updateFaders(); diff --git a/include/Graph.h b/include/Graph.h index 1bee05c41..2a6fc4f8a 100644 --- a/include/Graph.h +++ b/include/Graph.h @@ -87,19 +87,19 @@ public: signals: void drawn(); protected: - virtual void paintEvent( QPaintEvent * _pe ); - virtual void dropEvent( QDropEvent * _de ); - virtual void dragEnterEvent( QDragEnterEvent * _dee ); - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void mouseMoveEvent( QMouseEvent * _me ); - virtual void mouseReleaseEvent( QMouseEvent * _me ); + void paintEvent( QPaintEvent * _pe ) override; + void dropEvent( QDropEvent * _de ) override; + void dragEnterEvent( QDragEnterEvent * _dee ) override; + void mousePressEvent( QMouseEvent * _me ) override; + void mouseMoveEvent( QMouseEvent * _me ) override; + void mouseReleaseEvent( QMouseEvent * _me ) override; protected slots: void updateGraph( int _startPos, int _endPos ); void updateGraph(); private: - virtual void modelChanged(); + void modelChanged() override; void changeSampleAt( int _x, int _y ); void drawLineAt( int _x, int _y, int _lastx ); diff --git a/include/GroupBox.h b/include/GroupBox.h index 8a857199f..88428b1aa 100644 --- a/include/GroupBox.h +++ b/include/GroupBox.h @@ -42,7 +42,7 @@ public: GroupBox( const QString & _caption, QWidget * _parent = NULL ); virtual ~GroupBox(); - virtual void modelChanged(); + void modelChanged() override; PixmapButton * ledButton() { @@ -56,8 +56,8 @@ public: protected: - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void paintEvent( QPaintEvent * _pe ); + void mousePressEvent( QMouseEvent * _me ) override; + void paintEvent( QPaintEvent * _pe ) override; private: diff --git a/include/ImportFilter.h b/include/ImportFilter.h index 166c1bfda..ccefd3db2 100644 --- a/include/ImportFilter.h +++ b/include/ImportFilter.h @@ -89,15 +89,15 @@ protected: m_file.ungetChar( _ch ); } - virtual void saveSettings( QDomDocument &, QDomElement & ) + void saveSettings( QDomDocument &, QDomElement & ) override { } - virtual void loadSettings( const QDomElement & ) + void loadSettings( const QDomElement & ) override { } - virtual QString nodeName() const + QString nodeName() const override { return "import_filter"; } diff --git a/include/InlineAutomation.h b/include/InlineAutomation.h index d70121a45..431ecbc81 100644 --- a/include/InlineAutomation.h +++ b/include/InlineAutomation.h @@ -79,8 +79,8 @@ public: return m_autoPattern; } - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; + void loadSettings( const QDomElement & _this ) override; private: diff --git a/include/Instrument.h b/include/Instrument.h index 2179a1f72..438197cd8 100644 --- a/include/Instrument.h +++ b/include/Instrument.h @@ -110,7 +110,7 @@ public: return true; } - virtual QString fullDisplayName() const; + QString fullDisplayName() const override; // -------------------------------------------------------------------- // provided functions: diff --git a/include/InstrumentFunctionViews.h b/include/InstrumentFunctionViews.h index 8ac13e1b9..58f915b15 100644 --- a/include/InstrumentFunctionViews.h +++ b/include/InstrumentFunctionViews.h @@ -49,7 +49,7 @@ public: private: - virtual void modelChanged(); + void modelChanged() override; InstrumentFunctionNoteStacking * m_cc; @@ -72,7 +72,7 @@ public: private: - virtual void modelChanged(); + void modelChanged() override; InstrumentFunctionArpeggio * m_a; GroupBox * m_arpGroupBox; diff --git a/include/InstrumentFunctions.h b/include/InstrumentFunctions.h index 0055c6c97..b45484e71 100644 --- a/include/InstrumentFunctions.h +++ b/include/InstrumentFunctions.h @@ -54,10 +54,10 @@ public: void processNote( NotePlayHandle* n ); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; + void loadSettings( const QDomElement & _this ) override; - inline virtual QString nodeName() const + inline QString nodeName() const override { return "chordcreator"; } @@ -176,10 +176,10 @@ public: void processNote( NotePlayHandle* n ); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; + void loadSettings( const QDomElement & _this ) override; - inline virtual QString nodeName() const + inline QString nodeName() const override { return "arpeggiator"; } diff --git a/include/InstrumentMidiIOView.h b/include/InstrumentMidiIOView.h index 38f441942..e63b48425 100644 --- a/include/InstrumentMidiIOView.h +++ b/include/InstrumentMidiIOView.h @@ -47,7 +47,7 @@ public: private: - virtual void modelChanged(); + void modelChanged() override; GroupBox * m_midiInputGroupBox; LcdSpinBox * m_inputChannelSpinBox; diff --git a/include/InstrumentPlayHandle.h b/include/InstrumentPlayHandle.h index 426b413ce..ac5fc3222 100644 --- a/include/InstrumentPlayHandle.h +++ b/include/InstrumentPlayHandle.h @@ -40,7 +40,7 @@ public: } - virtual void play( sampleFrame * _working_buffer ) + void play( sampleFrame * _working_buffer ) override { // ensure that all our nph's have been processed first ConstNotePlayHandleList nphv = NotePlayHandle::nphsOfInstrumentTrack( m_instrument->instrumentTrack(), true ); @@ -65,12 +65,12 @@ public: m_instrument->play( _working_buffer ); } - virtual bool isFinished() const + bool isFinished() const override { return false; } - virtual bool isFromTrack( const Track* _track ) const + bool isFromTrack( const Track* _track ) const override { return m_instrument->isFromTrack( _track ); } diff --git a/include/InstrumentSoundShaping.h b/include/InstrumentSoundShaping.h index a159f8380..1b8df38d3 100644 --- a/include/InstrumentSoundShaping.h +++ b/include/InstrumentSoundShaping.h @@ -57,9 +57,9 @@ public: float volumeLevel( NotePlayHandle * _n, const f_cnt_t _frame ); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); - inline virtual QString nodeName() const + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; + void loadSettings( const QDomElement & _this ) override; + inline QString nodeName() const override { return "eldata"; } diff --git a/include/InstrumentSoundShapingView.h b/include/InstrumentSoundShapingView.h index a409e8446..06d53232c 100644 --- a/include/InstrumentSoundShapingView.h +++ b/include/InstrumentSoundShapingView.h @@ -50,7 +50,7 @@ public: private: - virtual void modelChanged(); + void modelChanged() override; InstrumentSoundShaping * m_ss; diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index 72e0d04cc..d72331e52 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -80,8 +80,8 @@ public: MidiEvent applyMasterKey( const MidiEvent& event ); - virtual void processInEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 ); - virtual void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 ); + void processInEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 ) override; + void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime(), f_cnt_t offset = 0 ) override; // silence all running notes played by this track void silenceAllNotes( bool removeIPH = false ); @@ -111,7 +111,7 @@ public: void deleteNotePluginData( NotePlayHandle * _n ); // name-stuff - virtual void setName( const QString & _new_name ); + void setName( const QString & _new_name ) override; // translate given key of a note-event to absolute key (i.e. // add global master-pitch and base-note of this instrument track) @@ -131,18 +131,18 @@ public: // play everything in given frame-range - creates note-play-handles virtual bool play( const MidiTime & _start, const fpp_t _frames, - const f_cnt_t _frame_base, int _tco_num = -1 ); + const f_cnt_t _frame_base, int _tco_num = -1 ) override; // create new view for me - virtual TrackView * createView( TrackContainerView* tcv ); + TrackView * createView( TrackContainerView* tcv ) override; // create new track-content-object = pattern - virtual TrackContentObject * createTCO( const MidiTime & _pos ); + TrackContentObject * createTCO( const MidiTime & _pos ) override; // called by track virtual void saveTrackSpecificSettings( QDomDocument & _doc, - QDomElement & _parent ); - virtual void loadTrackSpecificSettings( const QDomElement & _this ); + QDomElement & _parent ) override; + void loadTrackSpecificSettings( const QDomElement & _this ) override; using Track::setJournalling; @@ -225,7 +225,7 @@ signals: protected: - virtual QString nodeName() const + QString nodeName() const override { return "instrumenttrack"; } @@ -317,12 +317,12 @@ public: static void cleanupWindowCache(); // Create a menu for assigning/creating channels for this track - QMenu * createFxMenu( QString title, QString newFxLabel ); + QMenu * createFxMenu( QString title, QString newFxLabel ) override; protected: - virtual void dragEnterEvent( QDragEnterEvent * _dee ); - virtual void dropEvent( QDropEvent * _de ); + void dragEnterEvent( QDragEnterEvent * _dee ) override; + void dropEvent( QDropEvent * _de ) override; private slots: @@ -404,8 +404,8 @@ public: static void dragEnterEventGeneric( QDragEnterEvent * _dee ); - virtual void dragEnterEvent( QDragEnterEvent * _dee ); - virtual void dropEvent( QDropEvent * _de ); + void dragEnterEvent( QDragEnterEvent * _dee ) override; + void dropEvent( QDropEvent * _de ) override; public slots: @@ -417,11 +417,11 @@ public slots: protected: // capture close-events for toggling instrument-track-button - virtual void closeEvent( QCloseEvent * _ce ); - virtual void focusInEvent( QFocusEvent * _fe ); + void closeEvent( QCloseEvent * _ce ) override; + void focusInEvent( QFocusEvent * _fe ) override; - virtual void saveSettings( QDomDocument & _doc, QDomElement & _this ); - virtual void loadSettings( const QDomElement & _this ); + void saveSettings( QDomDocument & _doc, QDomElement & _this ) override; + void loadSettings( const QDomElement & _this ) override; protected slots: @@ -430,7 +430,7 @@ protected slots: void viewPrevInstrument(); private: - virtual void modelChanged(); + void modelChanged() override; void viewInstrumentInDirection(int d); //! adjust size of any child widget of the main tab //! required to keep the old look when using a variable sized tab widget diff --git a/include/JournallingObject.h b/include/JournallingObject.h index 6974bef84..f4755994b 100644 --- a/include/JournallingObject.h +++ b/include/JournallingObject.h @@ -59,9 +59,9 @@ public: void addJournalCheckPoint(); virtual QDomElement saveState( QDomDocument & _doc, - QDomElement & _parent ); + QDomElement & _parent ) override; - virtual void restoreState( const QDomElement & _this ); + void restoreState( const QDomElement & _this ) override; inline bool isJournalling() const { diff --git a/include/Knob.h b/include/Knob.h index b8d460f45..4f8064731 100644 --- a/include/Knob.h +++ b/include/Knob.h @@ -124,16 +124,16 @@ signals: protected: - virtual void contextMenuEvent( QContextMenuEvent * _me ); - virtual void dragEnterEvent( QDragEnterEvent * _dee ); - virtual void dropEvent( QDropEvent * _de ); - virtual void focusOutEvent( QFocusEvent * _fe ); - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void mouseReleaseEvent( QMouseEvent * _me ); - virtual void mouseMoveEvent( QMouseEvent * _me ); - virtual void mouseDoubleClickEvent( QMouseEvent * _me ); - virtual void paintEvent( QPaintEvent * _me ); - virtual void wheelEvent( QWheelEvent * _me ); + void contextMenuEvent( QContextMenuEvent * _me ) override; + void dragEnterEvent( QDragEnterEvent * _dee ) override; + void dropEvent( QDropEvent * _de ) override; + void focusOutEvent( QFocusEvent * _fe ) override; + void mousePressEvent( QMouseEvent * _me ) override; + void mouseReleaseEvent( QMouseEvent * _me ) override; + void mouseMoveEvent( QMouseEvent * _me ) override; + void mouseDoubleClickEvent( QMouseEvent * _me ) override; + void paintEvent( QPaintEvent * _me ) override; + void wheelEvent( QWheelEvent * _me ) override; virtual float getValue( const QPoint & _p ); @@ -145,7 +145,7 @@ private slots: private: QString displayValue() const; - virtual void doConnections(); + void doConnections() override; QLineF calculateLine( const QPointF & _mid, float _radius, float _innerRadius = 1) const; diff --git a/include/LadspaControl.h b/include/LadspaControl.h index 2ad895b3f..34f6c9ae2 100644 --- a/include/LadspaControl.h +++ b/include/LadspaControl.h @@ -74,7 +74,7 @@ public: virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent, const QString & _name ); virtual void loadSettings( const QDomElement & _this, const QString & _name ); - inline virtual QString nodeName() const + inline QString nodeName() const override { return "port"; } @@ -92,13 +92,13 @@ protected slots: void linkStateChanged(); protected: - virtual void saveSettings( QDomDocument& doc, QDomElement& element ) + void saveSettings( QDomDocument& doc, QDomElement& element ) override { Q_UNUSED(doc) Q_UNUSED(element) } - virtual void loadSettings( const QDomElement& element ) + void loadSettings( const QDomElement& element ) override { Q_UNUSED(element) } diff --git a/include/LcdSpinBox.h b/include/LcdSpinBox.h index b63dfaa40..379b743ac 100644 --- a/include/LcdSpinBox.h +++ b/include/LcdSpinBox.h @@ -40,7 +40,7 @@ public: virtual ~LcdSpinBox() = default; - virtual void modelChanged() + void modelChanged() override { ModelView::modelChanged(); update(); @@ -65,12 +65,12 @@ public slots: protected: - virtual void contextMenuEvent( QContextMenuEvent * _me ); - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void mouseMoveEvent( QMouseEvent * _me ); - virtual void mouseReleaseEvent( QMouseEvent * _me ); - virtual void wheelEvent( QWheelEvent * _we ); - virtual void mouseDoubleClickEvent( QMouseEvent * _me ); + void contextMenuEvent( QContextMenuEvent * _me ) override; + void mousePressEvent( QMouseEvent * _me ) override; + void mouseMoveEvent( QMouseEvent * _me ) override; + void mouseReleaseEvent( QMouseEvent * _me ) override; + void wheelEvent( QWheelEvent * _we ) override; + void mouseDoubleClickEvent( QMouseEvent * _me ) override; private: bool m_mouseMoving; diff --git a/include/LcdWidget.h b/include/LcdWidget.h index db969dd33..f4c7d1579 100644 --- a/include/LcdWidget.h +++ b/include/LcdWidget.h @@ -71,7 +71,7 @@ public slots: protected: - virtual void paintEvent( QPaintEvent * pe ); + void paintEvent( QPaintEvent * pe ) override; virtual void updateSize(); diff --git a/include/LedCheckbox.h b/include/LedCheckbox.h index 723bae6a9..66d7ce07e 100644 --- a/include/LedCheckbox.h +++ b/include/LedCheckbox.h @@ -64,7 +64,7 @@ public: Q_PROPERTY( QString text READ text WRITE setText ) protected: - virtual void paintEvent( QPaintEvent * _pe ); + void paintEvent( QPaintEvent * _pe ) override; private: diff --git a/include/LfoController.h b/include/LfoController.h index 9dfbba671..8fc35fd09 100644 --- a/include/LfoController.h +++ b/include/LfoController.h @@ -49,18 +49,18 @@ public: virtual ~LfoController(); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _this ); - virtual void loadSettings( const QDomElement & _this ); - virtual QString nodeName() const; + void saveSettings( QDomDocument & _doc, QDomElement & _this ) override; + void loadSettings( const QDomElement & _this ) override; + QString nodeName() const override; public slots: - virtual ControllerDialog * createDialog( QWidget * _parent ); + ControllerDialog * createDialog( QWidget * _parent ) override; protected: // The internal per-controller value updating function - virtual void updateValueBuffer(); + void updateValueBuffer() override; FloatModel m_baseModel; TempoSyncKnobModel m_speedModel; @@ -98,8 +98,8 @@ public: protected: - virtual void contextMenuEvent( QContextMenuEvent * _me ); - virtual void modelChanged(); + void contextMenuEvent( QContextMenuEvent * _me ) override; + void modelChanged() override; LfoController * m_lfo; diff --git a/include/LmmsStyle.h b/include/LmmsStyle.h index 88b8a2112..ccf14396c 100644 --- a/include/LmmsStyle.h +++ b/include/LmmsStyle.h @@ -67,21 +67,21 @@ public: { } - virtual QPalette standardPalette( void ) const; + QPalette standardPalette( void ) const override; virtual void drawComplexControl( ComplexControl control, const QStyleOptionComplex * option, QPainter *painter, - const QWidget *widget ) const; + const QWidget *widget ) const override; virtual void drawPrimitive( PrimitiveElement element, const QStyleOption *option, QPainter *painter, - const QWidget *widget = 0 ) const; + const QWidget *widget = 0 ) const override; virtual int pixelMetric( PixelMetric metric, const QStyleOption * option = 0, - const QWidget * widget = 0 ) const; + const QWidget * widget = 0 ) const override; static QPalette * s_palette; diff --git a/include/MainApplication.h b/include/MainApplication.h index 41d670419..d28900213 100644 --- a/include/MainApplication.h +++ b/include/MainApplication.h @@ -42,7 +42,7 @@ class MainApplication : public QApplication { public: MainApplication(int& argc, char** argv); - bool event(QEvent* event); + bool event(QEvent* event) override; #ifdef LMMS_BUILD_WIN32 bool winEventFilter(MSG* msg, long* result); bool nativeEventFilter(const QByteArray& eventType, void* message, diff --git a/include/MainWindow.h b/include/MainWindow.h index 74e569653..5dc102321 100644 --- a/include/MainWindow.h +++ b/include/MainWindow.h @@ -176,11 +176,11 @@ private slots: void onExportProjectMidi(); protected: - virtual void closeEvent( QCloseEvent * _ce ); - virtual void focusOutEvent( QFocusEvent * _fe ); - virtual void keyPressEvent( QKeyEvent * _ke ); - virtual void keyReleaseEvent( QKeyEvent * _ke ); - virtual void timerEvent( QTimerEvent * _ev ); + void closeEvent( QCloseEvent * _ce ) override; + void focusOutEvent( QFocusEvent * _fe ) override; + void keyPressEvent( QKeyEvent * _ke ) override; + void keyReleaseEvent( QKeyEvent * _ke ) override; + void timerEvent( QTimerEvent * _ev ) override; private: diff --git a/include/MeterDialog.h b/include/MeterDialog.h index 5399c4a9a..da254c7c7 100644 --- a/include/MeterDialog.h +++ b/include/MeterDialog.h @@ -40,7 +40,7 @@ public: MeterDialog( QWidget * _parent, bool _simple = false ); virtual ~MeterDialog(); - virtual void modelChanged(); + void modelChanged() override; private: diff --git a/include/MidiAlsaRaw.h b/include/MidiAlsaRaw.h index 81f288c22..69f9366f1 100644 --- a/include/MidiAlsaRaw.h +++ b/include/MidiAlsaRaw.h @@ -62,8 +62,8 @@ public: protected: - virtual void sendByte( const unsigned char c ); - virtual void run(); + void sendByte( const unsigned char c ) override; + void run() override; private: diff --git a/include/MidiAlsaSeq.h b/include/MidiAlsaSeq.h index 0406b42b9..b6e498721 100644 --- a/include/MidiAlsaSeq.h +++ b/include/MidiAlsaSeq.h @@ -67,44 +67,44 @@ public: virtual void processOutEvent( const MidiEvent & _me, const MidiTime & _time, - const MidiPort * _port ); + const MidiPort * _port ) override; - virtual void applyPortMode( MidiPort * _port ); - virtual void applyPortName( MidiPort * _port ); + void applyPortMode( MidiPort * _port ) override; + void applyPortName( MidiPort * _port ) override; - virtual void removePort( MidiPort * _port ); + void removePort( MidiPort * _port ) override; // list seq-ports from ALSA - virtual QStringList readablePorts() const + QStringList readablePorts() const override { return m_readablePorts; } - virtual QStringList writablePorts() const + QStringList writablePorts() const override { return m_writablePorts; } // return name of port which specified MIDI event came from - virtual QString sourcePortName( const MidiEvent & ) const; + QString sourcePortName( const MidiEvent & ) const override; // (un)subscribe given MidiPort to/from destination-port virtual void subscribeReadablePort( MidiPort * _port, const QString & _dest, - bool _subscribe = true ); + bool _subscribe = true ) override; virtual void subscribeWritablePort( MidiPort * _port, const QString & _dest, - bool _subscribe = true ); + bool _subscribe = true ) override; virtual void connectRPChanged( QObject * _receiver, - const char * _member ) + const char * _member ) override { connect( this, SIGNAL( readablePortsChanged() ), _receiver, _member ); } virtual void connectWPChanged( QObject * _receiver, - const char * _member ) + const char * _member ) override { connect( this, SIGNAL( writablePortsChanged() ), _receiver, _member ); @@ -117,7 +117,7 @@ private slots: private: - virtual void run(); + void run() override; #ifdef LMMS_HAVE_ALSA QMutex m_seqMutex; diff --git a/include/MidiClient.h b/include/MidiClient.h index 293f2b3da..f06cac893 100644 --- a/include/MidiClient.h +++ b/include/MidiClient.h @@ -124,7 +124,7 @@ public: virtual ~MidiClientRaw(); // we are raw-clients for sure! - virtual bool isRaw() const + bool isRaw() const override { return true; } @@ -141,7 +141,7 @@ protected: private: // this does MIDI-event-process void processParsedEvent(); - virtual void processOutEvent( const MidiEvent& event, const MidiTime& time, const MidiPort* port ); + void processOutEvent( const MidiEvent& event, const MidiTime& time, const MidiPort* port ) override; // small helper function returning length of a certain event - this // is necessary for parsing raw-MIDI-data diff --git a/include/MidiController.h b/include/MidiController.h index d661b8d0f..43f928a25 100644 --- a/include/MidiController.h +++ b/include/MidiController.h @@ -44,30 +44,30 @@ public: virtual ~MidiController(); virtual void processInEvent( const MidiEvent & _me, - const MidiTime & _time, f_cnt_t offset = 0 ); + const MidiTime & _time, f_cnt_t offset = 0 ) override; virtual void processOutEvent( const MidiEvent& _me, - const MidiTime & _time, f_cnt_t offset = 0 ) + const MidiTime & _time, f_cnt_t offset = 0 ) override { // No output yet } - virtual void saveSettings( QDomDocument & _doc, QDomElement & _this ); - virtual void loadSettings( const QDomElement & _this ); - virtual QString nodeName() const; + void saveSettings( QDomDocument & _doc, QDomElement & _this ) override; + void loadSettings( const QDomElement & _this ) override; + QString nodeName() const override; // Used by controllerConnectionDialog to copy void subscribeReadablePorts( const MidiPort::Map & _map ); public slots: - virtual ControllerDialog * createDialog( QWidget * _parent ); + ControllerDialog * createDialog( QWidget * _parent ) override; void updateName(); protected: // The internal per-controller get-value function - virtual void updateValueBuffer(); + void updateValueBuffer() override; MidiPort m_midiPort; diff --git a/include/MidiDummy.h b/include/MidiDummy.h index dffd1ce51..f809d3c36 100644 --- a/include/MidiDummy.h +++ b/include/MidiDummy.h @@ -56,7 +56,7 @@ public: protected: - virtual void sendByte( const unsigned char ) + void sendByte( const unsigned char ) override { } diff --git a/include/MidiOss.h b/include/MidiOss.h index 27ebf0771..7e1f179ef 100644 --- a/include/MidiOss.h +++ b/include/MidiOss.h @@ -58,8 +58,8 @@ public: } protected: - virtual void sendByte( const unsigned char c ); - virtual void run(); + void sendByte( const unsigned char c ) override; + void run() override; private: diff --git a/include/MidiPort.h b/include/MidiPort.h index 07c61d788..e9cba39ed 100644 --- a/include/MidiPort.h +++ b/include/MidiPort.h @@ -103,10 +103,10 @@ public: void processOutEvent( const MidiEvent& event, const MidiTime& time = MidiTime() ); - virtual void saveSettings( QDomDocument& doc, QDomElement& thisElement ); - virtual void loadSettings( const QDomElement& thisElement ); + void saveSettings( QDomDocument& doc, QDomElement& thisElement ) override; + void loadSettings( const QDomElement& thisElement ) override; - virtual QString nodeName() const + QString nodeName() const override { return "midiport"; } diff --git a/include/MidiPortMenu.h b/include/MidiPortMenu.h index b963a7bd9..ce39c4aac 100644 --- a/include/MidiPortMenu.h +++ b/include/MidiPortMenu.h @@ -51,7 +51,7 @@ protected slots: private: - virtual void modelChanged(); + void modelChanged() override; MidiPort::Modes m_mode; diff --git a/include/MidiSndio.h b/include/MidiSndio.h index d115993fe..14ecfa0e9 100644 --- a/include/MidiSndio.h +++ b/include/MidiSndio.h @@ -59,8 +59,8 @@ public: protected: - virtual void sendByte(const unsigned char c); - virtual void run(void); + void sendByte(const unsigned char c) override; + void run(void) override; private: struct mio_hdl *m_hdl; diff --git a/include/Mixer.h b/include/Mixer.h index 69ea0d12d..32eeb8977 100644 --- a/include/Mixer.h +++ b/include/Mixer.h @@ -345,7 +345,7 @@ private: fifo * m_fifo; volatile bool m_writing; - virtual void run(); + void run() override; void write( surroundSampleFrame * buffer ); diff --git a/include/MixerWorkerThread.h b/include/MixerWorkerThread.h index 7c3792392..2d49dce09 100644 --- a/include/MixerWorkerThread.h +++ b/include/MixerWorkerThread.h @@ -106,7 +106,7 @@ public: private: - virtual void run(); + void run() override; static JobQueue globalJobQueue; static QWaitCondition * queueReadyWaitCond; diff --git a/include/NStateButton.h b/include/NStateButton.h index d9e56b892..95d36c253 100644 --- a/include/NStateButton.h +++ b/include/NStateButton.h @@ -61,7 +61,7 @@ signals: protected: - virtual void mousePressEvent( QMouseEvent * _me ); + void mousePressEvent( QMouseEvent * _me ) override; private: diff --git a/include/Note.h b/include/Note.h index 0eae8f6b0..30969b4c8 100644 --- a/include/Note.h +++ b/include/Note.h @@ -200,7 +200,7 @@ public: return "note"; } - inline virtual QString nodeName() const + inline QString nodeName() const override { return classNodeName(); } @@ -218,8 +218,8 @@ public: protected: - virtual void saveSettings( QDomDocument & doc, QDomElement & parent ); - virtual void loadSettings( const QDomElement & _this ); + void saveSettings( QDomDocument & doc, QDomElement & parent ) override; + void loadSettings( const QDomElement & _this ) override; private: diff --git a/include/NotePlayHandle.h b/include/NotePlayHandle.h index ae55c9ebb..3dba0f277 100644 --- a/include/NotePlayHandle.h +++ b/include/NotePlayHandle.h @@ -74,8 +74,8 @@ public: return p; } - virtual void setVolume( volume_t volume ); - virtual void setPanning( panning_t panning ); + void setVolume( volume_t volume ) override; + void setPanning( panning_t panning ) override; int midiKey() const; int midiChannel() const @@ -105,10 +105,10 @@ public: } /*! Renders one chunk using the attached instrument into the buffer */ - virtual void play( sampleFrame* buffer ); + void play( sampleFrame* buffer ) override; /*! Returns whether playback of note is finished and thus handle can be deleted */ - virtual bool isFinished() const + bool isFinished() const override { return m_released && framesLeft() <= 0; } @@ -120,7 +120,7 @@ public: fpp_t framesLeftForCurrentPeriod() const; /*! Returns whether the play handle plays on a certain track */ - virtual bool isFromTrack( const Track* _track ) const; + bool isFromTrack( const Track* _track ) const override; /*! Releases the note (and plays release frames */ void noteOff( const f_cnt_t offset = 0 ); diff --git a/include/Pattern.h b/include/Pattern.h index 3a1cc941c..5192da9fa 100644 --- a/include/Pattern.h +++ b/include/Pattern.h @@ -94,9 +94,9 @@ public: Pattern * nextPattern() const; // settings-management - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); - inline virtual QString nodeName() const + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; + void loadSettings( const QDomElement & _this ) override; + inline QString nodeName() const override { return "pattern"; } @@ -109,7 +109,7 @@ public: bool empty(); - virtual TrackContentObjectView * createView( TrackView * _tv ); + TrackContentObjectView * createView( TrackView * _tv ) override; using Model::dataChanged; @@ -182,7 +182,7 @@ public: void setMutedNoteBorderColor(QColor const & color) { m_mutedNoteBorderColor = color; } public slots: - virtual void update(); + void update() override; protected slots: @@ -194,11 +194,11 @@ protected slots: protected: - virtual void constructContextMenu( QMenu * ); - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void mouseDoubleClickEvent( QMouseEvent * _me ); - virtual void paintEvent( QPaintEvent * pe ); - virtual void wheelEvent( QWheelEvent * _we ); + void constructContextMenu( QMenu * ) override; + void mousePressEvent( QMouseEvent * _me ) override; + void mouseDoubleClickEvent( QMouseEvent * _me ) override; + void paintEvent( QPaintEvent * pe ) override; + void wheelEvent( QWheelEvent * _we ) override; private: diff --git a/include/PeakController.h b/include/PeakController.h index b2824f0ac..74a3aab59 100644 --- a/include/PeakController.h +++ b/include/PeakController.h @@ -46,9 +46,9 @@ public: virtual ~PeakController(); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _this ); - virtual void loadSettings( const QDomElement & _this ); - virtual QString nodeName() const; + void saveSettings( QDomDocument & _doc, QDomElement & _this ) override; + void loadSettings( const QDomElement & _this ) override; + QString nodeName() const override; static void initGetControllerBySetting(); static PeakController * getControllerBySetting( const QDomElement & _this ); @@ -57,13 +57,13 @@ public: public slots: - virtual ControllerDialog * createDialog( QWidget * _parent ); + ControllerDialog * createDialog( QWidget * _parent ) override; void handleDestroyedEffect( ); void updateCoeffs(); protected: // The internal per-controller get-value function - virtual void updateValueBuffer(); + void updateValueBuffer() override; PeakControllerEffect * m_peakEffect; @@ -91,9 +91,9 @@ public: virtual ~PeakControllerDialog(); protected: - virtual void contextMenuEvent( QContextMenuEvent * _me ); - virtual void paintEvent( QPaintEvent * _pe ); - virtual void modelChanged(); + void contextMenuEvent( QContextMenuEvent * _me ) override; + void paintEvent( QPaintEvent * _pe ) override; + void modelChanged() override; PeakController * m_peakController; diff --git a/include/PianoRoll.h b/include/PianoRoll.h index b600385c8..27a15149e 100644 --- a/include/PianoRoll.h +++ b/include/PianoRoll.h @@ -167,17 +167,17 @@ public: protected: - virtual void keyPressEvent( QKeyEvent * ke ); - virtual void keyReleaseEvent( QKeyEvent * ke ); - virtual void leaveEvent( QEvent * e ); - virtual void mousePressEvent( QMouseEvent * me ); - virtual void mouseDoubleClickEvent( QMouseEvent * me ); - virtual void mouseReleaseEvent( QMouseEvent * me ); - virtual void mouseMoveEvent( QMouseEvent * me ); - virtual void paintEvent( QPaintEvent * pe ); - virtual void resizeEvent( QResizeEvent * re ); - virtual void wheelEvent( QWheelEvent * we ); - virtual void focusOutEvent( QFocusEvent * ); + void keyPressEvent( QKeyEvent * ke ) override; + void keyReleaseEvent( QKeyEvent * ke ) override; + void leaveEvent( QEvent * e ) override; + void mousePressEvent( QMouseEvent * me ) override; + void mouseDoubleClickEvent( QMouseEvent * me ) override; + void mouseReleaseEvent( QMouseEvent * me ) override; + void mouseMoveEvent( QMouseEvent * me ) override; + void paintEvent( QPaintEvent * pe ) override; + void resizeEvent( QResizeEvent * re ) override; + void wheelEvent( QWheelEvent * we ) override; + void focusOutEvent( QFocusEvent * ) override; int getKey( int y ) const; static void drawNoteRect( QPainter & p, int x, int y, @@ -460,11 +460,11 @@ public: int quantization() const; - void play(); - void stop(); - void record(); - void recordAccompany(); - void toggleStepRecording(); + void play() override; + void stop() override; + void record() override; + void recordAccompany() override; + void toggleStepRecording() override; void stopRecording(); bool isRecording() const; @@ -474,15 +474,15 @@ public: using SerializingObject::saveState; using SerializingObject::restoreState; - virtual void saveSettings(QDomDocument & doc, QDomElement & de ); - virtual void loadSettings( const QDomElement & de ); + void saveSettings(QDomDocument & doc, QDomElement & de ) override; + void loadSettings( const QDomElement & de ) override; - inline virtual QString nodeName() const + inline QString nodeName() const override { return "pianoroll"; } - QSize sizeHint() const; + QSize sizeHint() const override; signals: void currentPatternChanged(); @@ -494,7 +494,7 @@ private slots: private: void patternRenamed(); - void focusInEvent(QFocusEvent * event); + void focusInEvent(QFocusEvent * event) override; void stopStepRecording(); void updateStepRecordingIcon(); diff --git a/include/PianoView.h b/include/PianoView.h index 2a362c584..b793ee768 100644 --- a/include/PianoView.h +++ b/include/PianoView.h @@ -44,19 +44,19 @@ public: public: - virtual void keyPressEvent( QKeyEvent * ke ); - virtual void keyReleaseEvent( QKeyEvent * ke ); + void keyPressEvent( QKeyEvent * ke ) override; + void keyReleaseEvent( QKeyEvent * ke ) override; protected: - virtual void modelChanged(); - virtual void contextMenuEvent( QContextMenuEvent * _me ); - virtual void paintEvent( QPaintEvent * ); - virtual void mousePressEvent( QMouseEvent * me ); - virtual void mouseReleaseEvent( QMouseEvent * me ); - virtual void mouseMoveEvent( QMouseEvent * me ); - virtual void focusOutEvent( QFocusEvent * _fe ); - virtual void resizeEvent( QResizeEvent * _event ); + void modelChanged() override; + void contextMenuEvent( QContextMenuEvent * _me ) override; + void paintEvent( QPaintEvent * ) override; + void mousePressEvent( QMouseEvent * me ) override; + void mouseReleaseEvent( QMouseEvent * me ) override; + void mouseMoveEvent( QMouseEvent * me ) override; + void focusOutEvent( QFocusEvent * _fe ) override; + void resizeEvent( QResizeEvent * _event ) override; private: diff --git a/include/PixmapButton.h b/include/PixmapButton.h index 6ee7bcdc8..e2fb58885 100644 --- a/include/PixmapButton.h +++ b/include/PixmapButton.h @@ -42,17 +42,17 @@ public: void setActiveGraphic( const QPixmap & _pm ); void setInactiveGraphic( const QPixmap & _pm, bool _update = true ); - QSize sizeHint() const; + QSize sizeHint() const override; signals: void doubleClicked(); protected: - virtual void paintEvent( QPaintEvent * _pe ); - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void mouseReleaseEvent( QMouseEvent * _me ); - virtual void mouseDoubleClickEvent( QMouseEvent * _me ); + void paintEvent( QPaintEvent * _pe ) override; + void mousePressEvent( QMouseEvent * _me ) override; + void mouseReleaseEvent( QMouseEvent * _me ) override; + void mouseDoubleClickEvent( QMouseEvent * _me ) override; private: diff --git a/include/PlayHandle.h b/include/PlayHandle.h index 1760e1ec7..1ddd632d1 100644 --- a/include/PlayHandle.h +++ b/include/PlayHandle.h @@ -87,9 +87,9 @@ public: } // required for ThreadableJob - virtual void doProcessing(); + void doProcessing() override; - virtual bool requiresProcessing() const + bool requiresProcessing() const override { return !isFinished(); } diff --git a/include/Plugin.h b/include/Plugin.h index af42b0f10..cb8995bf2 100644 --- a/include/Plugin.h +++ b/include/Plugin.h @@ -239,7 +239,7 @@ public: virtual ~Plugin(); //! Return display-name out of sub plugin or descriptor - virtual QString displayName() const; + QString displayName() const override; //! Return logo out of sub plugin or descriptor const PixmapLoader *logo() const; diff --git a/include/PresetPreviewPlayHandle.h b/include/PresetPreviewPlayHandle.h index 57996fa17..a95b680ab 100644 --- a/include/PresetPreviewPlayHandle.h +++ b/include/PresetPreviewPlayHandle.h @@ -38,15 +38,15 @@ public: PresetPreviewPlayHandle( const QString& presetFile, bool loadByPlugin = false, DataFile *dataFile = 0 ); virtual ~PresetPreviewPlayHandle(); - virtual inline bool affinityMatters() const + inline bool affinityMatters() const override { return true; } - virtual void play( sampleFrame* buffer ); - virtual bool isFinished() const; + void play( sampleFrame* buffer ) override; + bool isFinished() const override; - virtual bool isFromTrack( const Track * _track ) const; + bool isFromTrack( const Track * _track ) const override; static void init(); static void cleanup(); diff --git a/include/ProjectNotes.h b/include/ProjectNotes.h index ab82e4eeb..fc97a8844 100644 --- a/include/ProjectNotes.h +++ b/include/ProjectNotes.h @@ -47,17 +47,17 @@ public: void clear(); void setText( const QString & _text ); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; + void loadSettings( const QDomElement & _this ) override; - inline virtual QString nodeName() const + inline QString nodeName() const override { return "projectnotes"; } protected: - virtual void closeEvent( QCloseEvent * _ce ); + void closeEvent( QCloseEvent * _ce ) override; void setupActions(); diff --git a/include/ProjectRenderer.h b/include/ProjectRenderer.h index 4f932ad34..1af9d422d 100644 --- a/include/ProjectRenderer.h +++ b/include/ProjectRenderer.h @@ -86,7 +86,7 @@ signals: private: - virtual void run(); + void run() override; AudioFileDevice * m_fileDev; Mixer::qualitySettings m_qualitySettings; diff --git a/include/RemotePlugin.h b/include/RemotePlugin.h index 27c658a3d..862370d1f 100644 --- a/include/RemotePlugin.h +++ b/include/RemotePlugin.h @@ -766,7 +766,7 @@ public: } private: - virtual void run(); + void run() override; RemotePlugin * m_plugin; volatile bool m_quit; @@ -803,7 +803,7 @@ public: m_failed = waitForMessage( IdInitDone, _busyWaiting ).id != IdInitDone; } - virtual bool processMessage( const message & _m ); + bool processMessage( const message & _m ) override; bool process( const sampleFrame * _in_buf, sampleFrame * _out_buf ); diff --git a/include/RenameDialog.h b/include/RenameDialog.h index c1d24a8a9..8f526badd 100644 --- a/include/RenameDialog.h +++ b/include/RenameDialog.h @@ -42,8 +42,8 @@ public: protected: - void keyPressEvent( QKeyEvent * _ke ); - virtual void resizeEvent(QResizeEvent * event); + void keyPressEvent( QKeyEvent * _ke ) override; + void resizeEvent(QResizeEvent * event) override; protected slots: diff --git a/include/RowTableView.h b/include/RowTableView.h index 537792a05..a7b07c2c8 100644 --- a/include/RowTableView.h +++ b/include/RowTableView.h @@ -38,11 +38,11 @@ public: RowTableView( QWidget * parent = 0 ); virtual ~RowTableView(); - virtual void setModel( QAbstractItemModel * model ); + void setModel( QAbstractItemModel * model ) override; protected: - virtual void keyPressEvent( QKeyEvent * event ); + void keyPressEvent( QKeyEvent * event ) override; private: diff --git a/include/Rubberband.h b/include/Rubberband.h index bc9f3c6a2..eeb3c7e5b 100644 --- a/include/Rubberband.h +++ b/include/Rubberband.h @@ -83,7 +83,7 @@ public: protected: - virtual void resizeEvent( QResizeEvent * _re ); + void resizeEvent( QResizeEvent * _re ) override; private: diff --git a/include/SamplePlayHandle.h b/include/SamplePlayHandle.h index d10c44837..33f5ebe52 100644 --- a/include/SamplePlayHandle.h +++ b/include/SamplePlayHandle.h @@ -44,16 +44,16 @@ public: SamplePlayHandle( SampleTCO* tco ); virtual ~SamplePlayHandle(); - virtual inline bool affinityMatters() const + inline bool affinityMatters() const override { return true; } - virtual void play( sampleFrame * buffer ); - virtual bool isFinished() const; + void play( sampleFrame * buffer ) override; + bool isFinished() const override; - virtual bool isFromTrack( const Track * _track ) const; + bool isFromTrack( const Track * _track ) const override; f_cnt_t totalFrames() const; inline f_cnt_t framesDone() const diff --git a/include/SampleRecordHandle.h b/include/SampleRecordHandle.h index 22d9bf315..fc40d0622 100644 --- a/include/SampleRecordHandle.h +++ b/include/SampleRecordHandle.h @@ -44,10 +44,10 @@ public: SampleRecordHandle( SampleTCO* tco ); virtual ~SampleRecordHandle(); - virtual void play( sampleFrame * _working_buffer ); - virtual bool isFinished() const; + void play( sampleFrame * _working_buffer ) override; + bool isFinished() const override; - virtual bool isFromTrack( const Track * _track ) const; + bool isFromTrack( const Track * _track ) const override; f_cnt_t framesRecorded() const; void createSampleBuffer( SampleBuffer * * _sample_buf ); diff --git a/include/SampleTrack.h b/include/SampleTrack.h index 9469669a1..2bad4d910 100644 --- a/include/SampleTrack.h +++ b/include/SampleTrack.h @@ -49,12 +49,12 @@ public: SampleTCO( Track * _track ); virtual ~SampleTCO(); - virtual void changeLength( const MidiTime & _length ); + void changeLength( const MidiTime & _length ) override; const QString & sampleFile() const; - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); - inline virtual QString nodeName() const + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; + void loadSettings( const QDomElement & _this ) override; + inline QString nodeName() const override { return "sampletco"; } @@ -67,7 +67,7 @@ public: MidiTime sampleLength() const; void setSampleStartFrame( f_cnt_t startFrame ); void setSamplePlayLength( f_cnt_t length ); - virtual TrackContentObjectView * createView( TrackView * _tv ); + TrackContentObjectView * createView( TrackView * _tv ) override; bool isPlaying() const; @@ -112,13 +112,13 @@ public slots: protected: - virtual void contextMenuEvent( QContextMenuEvent * _cme ); - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void mouseReleaseEvent( QMouseEvent * _me ); - virtual void dragEnterEvent( QDragEnterEvent * _dee ); - virtual void dropEvent( QDropEvent * _de ); - virtual void mouseDoubleClickEvent( QMouseEvent * ); - virtual void paintEvent( QPaintEvent * ); + void contextMenuEvent( QContextMenuEvent * _cme ) override; + void mousePressEvent( QMouseEvent * _me ) override; + void mouseReleaseEvent( QMouseEvent * _me ) override; + void dragEnterEvent( QDragEnterEvent * _dee ) override; + void dropEvent( QDropEvent * _de ) override; + void mouseDoubleClickEvent( QMouseEvent * ) override; + void paintEvent( QPaintEvent * ) override; private: @@ -137,14 +137,14 @@ public: virtual ~SampleTrack(); virtual bool play( const MidiTime & _start, const fpp_t _frames, - const f_cnt_t _frame_base, int _tco_num = -1 ); - virtual TrackView * createView( TrackContainerView* tcv ); - virtual TrackContentObject * createTCO(const MidiTime & pos); + const f_cnt_t _frame_base, int _tco_num = -1 ) override; + TrackView * createView( TrackContainerView* tcv ) override; + TrackContentObject * createTCO( const MidiTime & _pos ) override; virtual void saveTrackSpecificSettings( QDomDocument & _doc, - QDomElement & _parent ); - virtual void loadTrackSpecificSettings( const QDomElement & _this ); + QDomElement & _parent ) override; + void loadTrackSpecificSettings( const QDomElement & _this ) override; inline IntModel * effectChannelModel() { @@ -156,7 +156,7 @@ public: return &m_audioPort; } - virtual QString nodeName() const + QString nodeName() const override { return "sampletrack"; } @@ -204,7 +204,7 @@ public: } - virtual QMenu * createFxMenu( QString title, QString newFxLabel ); + QMenu * createFxMenu( QString title, QString newFxLabel ) override; public slots: @@ -212,14 +212,14 @@ public slots: protected: - void modelChanged(); - virtual QString nodeName() const + void modelChanged() override; + QString nodeName() const override { return "SampleTrackView"; } - void dragEnterEvent(QDragEnterEvent *dee); - void dropEvent(QDropEvent *de); + void dragEnterEvent(QDragEnterEvent *dee) override; + void dropEvent(QDropEvent *de) override; private slots: void assignFxLine( int channelIndex ); @@ -273,13 +273,13 @@ public slots: protected: // capture close-events for toggling sample-track-button - virtual void closeEvent(QCloseEvent * ce); + void closeEvent(QCloseEvent * ce) override; - virtual void saveSettings(QDomDocument & doc, QDomElement & element); - virtual void loadSettings(const QDomElement & element); + void saveSettings(QDomDocument & doc, QDomElement & element) override; + void loadSettings(const QDomElement & element) override; private: - virtual void modelChanged(); + void modelChanged() override; SampleTrack * m_track; SampleTrackView * m_stv; diff --git a/include/SendButtonIndicator.h b/include/SendButtonIndicator.h index 97acde1ba..b60113758 100644 --- a/include/SendButtonIndicator.h +++ b/include/SendButtonIndicator.h @@ -17,7 +17,7 @@ public: SendButtonIndicator( QWidget * _parent, FxLine * _owner, FxMixerView * _mv); - virtual void mousePressEvent( QMouseEvent * e ); + void mousePressEvent( QMouseEvent * e ) override; void updateLightStatus(); private: diff --git a/include/SetupDialog.h b/include/SetupDialog.h index 4a2e5c025..9f9ae1b3f 100644 --- a/include/SetupDialog.h +++ b/include/SetupDialog.h @@ -63,7 +63,7 @@ public: protected slots: - virtual void accept(); + void accept() override; private slots: diff --git a/include/SideBarWidget.h b/include/SideBarWidget.h index 37acc9770..9972daa7c 100644 --- a/include/SideBarWidget.h +++ b/include/SideBarWidget.h @@ -52,9 +52,9 @@ signals: void closeButtonClicked(); protected: - virtual void paintEvent( QPaintEvent * _pe ); - virtual void resizeEvent( QResizeEvent * _re ); - virtual void contextMenuEvent( QContextMenuEvent * ) + void paintEvent( QPaintEvent * _pe ) override; + void resizeEvent( QResizeEvent * _re ) override; + void contextMenuEvent( QContextMenuEvent * ) override { } diff --git a/include/Song.h b/include/Song.h index 1e047caaa..d398a168c 100644 --- a/include/Song.h +++ b/include/Song.h @@ -261,7 +261,7 @@ public: bpm_t getTempo(); - virtual AutomationPattern * tempoAutomationPattern(); + AutomationPattern * tempoAutomationPattern() override; AutomationTrack * globalAutomationTrack() { @@ -269,7 +269,7 @@ public: } //TODO: Add Q_DECL_OVERRIDE when Qt4 is dropped - AutomatedValueMap automatedValuesAt(MidiTime time, int tcoNum = -1) const; + AutomatedValueMap automatedValuesAt(MidiTime time, int tcoNum = -1) const override; // file management void createNewProject(); @@ -305,7 +305,7 @@ public: return m_modified; } - virtual QString nodeName() const + QString nodeName() const override { return "song"; } diff --git a/include/SongEditor.h b/include/SongEditor.h index 6f39cc1d9..9621bcc23 100644 --- a/include/SongEditor.h +++ b/include/SongEditor.h @@ -51,7 +51,7 @@ public: positionLine( QWidget * parent ); private: - virtual void paintEvent( QPaintEvent * pe ); + void paintEvent( QPaintEvent * pe ) override; } ; @@ -69,8 +69,8 @@ public: SongEditor( Song * song ); ~SongEditor(); - void saveSettings( QDomDocument& doc, QDomElement& element ); - void loadSettings( const QDomElement& element ); + void saveSettings( QDomDocument& doc, QDomElement& element ) override; + void loadSettings( const QDomElement& element ) override; ComboBoxModel *zoomingModel() const; ComboBoxModel *snappingModel() const; @@ -93,10 +93,10 @@ public slots: void selectAllTcos( bool select ); protected: - virtual void closeEvent( QCloseEvent * ce ); - virtual void mousePressEvent(QMouseEvent * me); - virtual void mouseMoveEvent(QMouseEvent * me); - virtual void mouseReleaseEvent(QMouseEvent * me); + void closeEvent( QCloseEvent * ce ) override; + void mousePressEvent(QMouseEvent * me) override; + void mouseMoveEvent(QMouseEvent * me) override; + void mouseReleaseEvent(QMouseEvent * me) override; private slots: void setHighQuality( bool ); @@ -116,10 +116,10 @@ private slots: void zoomingChanged(); private: - virtual void keyPressEvent( QKeyEvent * ke ); - virtual void wheelEvent( QWheelEvent * we ); + void keyPressEvent( QKeyEvent * ke ) override; + void wheelEvent( QWheelEvent * we ) override; - virtual bool allowRubberband() const; + bool allowRubberband() const override; int trackIndexFromSelectionPoint(int yPos); int indexOfTrackView(const TrackView* tv); @@ -175,19 +175,19 @@ class SongEditorWindow : public Editor public: SongEditorWindow( Song* song ); - QSize sizeHint() const; + QSize sizeHint() const override; SongEditor* m_editor; protected: - virtual void resizeEvent( QResizeEvent * event ); - virtual void changeEvent( QEvent * ); + void resizeEvent( QResizeEvent * event ) override; + void changeEvent( QEvent * ) override; protected slots: - void play(); - void record(); - void recordAccompany(); - void stop(); + void play() override; + void record() override; + void recordAccompany() override; + void stop() override; void lostFocus(); void adjustUiAfterProjectLoad(); @@ -199,8 +199,8 @@ signals: void resized(); private: - virtual void keyPressEvent( QKeyEvent * ke ); - virtual void keyReleaseEvent( QKeyEvent * ke ); + void keyPressEvent( QKeyEvent * ke ) override; + void keyReleaseEvent( QKeyEvent * ke ) override; QAction* m_addBBTrackAction; QAction* m_addSampleTrackAction; diff --git a/include/StepRecorderWidget.h b/include/StepRecorderWidget.h index cafce2b24..14cfc2eed 100644 --- a/include/StepRecorderWidget.h +++ b/include/StepRecorderWidget.h @@ -55,7 +55,7 @@ public: void showHint(); private: - virtual void paintEvent(QPaintEvent * pe); + void paintEvent(QPaintEvent * pe) override; int xCoordOfTick(int tick); diff --git a/include/SubWindow.h b/include/SubWindow.h index 5d7a810c2..148cf2c99 100644 --- a/include/SubWindow.h +++ b/include/SubWindow.h @@ -67,10 +67,10 @@ public: protected: // hook the QWidget move/resize events to update the tracked geometry - virtual void moveEvent( QMoveEvent * event ); - virtual void resizeEvent( QResizeEvent * event ); - virtual void paintEvent( QPaintEvent * pe ); - virtual void changeEvent( QEvent * event ); + void moveEvent( QMoveEvent * event ) override; + void resizeEvent( QResizeEvent * event ) override; + void paintEvent( QPaintEvent * pe ) override; + void changeEvent( QEvent * event ) override; signals: void focusLost(); diff --git a/include/TabWidget.h b/include/TabWidget.h index 88ecf9034..0cf15155b 100644 --- a/include/TabWidget.h +++ b/include/TabWidget.h @@ -72,13 +72,13 @@ public: void setTabBorder( const QColor & c ); protected: - virtual bool event( QEvent * event ); - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void paintEvent( QPaintEvent * _pe ); - virtual void resizeEvent( QResizeEvent * _re ); - virtual void wheelEvent( QWheelEvent * _we ); - virtual QSize minimumSizeHint() const; - virtual QSize sizeHint() const; + bool event( QEvent * event ) override; + void mousePressEvent( QMouseEvent * _me ) override; + void paintEvent( QPaintEvent * _pe ) override; + void resizeEvent( QResizeEvent * _re ) override; + void wheelEvent( QWheelEvent * _we ) override; + QSize minimumSizeHint() const override; + QSize sizeHint() const override; private: struct widgetDesc diff --git a/include/TempoSyncKnob.h b/include/TempoSyncKnob.h index 034e2b8f4..416abe1fc 100644 --- a/include/TempoSyncKnob.h +++ b/include/TempoSyncKnob.h @@ -52,7 +52,7 @@ public: return castModel(); } - virtual void modelChanged(); + void modelChanged() override; signals: @@ -61,7 +61,7 @@ signals: protected: - virtual void contextMenuEvent( QContextMenuEvent * _me ); + void contextMenuEvent( QContextMenuEvent * _me ) override; protected slots: diff --git a/include/TempoSyncKnobModel.h b/include/TempoSyncKnobModel.h index 9aaf48fea..b9512aa1a 100644 --- a/include/TempoSyncKnobModel.h +++ b/include/TempoSyncKnobModel.h @@ -52,7 +52,7 @@ public: const float _max, const float _step, const float _scale, Model * _parent, const QString & _display_name = QString() ); - virtual ~TempoSyncKnobModel() override; + ~TempoSyncKnobModel() override; void saveSettings( QDomDocument & _doc, QDomElement & _this, const QString& name ) override; void loadSettings( const QDomElement & _this, const QString& name ) override; diff --git a/include/TextFloat.h b/include/TextFloat.h index ed10516b5..8f940c591 100644 --- a/include/TextFloat.h +++ b/include/TextFloat.h @@ -66,8 +66,8 @@ public: protected: - virtual void paintEvent( QPaintEvent * _me ); - virtual void mousePressEvent( QMouseEvent * _me ); + void paintEvent( QPaintEvent * _me ) override; + void mousePressEvent( QMouseEvent * _me ) override; private: diff --git a/include/TimeDisplayWidget.h b/include/TimeDisplayWidget.h index 175f159c9..e7e5cb210 100644 --- a/include/TimeDisplayWidget.h +++ b/include/TimeDisplayWidget.h @@ -41,7 +41,7 @@ public: protected: - virtual void mousePressEvent( QMouseEvent* mouseEvent ); + void mousePressEvent( QMouseEvent* mouseEvent ) override; private slots: diff --git a/include/TimeLineWidget.h b/include/TimeLineWidget.h index 374a26418..bc0881f82 100644 --- a/include/TimeLineWidget.h +++ b/include/TimeLineWidget.h @@ -153,9 +153,9 @@ public: void addToolButtons(QToolBar* _tool_bar ); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); - inline virtual QString nodeName() const + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; + void loadSettings( const QDomElement & _this ) override; + inline QString nodeName() const override { return "timeline"; } @@ -184,10 +184,10 @@ public slots: protected: - virtual void paintEvent( QPaintEvent * _pe ); - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void mouseMoveEvent( QMouseEvent * _me ); - virtual void mouseReleaseEvent( QMouseEvent * _me ); + void paintEvent( QPaintEvent * _pe ) override; + void mousePressEvent( QMouseEvent * _me ) override; + void mouseMoveEvent( QMouseEvent * _me ) override; + void mouseReleaseEvent( QMouseEvent * _me ) override; private: diff --git a/include/Track.h b/include/Track.h index 4adf6378e..70e49a1c6 100644 --- a/include/Track.h +++ b/include/Track.h @@ -98,7 +98,7 @@ public: emit dataChanged(); } - virtual QString displayName() const + QString displayName() const override { return name(); } @@ -246,21 +246,21 @@ public slots: virtual bool close(); void cut(); void remove(); - virtual void update(); + void update() override; protected: virtual void constructContextMenu( QMenu * ) { } - virtual void contextMenuEvent( QContextMenuEvent * cme ); - virtual void dragEnterEvent( QDragEnterEvent * dee ); - virtual void dropEvent( QDropEvent * de ); - virtual void leaveEvent( QEvent * e ); - virtual void mousePressEvent( QMouseEvent * me ); - virtual void mouseMoveEvent( QMouseEvent * me ); - virtual void mouseReleaseEvent( QMouseEvent * me ); - virtual void resizeEvent( QResizeEvent * re ) + void contextMenuEvent( QContextMenuEvent * cme ) override; + void dragEnterEvent( QDragEnterEvent * dee ) override; + void dropEvent( QDropEvent * de ) override; + void leaveEvent( QEvent * e ) override; + void mousePressEvent( QMouseEvent * me ) override; + void mouseMoveEvent( QMouseEvent * me ) override; + void mouseReleaseEvent( QMouseEvent * me ) override; + void resizeEvent( QResizeEvent * re ) override { m_needsUpdate = true; selectableObject::resizeEvent( re ); @@ -381,24 +381,24 @@ public slots: void changePosition( const MidiTime & newPos = MidiTime( -1 ) ); protected: - virtual void dragEnterEvent( QDragEnterEvent * dee ); - virtual void dropEvent( QDropEvent * de ); - virtual void mousePressEvent( QMouseEvent * me ); - virtual void paintEvent( QPaintEvent * pe ); - virtual void resizeEvent( QResizeEvent * re ); + void dragEnterEvent( QDragEnterEvent * dee ) override; + void dropEvent( QDropEvent * de ) override; + void mousePressEvent( QMouseEvent * me ) override; + void paintEvent( QPaintEvent * pe ) override; + void resizeEvent( QResizeEvent * re ) override; - virtual QString nodeName() const + QString nodeName() const override { return "trackcontentwidget"; } - virtual void saveSettings( QDomDocument& doc, QDomElement& element ) + void saveSettings( QDomDocument& doc, QDomElement& element ) override { Q_UNUSED(doc) Q_UNUSED(element) } - virtual void loadSettings( const QDomElement& element ) + void loadSettings( const QDomElement& element ) override { Q_UNUSED(element) } @@ -435,8 +435,8 @@ public: protected: - virtual void mousePressEvent( QMouseEvent * me ); - virtual void paintEvent( QPaintEvent * pe ); + void mousePressEvent( QMouseEvent * me ) override; + void paintEvent( QPaintEvent * pe ) override; private slots: @@ -518,8 +518,8 @@ public: virtual void loadTrackSpecificSettings( const QDomElement & element ) = 0; - virtual void saveSettings( QDomDocument & doc, QDomElement & element ); - virtual void loadSettings( const QDomElement & element ); + void saveSettings( QDomDocument & doc, QDomElement & element ) override; + void loadSettings( const QDomElement & element ) override; void setSimpleSerializing() { @@ -564,7 +564,7 @@ public: return m_name; } - virtual QString displayName() const + QString displayName() const override { return name(); } @@ -692,32 +692,32 @@ public slots: protected: - virtual void modelChanged(); + void modelChanged() override; - virtual void saveSettings( QDomDocument& doc, QDomElement& element ) + void saveSettings( QDomDocument& doc, QDomElement& element ) override { Q_UNUSED(doc) Q_UNUSED(element) } - virtual void loadSettings( const QDomElement& element ) + void loadSettings( const QDomElement& element ) override { Q_UNUSED(element) } - virtual QString nodeName() const + QString nodeName() const override { return "trackview"; } - virtual void dragEnterEvent( QDragEnterEvent * dee ); - virtual void dropEvent( QDropEvent * de ); - virtual void mousePressEvent( QMouseEvent * me ); - virtual void mouseMoveEvent( QMouseEvent * me ); - virtual void mouseReleaseEvent( QMouseEvent * me ); - virtual void paintEvent( QPaintEvent * pe ); - virtual void resizeEvent( QResizeEvent * re ); + void dragEnterEvent( QDragEnterEvent * dee ) override; + void dropEvent( QDropEvent * de ) override; + void mousePressEvent( QMouseEvent * me ) override; + void mouseMoveEvent( QMouseEvent * me ) override; + void mouseReleaseEvent( QMouseEvent * me ) override; + void paintEvent( QPaintEvent * pe ) override; + void resizeEvent( QResizeEvent * re ) override; private: diff --git a/include/TrackContainer.h b/include/TrackContainer.h index 1caca922e..fd853a73c 100644 --- a/include/TrackContainer.h +++ b/include/TrackContainer.h @@ -51,9 +51,9 @@ public: TrackContainer(); virtual ~TrackContainer(); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; - virtual void loadSettings( const QDomElement & _this ); + void loadSettings( const QDomElement & _this ) override; virtual AutomationPattern * tempoAutomationPattern() @@ -124,7 +124,7 @@ public: { } - virtual QString nodeName() const + QString nodeName() const override { return "DummyTrackContainer"; } diff --git a/include/TrackContainerView.h b/include/TrackContainerView.h index cf79a0a21..6e952189b 100644 --- a/include/TrackContainerView.h +++ b/include/TrackContainerView.h @@ -49,8 +49,8 @@ public: TrackContainerView( TrackContainer* tc ); virtual ~TrackContainerView(); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _this ); - virtual void loadSettings( const QDomElement & _this ); + void saveSettings( QDomDocument & _doc, QDomElement & _this ) override; + void loadSettings( const QDomElement & _this ) override; QScrollArea * contentWidget() { @@ -116,7 +116,7 @@ public: void clearAllTracks(); - virtual QString nodeName() const + QString nodeName() const override { return "trackcontainerview"; } @@ -129,8 +129,8 @@ public slots: TrackView * createTrackView( Track * _t ); void deleteTrackView( TrackView * _tv ); - virtual void dropEvent( QDropEvent * _de ); - virtual void dragEnterEvent( QDragEnterEvent * _dee ); + void dropEvent( QDropEvent * _de ) override; + void dragEnterEvent( QDragEnterEvent * _dee ) override; /// /// \brief stopRubberBand @@ -141,8 +141,7 @@ public slots: protected: static const int DEFAULT_PIXELS_PER_BAR = 16; - - virtual void resizeEvent( QResizeEvent * ); + void resizeEvent( QResizeEvent * ) override; MidiTime m_currentPosition; @@ -161,7 +160,7 @@ private: virtual ~scrollArea(); protected: - virtual void wheelEvent( QWheelEvent * _we ); + void wheelEvent( QWheelEvent * _we ) override; private: TrackContainerView* m_trackContainerView; @@ -195,7 +194,7 @@ public: InstrumentLoaderThread( QObject *parent = 0, InstrumentTrack *it = 0, QString name = "" ); - void run(); + void run() override; private: InstrumentTrack *m_it; diff --git a/include/TrackLabelButton.h b/include/TrackLabelButton.h index f1059bdbf..7d9726feb 100644 --- a/include/TrackLabelButton.h +++ b/include/TrackLabelButton.h @@ -49,13 +49,13 @@ public slots: protected: - virtual void dragEnterEvent( QDragEnterEvent * _dee ); - virtual void dropEvent( QDropEvent * _de ); - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void mouseDoubleClickEvent( QMouseEvent * _me ); - virtual void mouseReleaseEvent( QMouseEvent * _me ); - virtual void paintEvent( QPaintEvent * _pe ); - virtual void resizeEvent( QResizeEvent * _re ); + void dragEnterEvent( QDragEnterEvent * _dee ) override; + void dropEvent( QDropEvent * _de ) override; + void mousePressEvent( QMouseEvent * _me ) override; + void mouseDoubleClickEvent( QMouseEvent * _me ) override; + void mouseReleaseEvent( QMouseEvent * _me ) override; + void paintEvent( QPaintEvent * _pe ) override; + void resizeEvent( QResizeEvent * _re ) override; private: diff --git a/include/TrackRenameLineEdit.h b/include/TrackRenameLineEdit.h index 6883b9b05..e681a2d21 100644 --- a/include/TrackRenameLineEdit.h +++ b/include/TrackRenameLineEdit.h @@ -37,7 +37,7 @@ public: void show(); protected: - virtual void keyPressEvent( QKeyEvent * ke ); + void keyPressEvent( QKeyEvent * ke ) override; private: QString m_oldName; diff --git a/include/VisualizationWidget.h b/include/VisualizationWidget.h index a178b1ad8..85825975a 100644 --- a/include/VisualizationWidget.h +++ b/include/VisualizationWidget.h @@ -61,8 +61,8 @@ public: protected: - virtual void paintEvent( QPaintEvent * _pe ); - virtual void mousePressEvent( QMouseEvent * _me ); + void paintEvent( QPaintEvent * _pe ) override; + void mousePressEvent( QMouseEvent * _me ) override; protected slots: diff --git a/plugins/VstEffect/VstEffectControlDialog.h b/plugins/VstEffect/VstEffectControlDialog.h index 3cd9af360..930f514c9 100644 --- a/plugins/VstEffect/VstEffectControlDialog.h +++ b/plugins/VstEffect/VstEffectControlDialog.h @@ -49,8 +49,8 @@ public: virtual ~VstEffectControlDialog(); protected: - virtual void paintEvent( QPaintEvent * _pe ); - virtual void showEvent( QShowEvent* _se ) override; + void paintEvent( QPaintEvent * _pe ) override; + void showEvent( QShowEvent* _se ) override; private: QWidget * m_pluginWidget; diff --git a/plugins/peak_controller_effect/peak_controller_effect.h b/plugins/peak_controller_effect/peak_controller_effect.h index 093b56437..a872e2b8b 100644 --- a/plugins/peak_controller_effect/peak_controller_effect.h +++ b/plugins/peak_controller_effect/peak_controller_effect.h @@ -36,9 +36,9 @@ public: const Descriptor::SubPluginFeatures::Key * _key ); virtual ~PeakControllerEffect(); virtual bool processAudioBuffer( sampleFrame * _buf, - const fpp_t _frames ); + const fpp_t _frames ) override; - virtual EffectControls * controls() + EffectControls * controls() override { return &m_peakControls; } diff --git a/plugins/peak_controller_effect/peak_controller_effect_controls.h b/plugins/peak_controller_effect/peak_controller_effect_controls.h index 784df4d8d..fe90eddca 100644 --- a/plugins/peak_controller_effect/peak_controller_effect_controls.h +++ b/plugins/peak_controller_effect/peak_controller_effect_controls.h @@ -41,18 +41,18 @@ public: { } - virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); - virtual void loadSettings( const QDomElement & _this ); - inline virtual QString nodeName() const + void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; + void loadSettings( const QDomElement & _this ) override; + inline QString nodeName() const override { return "peakcontrollereffectcontrols"; } - virtual int controlCount() + int controlCount() override { return 1; } - virtual EffectControlDialog * createView() + EffectControlDialog * createView() override { return new PeakControllerEffectControlDialog( this ); } diff --git a/plugins/vst_base/VstPlugin.h b/plugins/vst_base/VstPlugin.h index 5b459d40d..26e7fec36 100644 --- a/plugins/vst_base/VstPlugin.h +++ b/plugins/vst_base/VstPlugin.h @@ -49,7 +49,7 @@ public: void tryLoad( const QString &remoteVstPluginExecutable ); - virtual bool processMessage( const message & _m ); + bool processMessage( const message & _m ) override; inline bool hasEditor() const { @@ -99,17 +99,17 @@ public: QWidget * pluginWidget(); - virtual void loadSettings( const QDomElement & _this ); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _this ); + void loadSettings( const QDomElement & _this ) override; + void saveSettings( QDomDocument & _doc, QDomElement & _this ) override; - inline virtual QString nodeName() const + virtual QString nodeName() const override { return "vstplugin"; } virtual void createUI(QWidget *parent); - bool eventFilter(QObject *obj, QEvent *event); + bool eventFilter(QObject *obj, QEvent *event) override; QString embedMethod() const; diff --git a/src/core/PresetPreviewPlayHandle.cpp b/src/core/PresetPreviewPlayHandle.cpp index ca0e52194..11b145b22 100644 --- a/src/core/PresetPreviewPlayHandle.cpp +++ b/src/core/PresetPreviewPlayHandle.cpp @@ -54,7 +54,7 @@ public: { } - virtual QString nodeName() const + QString nodeName() const override { return "previewtrackcontainer"; } diff --git a/src/gui/ControllerConnectionDialog.cpp b/src/gui/ControllerConnectionDialog.cpp index 02857b034..f0d3d10e9 100644 --- a/src/gui/ControllerConnectionDialog.cpp +++ b/src/gui/ControllerConnectionDialog.cpp @@ -63,7 +63,7 @@ public: } - virtual void processInEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset = 0 ) + void processInEvent( const MidiEvent& event, const MidiTime& time, f_cnt_t offset = 0 ) override { if( event.type() == MidiControlChange && ( m_midiPort.inputChannel() == 0 || m_midiPort.inputChannel() == event.channel() + 1 ) ) diff --git a/src/gui/FxMixerView.cpp b/src/gui/FxMixerView.cpp index 4ae2a630a..54bbff70f 100644 --- a/src/gui/FxMixerView.cpp +++ b/src/gui/FxMixerView.cpp @@ -115,7 +115,7 @@ FxMixerView::FxMixerView() : ChannelArea( QWidget * parent, FxMixerView * mv ) : QScrollArea( parent ), m_mv( mv ) {} ~ChannelArea() {} - virtual void keyPressEvent( QKeyEvent * e ) + void keyPressEvent( QKeyEvent * e ) override { m_mv->keyPressEvent( e ); } diff --git a/src/gui/RowTableView.cpp b/src/gui/RowTableView.cpp index a4daeb17f..9830354be 100644 --- a/src/gui/RowTableView.cpp +++ b/src/gui/RowTableView.cpp @@ -39,12 +39,12 @@ public: } virtual void paint( QPainter * painter, const QStyleOptionViewItem & option, - const QModelIndex & index ) const; + const QModelIndex & index ) const override; protected: virtual void initStyleOption( QStyleOptionViewItem * option, - const QModelIndex & index ) const; + const QModelIndex & index ) const override; private: diff --git a/src/gui/widgets/SideBar.cpp b/src/gui/widgets/SideBar.cpp index cc83abae4..36c417b93 100644 --- a/src/gui/widgets/SideBar.cpp +++ b/src/gui/widgets/SideBar.cpp @@ -49,7 +49,7 @@ public: return m_orientation; } - virtual QSize sizeHint() const + QSize sizeHint() const override { QSize s = QToolButton::sizeHint(); s.setWidth( s.width() + 8 ); @@ -62,7 +62,7 @@ public: protected: - virtual void paintEvent( QPaintEvent * ) + void paintEvent( QPaintEvent * ) override { QStylePainter p( this ); QStyleOptionToolButton opt; From ebf71003c7873d02da10ea44c60e69ca773c79f4 Mon Sep 17 00:00:00 2001 From: Kevin Zander Date: Fri, 1 Nov 2019 02:36:54 -0500 Subject: [PATCH 438/445] Fix vertical piano mouse click unresponsiveness `PianoRoll::mouseDoubleClickEvent` wasn't forwarding the event to the base class when not acting on the event. The base class calls `mousePressEvent`. Fixes #3005 --- src/gui/editors/PianoRoll.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 183735450..3b42bd9b2 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -1948,6 +1948,10 @@ void PianoRoll::mouseDoubleClickEvent(QMouseEvent * me ) enterValue( &nv ); } } + else + { + QWidget::mouseDoubleClickEvent(me); + } } From 8a52ddb642d0789fd017fa36e491d187040de594 Mon Sep 17 00:00:00 2001 From: Lukas W Date: Fri, 1 Nov 2019 09:56:39 +0100 Subject: [PATCH 439/445] CricleCI: Test merged pull request --- .circleci/config.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0ab2c51a0..a3be541b5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -42,6 +42,14 @@ shared: mkdir -p /tmp/artifacts # Workaround for failing submodule fetching git config --global --unset url."ssh://git@github.com".insteadOf || true + if [[ -n "${CIRCLE_PR_NUMBER}" ]] + then + echo "Fetching out merged pull request" + git fetch -u origin refs/pull/${CIRCLE_PR_NUMBER}/merge:pr/merge + git checkout pr/merge + else + echo "Not a pull request" + fi # Commmon environment variables common_environment: &common_environment From a24f1d779d2226104a69ff004e5ad83365cbec9b Mon Sep 17 00:00:00 2001 From: Hussam al-Homsi Date: Wed, 6 Nov 2019 22:03:39 -0500 Subject: [PATCH 440/445] Do not include unused headers --- include/Pitch.h | 3 --- include/panning.h | 1 - include/volume.h | 3 --- 3 files changed, 7 deletions(-) diff --git a/include/Pitch.h b/include/Pitch.h index 5ef1c3d62..8a9b371b4 100644 --- a/include/Pitch.h +++ b/include/Pitch.h @@ -25,9 +25,6 @@ #ifndef PITCH_H #define PITCH_H -#include "lmms_basics.h" -#include "Midi.h" - typedef int16_t pitch_t; const pitch_t CentsPerSemitone = 100; diff --git a/include/panning.h b/include/panning.h index 8668ddf88..8994df9ab 100644 --- a/include/panning.h +++ b/include/panning.h @@ -27,7 +27,6 @@ #define PANNING_H #include "lmms_basics.h" -#include "volume.h" #include "panning_constants.h" #include "Midi.h" diff --git a/include/volume.h b/include/volume.h index f0f7708ad..9172395d6 100644 --- a/include/volume.h +++ b/include/volume.h @@ -26,10 +26,7 @@ #ifndef VOLUME_H #define VOLUME_H -#include "lmmsconfig.h" - #include "lmms_basics.h" -#include "Midi.h" const volume_t MinVolume = 0; const volume_t MaxVolume = 200; From b4459bed9e48f8dddc448da2f8bf6202dc87df5b Mon Sep 17 00:00:00 2001 From: nia <29542929+niacat@users.noreply.github.com> Date: Thu, 7 Nov 2019 04:47:20 +0000 Subject: [PATCH 441/445] Support NetBSD's OSS audio/midi implementation (#5277) --- src/core/audio/AudioOss.cpp | 2 +- src/core/midi/MidiOss.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/audio/AudioOss.cpp b/src/core/audio/AudioOss.cpp index bbd9a9507..cbf9278a7 100644 --- a/src/core/audio/AudioOss.cpp +++ b/src/core/audio/AudioOss.cpp @@ -59,7 +59,7 @@ #ifndef _PATH_DEV_DSP -#ifdef __OpenBSD__ +#if defined(__NetBSD__) || defined(__OpenBSD__) #define _PATH_DEV_DSP "/dev/audio" #else #define _PATH_DEV_DSP "/dev/dsp" diff --git a/src/core/midi/MidiOss.cpp b/src/core/midi/MidiOss.cpp index a8e948efc..c1c990b0b 100644 --- a/src/core/midi/MidiOss.cpp +++ b/src/core/midi/MidiOss.cpp @@ -71,7 +71,11 @@ QString MidiOss::probeDevice() { return getenv( "MIDIDEV" ); } +#ifdef __NetBSD__ + return "/dev/rmidi0"; +#else return "/dev/midi"; +#endif } return dev; } From ffce1d947a633881b78711062653c6eda1a6be86 Mon Sep 17 00:00:00 2001 From: Olivier Humbert Date: Fri, 15 Nov 2019 05:30:49 +0100 Subject: [PATCH 442/445] Debian packaging improvements (#5264) * d/control: http -> https * d/control: rearrange lists (one item per line + alphabetically ordered) * d/copyright: http -> https * Delete contributors.patch (integrated now) * d/series: removes contributors.patch --- debian/control | 38 +++++++++---- debian/copyright | 4 +- debian/patches/contributors.patch | 89 ------------------------------- debian/patches/series | 1 - 4 files changed, 30 insertions(+), 102 deletions(-) delete mode 100644 debian/patches/contributors.patch diff --git a/debian/control b/debian/control index 463353df0..880e0d89a 100644 --- a/debian/control +++ b/debian/control @@ -37,18 +37,28 @@ Build-Depends: qttools5-dev, wine64-tools [amd64] | wine32-tools [i386] Standards-Version: 4.2.1.4 -Homepage: http://lmms.io/ +Homepage: https://lmms.io/ Vcs-Browser: https://salsa.debian.org/debian-edu-pkg-team/lmms.git Package: lmms-bin Architecture: any -Depends: lmms-common (>= ${source:Version}), ${shlibs:Depends}, ${misc:Depends}, - stk -Recommends: tap-plugins, caps, +Depends: + lmms-common (>= ${source:Version}), + ${shlibs:Depends}, + ${misc:Depends}, + stk, +Recommends: + caps, lmms-vst-server:i386 (>= ${source:Version}), - lmms-vst-server:amd64 (>= ${source:Version}) -Suggests: fil-plugins, mcp-plugins, omins, freepats, fluid-soundfont-gm, - ladspa-plugin + lmms-vst-server:amd64 (>= ${source:Version}), + tap-plugins, +Suggests: + fil-plugins, + fluid-soundfont-gm, + freepats, + ladspa-plugin, + mcp-plugins, + omins, Replaces: lmms-common (<< 1.0.0-1) Breaks: lmms-common (<< 1.0.0-1) Multi-Arch: allowed @@ -67,7 +77,9 @@ Description: Linux Multimedia Studio - minimal installation Package: lmms Architecture: any -Depends: 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 @@ -83,7 +95,10 @@ Description: Linux Multimedia Studio Package: lmms-common Architecture: all -Depends: zynaddsubfx-data, ${shlibs:Depends}, ${misc:Depends} +Depends: + ${shlibs:Depends}, + ${misc:Depends}, + zynaddsubfx-data, Pre-Depends: ${misc:Pre-Depends} Description: Linux Multimedia Studio - common files LMMS aims to be a free alternative to popular (but commercial and closed- @@ -101,7 +116,10 @@ Description: Linux Multimedia Studio - common files Package: lmms-vst-server Architecture: amd64 i386 -Depends: wine64 [amd64] | wine64-development [amd64] | wine32 [i386] | wine32-development [i386], ${shlibs:Depends}, ${misc:Depends} +Depends: + wine64 [amd64] | wine64-development [amd64] | wine32 [i386] | wine32-development [i386], + ${shlibs:Depends}, + ${misc:Depends}, Recommends: lmms-bin:any Description: Linux Multimedia Studio - VST server This package contains a helper application that loads VST plugins. diff --git a/debian/copyright b/debian/copyright index 3fbf0917e..01b30459e 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,4 +1,4 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: LMMS Upstream-Contact: https://github.com/LMMS/lmms Source: https://github.com/LMMS/lmms/tags @@ -1367,7 +1367,7 @@ License: WOL 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. + ANY KIND. See https://www.dspguru.com/wol.htm for more information. License: non-free This license does not comply with Debian Free Software Guidelines. diff --git a/debian/patches/contributors.patch b/debian/patches/contributors.patch deleted file mode 100644 index d2b55fd9a..000000000 --- a/debian/patches/contributors.patch +++ /dev/null @@ -1,89 +0,0 @@ -Description: Add contributors - The list of contributors is missing from the source tarball. This list is - generated from upstream repository, running: - git shortlog -sne v1.1.3 | cut -c8- - See https://github.com/LMMS/lmms/issues/2914 for more information. -Author: Javier Serrano Polo - -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 index aba1af044..94ae11454 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,3 +1,2 @@ -contributors.patch clang.patch build-amd64-20181013.patch From 33b36ffc5ea7889066a04d7823fa6d027461ce0f Mon Sep 17 00:00:00 2001 From: Hussam al-Homsi Date: Fri, 15 Nov 2019 17:09:57 -0500 Subject: [PATCH 443/445] Add some missing includes --- include/Pitch.h | 2 ++ include/panning.h | 1 + 2 files changed, 3 insertions(+) diff --git a/include/Pitch.h b/include/Pitch.h index 8a9b371b4..2f866a1c5 100644 --- a/include/Pitch.h +++ b/include/Pitch.h @@ -25,6 +25,8 @@ #ifndef PITCH_H #define PITCH_H +#include + typedef int16_t pitch_t; const pitch_t CentsPerSemitone = 100; diff --git a/include/panning.h b/include/panning.h index 8994df9ab..c043adf5c 100644 --- a/include/panning.h +++ b/include/panning.h @@ -29,6 +29,7 @@ #include "lmms_basics.h" #include "panning_constants.h" #include "Midi.h" +#include "volume.h" inline stereoVolumeVector panningToVolumeVector( panning_t _p, float _scale = 1.0f ) From 256ae6dad6d03cbad2c72a14939faf2aaea20549 Mon Sep 17 00:00:00 2001 From: Kevin Zander Date: Fri, 15 Nov 2019 19:46:09 -0600 Subject: [PATCH 444/445] Fix incorrect m_lastSoloed after moving/deleting an FX channel Original code by @gi0e5b06. --- src/core/FxMixer.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/core/FxMixer.cpp b/src/core/FxMixer.cpp index 032090bf1..f04435e05 100644 --- a/src/core/FxMixer.cpp +++ b/src/core/FxMixer.cpp @@ -336,6 +336,11 @@ void FxMixer::deleteChannel( int index ) deleteChannelSend( ch->m_receives.first() ); } + // if m_lastSoloed was our index, reset it + if (m_lastSoloed == index) { m_lastSoloed = -1; } + // if m_lastSoloed is > delete index, it will move left + else if (m_lastSoloed > index) { --m_lastSoloed; } + // actually delete the channel m_fxChannels.remove(index); delete ch; @@ -373,6 +378,10 @@ void FxMixer::moveChannelLeft( int index ) // channels to swap int a = index - 1, b = index; + // check if m_lastSoloed is one of our swaps + if (m_lastSoloed == a) { m_lastSoloed = b; } + else if (m_lastSoloed == b) { m_lastSoloed = a; } + // go through every instrument and adjust for the channel index change QVector songTrackList = Engine::getSong()->tracks(); QVector bbTrackList = Engine::getBBTrackContainer()->tracks(); From 2f0010270eaf64efd716d775ddaffbb25818b3ea Mon Sep 17 00:00:00 2001 From: Kapandaria Date: Mon, 18 Nov 2019 22:29:08 +0200 Subject: [PATCH 445/445] Xpressive plugin updates (#5217) * Updated plugin artwork. * Update the formula in the presets to use integrate(f) instead of t*f, as integrate operation is more robust to frequency changes. * rename X-Pressive to Xpressive in help window title. * Xpressive.cpp, spaces to tabs and remove commented code. --- data/presets/X-Pressive/Ambition.xpf | 21 --- data/presets/X-Pressive/Baby Violin.xpf | 21 --- data/presets/X-Pressive/Bad Singer.xpf | 21 --- data/presets/X-Pressive/Cloud Bass.xpf | 21 --- data/presets/X-Pressive/Creature.xpf | 21 --- data/presets/X-Pressive/Electric Shock.xpf | 21 --- data/presets/X-Pressive/Faded Colors.xpf | 21 --- data/presets/X-Pressive/Fat Flute.xpf | 21 --- data/presets/X-Pressive/Horn.xpf | 21 --- data/presets/X-Pressive/Piano-Gong.xpf | 21 --- data/presets/X-Pressive/Rubber Bass.xpf | 21 --- data/presets/X-Pressive/Space Echoes.xpf | 21 --- data/presets/X-Pressive/Speaker Swapper.xpf | 21 --- data/presets/X-Pressive/Toss.xpf | 21 --- data/presets/X-Pressive/Untuned Bell.xpf | 21 --- data/presets/X-Pressive/Vibrato.xpf | 21 --- data/presets/X-Pressive/X-Distorted.xpf | 21 --- .../{X-Pressive => Xpressive}/Accordion.xpf | 0 data/presets/Xpressive/Ambition.xpf | 22 +++ data/presets/Xpressive/Baby Violin.xpf | 22 +++ data/presets/Xpressive/Bad Singer.xpf | 22 +++ data/presets/Xpressive/Cloud Bass.xpf | 22 +++ data/presets/Xpressive/Creature.xpf | 22 +++ .../{X-Pressive => Xpressive}/Dream.xpf | 0 data/presets/Xpressive/Electric Shock.xpf | 22 +++ .../Xpressive/Faded Colors - notes test.xpf | 22 +++ data/presets/Xpressive/Faded Colors.xpf | 22 +++ data/presets/Xpressive/Fat Flute.xpf | 22 +++ .../{X-Pressive => Xpressive}/Frog.xpf | 0 data/presets/Xpressive/Horn.xpf | 22 +++ .../{X-Pressive => Xpressive}/Low Battery.xpf | 23 ++-- data/presets/Xpressive/Piano-Gong.xpf | 22 +++ data/presets/Xpressive/Rubber Bass.xpf | 22 +++ data/presets/Xpressive/Space Echoes.xpf | 22 +++ data/presets/Xpressive/Speaker Swapper.xpf | 22 +++ data/presets/Xpressive/Toss.xpf | 22 +++ data/presets/Xpressive/Untuned Bell.xpf | 22 +++ data/presets/Xpressive/Vibrato.xpf | 22 +++ data/presets/Xpressive/X-Distorted.xpf | 22 +++ plugins/Xpressive/Xpressive.cpp | 90 ++++++------ plugins/Xpressive/Xpressive.svg | 130 ++++++++++++++++++ plugins/Xpressive/Xpressive_logo.svg | 106 ++++++++++++++ plugins/Xpressive/artwork.png | Bin 70956 -> 10950 bytes plugins/Xpressive/help_active.png | Bin 840 -> 546 bytes plugins/Xpressive/help_inactive.png | Bin 806 -> 549 bytes plugins/Xpressive/logo.png | Bin 4497 -> 1884 bytes plugins/Xpressive/o1_active.png | Bin 629 -> 548 bytes plugins/Xpressive/o1_inactive.png | Bin 508 -> 512 bytes plugins/Xpressive/o2_active.png | Bin 723 -> 653 bytes plugins/Xpressive/o2_inactive.png | Bin 602 -> 589 bytes plugins/Xpressive/w1_active.png | Bin 685 -> 590 bytes plugins/Xpressive/w1_inactive.png | Bin 549 -> 554 bytes plugins/Xpressive/w2_active.png | Bin 766 -> 715 bytes plugins/Xpressive/w2_inactive.png | Bin 628 -> 662 bytes plugins/Xpressive/w3_active.png | Bin 771 -> 705 bytes plugins/Xpressive/w3_inactive.png | Bin 626 -> 652 bytes plugins/Xpressive/wavegraph.png | Bin 9029 -> 9006 bytes 57 files changed, 694 insertions(+), 408 deletions(-) delete mode 100644 data/presets/X-Pressive/Ambition.xpf delete mode 100644 data/presets/X-Pressive/Baby Violin.xpf delete mode 100644 data/presets/X-Pressive/Bad Singer.xpf delete mode 100644 data/presets/X-Pressive/Cloud Bass.xpf delete mode 100644 data/presets/X-Pressive/Creature.xpf delete mode 100644 data/presets/X-Pressive/Electric Shock.xpf delete mode 100644 data/presets/X-Pressive/Faded Colors.xpf delete mode 100644 data/presets/X-Pressive/Fat Flute.xpf delete mode 100644 data/presets/X-Pressive/Horn.xpf delete mode 100644 data/presets/X-Pressive/Piano-Gong.xpf delete mode 100644 data/presets/X-Pressive/Rubber Bass.xpf delete mode 100644 data/presets/X-Pressive/Space Echoes.xpf delete mode 100644 data/presets/X-Pressive/Speaker Swapper.xpf delete mode 100644 data/presets/X-Pressive/Toss.xpf delete mode 100644 data/presets/X-Pressive/Untuned Bell.xpf delete mode 100644 data/presets/X-Pressive/Vibrato.xpf delete mode 100644 data/presets/X-Pressive/X-Distorted.xpf rename data/presets/{X-Pressive => Xpressive}/Accordion.xpf (100%) create mode 100644 data/presets/Xpressive/Ambition.xpf create mode 100644 data/presets/Xpressive/Baby Violin.xpf create mode 100644 data/presets/Xpressive/Bad Singer.xpf create mode 100644 data/presets/Xpressive/Cloud Bass.xpf create mode 100644 data/presets/Xpressive/Creature.xpf rename data/presets/{X-Pressive => Xpressive}/Dream.xpf (100%) create mode 100644 data/presets/Xpressive/Electric Shock.xpf create mode 100644 data/presets/Xpressive/Faded Colors - notes test.xpf create mode 100644 data/presets/Xpressive/Faded Colors.xpf create mode 100644 data/presets/Xpressive/Fat Flute.xpf rename data/presets/{X-Pressive => Xpressive}/Frog.xpf (100%) create mode 100644 data/presets/Xpressive/Horn.xpf rename data/presets/{X-Pressive => Xpressive}/Low Battery.xpf (64%) create mode 100644 data/presets/Xpressive/Piano-Gong.xpf create mode 100644 data/presets/Xpressive/Rubber Bass.xpf create mode 100644 data/presets/Xpressive/Space Echoes.xpf create mode 100644 data/presets/Xpressive/Speaker Swapper.xpf create mode 100644 data/presets/Xpressive/Toss.xpf create mode 100644 data/presets/Xpressive/Untuned Bell.xpf create mode 100644 data/presets/Xpressive/Vibrato.xpf create mode 100644 data/presets/Xpressive/X-Distorted.xpf create mode 100644 plugins/Xpressive/Xpressive.svg create mode 100644 plugins/Xpressive/Xpressive_logo.svg diff --git a/data/presets/X-Pressive/Ambition.xpf b/data/presets/X-Pressive/Ambition.xpf deleted file mode 100644 index 2d93f7c05..000000000 --- a/data/presets/X-Pressive/Ambition.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/Baby Violin.xpf b/data/presets/X-Pressive/Baby Violin.xpf deleted file mode 100644 index 2e887d3d2..000000000 --- a/data/presets/X-Pressive/Baby Violin.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/Bad Singer.xpf b/data/presets/X-Pressive/Bad Singer.xpf deleted file mode 100644 index ca9cfd5a3..000000000 --- a/data/presets/X-Pressive/Bad Singer.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/Cloud Bass.xpf b/data/presets/X-Pressive/Cloud Bass.xpf deleted file mode 100644 index 4e444f22a..000000000 --- a/data/presets/X-Pressive/Cloud Bass.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/Creature.xpf b/data/presets/X-Pressive/Creature.xpf deleted file mode 100644 index b667a9c7f..000000000 --- a/data/presets/X-Pressive/Creature.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/Electric Shock.xpf b/data/presets/X-Pressive/Electric Shock.xpf deleted file mode 100644 index 7dea6fe4a..000000000 --- a/data/presets/X-Pressive/Electric Shock.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/Faded Colors.xpf b/data/presets/X-Pressive/Faded Colors.xpf deleted file mode 100644 index 84a37826a..000000000 --- a/data/presets/X-Pressive/Faded Colors.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/Fat Flute.xpf b/data/presets/X-Pressive/Fat Flute.xpf deleted file mode 100644 index 92242114e..000000000 --- a/data/presets/X-Pressive/Fat Flute.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/Horn.xpf b/data/presets/X-Pressive/Horn.xpf deleted file mode 100644 index 099480569..000000000 --- a/data/presets/X-Pressive/Horn.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/Piano-Gong.xpf b/data/presets/X-Pressive/Piano-Gong.xpf deleted file mode 100644 index 241f61a55..000000000 --- a/data/presets/X-Pressive/Piano-Gong.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/Rubber Bass.xpf b/data/presets/X-Pressive/Rubber Bass.xpf deleted file mode 100644 index 73c3648ba..000000000 --- a/data/presets/X-Pressive/Rubber Bass.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/Space Echoes.xpf b/data/presets/X-Pressive/Space Echoes.xpf deleted file mode 100644 index 1d4d2b543..000000000 --- a/data/presets/X-Pressive/Space Echoes.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/Speaker Swapper.xpf b/data/presets/X-Pressive/Speaker Swapper.xpf deleted file mode 100644 index cf80b9304..000000000 --- a/data/presets/X-Pressive/Speaker Swapper.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/Toss.xpf b/data/presets/X-Pressive/Toss.xpf deleted file mode 100644 index 27a0b3f96..000000000 --- a/data/presets/X-Pressive/Toss.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/Untuned Bell.xpf b/data/presets/X-Pressive/Untuned Bell.xpf deleted file mode 100644 index 744927063..000000000 --- a/data/presets/X-Pressive/Untuned Bell.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/Vibrato.xpf b/data/presets/X-Pressive/Vibrato.xpf deleted file mode 100644 index 34795de11..000000000 --- a/data/presets/X-Pressive/Vibrato.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/X-Distorted.xpf b/data/presets/X-Pressive/X-Distorted.xpf deleted file mode 100644 index cbe3742a5..000000000 --- a/data/presets/X-Pressive/X-Distorted.xpf +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/data/presets/X-Pressive/Accordion.xpf b/data/presets/Xpressive/Accordion.xpf similarity index 100% rename from data/presets/X-Pressive/Accordion.xpf rename to data/presets/Xpressive/Accordion.xpf diff --git a/data/presets/Xpressive/Ambition.xpf b/data/presets/Xpressive/Ambition.xpf new file mode 100644 index 000000000..dd6448977 --- /dev/null +++ b/data/presets/Xpressive/Ambition.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/Xpressive/Baby Violin.xpf b/data/presets/Xpressive/Baby Violin.xpf new file mode 100644 index 000000000..45e407fc8 --- /dev/null +++ b/data/presets/Xpressive/Baby Violin.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/Xpressive/Bad Singer.xpf b/data/presets/Xpressive/Bad Singer.xpf new file mode 100644 index 000000000..10fe3b308 --- /dev/null +++ b/data/presets/Xpressive/Bad Singer.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/Xpressive/Cloud Bass.xpf b/data/presets/Xpressive/Cloud Bass.xpf new file mode 100644 index 000000000..15bf4188d --- /dev/null +++ b/data/presets/Xpressive/Cloud Bass.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/Xpressive/Creature.xpf b/data/presets/Xpressive/Creature.xpf new file mode 100644 index 000000000..bee39f224 --- /dev/null +++ b/data/presets/Xpressive/Creature.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/X-Pressive/Dream.xpf b/data/presets/Xpressive/Dream.xpf similarity index 100% rename from data/presets/X-Pressive/Dream.xpf rename to data/presets/Xpressive/Dream.xpf diff --git a/data/presets/Xpressive/Electric Shock.xpf b/data/presets/Xpressive/Electric Shock.xpf new file mode 100644 index 000000000..3f9aef104 --- /dev/null +++ b/data/presets/Xpressive/Electric Shock.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/Xpressive/Faded Colors - notes test.xpf b/data/presets/Xpressive/Faded Colors - notes test.xpf new file mode 100644 index 000000000..de4938f4d --- /dev/null +++ b/data/presets/Xpressive/Faded Colors - notes test.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/Xpressive/Faded Colors.xpf b/data/presets/Xpressive/Faded Colors.xpf new file mode 100644 index 000000000..a514ee438 --- /dev/null +++ b/data/presets/Xpressive/Faded Colors.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/Xpressive/Fat Flute.xpf b/data/presets/Xpressive/Fat Flute.xpf new file mode 100644 index 000000000..76d9e2f84 --- /dev/null +++ b/data/presets/Xpressive/Fat Flute.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/X-Pressive/Frog.xpf b/data/presets/Xpressive/Frog.xpf similarity index 100% rename from data/presets/X-Pressive/Frog.xpf rename to data/presets/Xpressive/Frog.xpf diff --git a/data/presets/Xpressive/Horn.xpf b/data/presets/Xpressive/Horn.xpf new file mode 100644 index 000000000..d44b332b2 --- /dev/null +++ b/data/presets/Xpressive/Horn.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/X-Pressive/Low Battery.xpf b/data/presets/Xpressive/Low Battery.xpf similarity index 64% rename from data/presets/X-Pressive/Low Battery.xpf rename to data/presets/Xpressive/Low Battery.xpf index c0e648ac9..78f1fc78f 100644 --- a/data/presets/X-Pressive/Low Battery.xpf +++ b/data/presets/Xpressive/Low Battery.xpf @@ -1,20 +1,21 @@ - + - - + + - + + + - - - - + + + + - - - + + diff --git a/data/presets/Xpressive/Piano-Gong.xpf b/data/presets/Xpressive/Piano-Gong.xpf new file mode 100644 index 000000000..a8244b799 --- /dev/null +++ b/data/presets/Xpressive/Piano-Gong.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/Xpressive/Rubber Bass.xpf b/data/presets/Xpressive/Rubber Bass.xpf new file mode 100644 index 000000000..4b1409e22 --- /dev/null +++ b/data/presets/Xpressive/Rubber Bass.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/Xpressive/Space Echoes.xpf b/data/presets/Xpressive/Space Echoes.xpf new file mode 100644 index 000000000..be6de3653 --- /dev/null +++ b/data/presets/Xpressive/Space Echoes.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/Xpressive/Speaker Swapper.xpf b/data/presets/Xpressive/Speaker Swapper.xpf new file mode 100644 index 000000000..d4da5aa2f --- /dev/null +++ b/data/presets/Xpressive/Speaker Swapper.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/Xpressive/Toss.xpf b/data/presets/Xpressive/Toss.xpf new file mode 100644 index 000000000..387e78fd9 --- /dev/null +++ b/data/presets/Xpressive/Toss.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/Xpressive/Untuned Bell.xpf b/data/presets/Xpressive/Untuned Bell.xpf new file mode 100644 index 000000000..5dd61ec18 --- /dev/null +++ b/data/presets/Xpressive/Untuned Bell.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/Xpressive/Vibrato.xpf b/data/presets/Xpressive/Vibrato.xpf new file mode 100644 index 000000000..a7dda25e9 --- /dev/null +++ b/data/presets/Xpressive/Vibrato.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/presets/Xpressive/X-Distorted.xpf b/data/presets/Xpressive/X-Distorted.xpf new file mode 100644 index 000000000..b42495d75 --- /dev/null +++ b/data/presets/Xpressive/X-Distorted.xpf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/Xpressive/Xpressive.cpp b/plugins/Xpressive/Xpressive.cpp index 018319c82..a80a0ae41 100644 --- a/plugins/Xpressive/Xpressive.cpp +++ b/plugins/Xpressive/Xpressive.cpp @@ -53,9 +53,9 @@ extern "C" { Plugin::Descriptor PLUGIN_EXPORT xpressive_plugin_descriptor = { STRINGIFY( - PLUGIN_NAME), "X-Pressive", QT_TRANSLATE_NOOP("pluginBrowser", - "Mathematical expression parser"), "Orr Dvori", 0x0100, - Plugin::Instrument, new PluginPixmapLoader("logo"), NULL, NULL }; + PLUGIN_NAME), "Xpressive", QT_TRANSLATE_NOOP("pluginBrowser", + "Mathematical expression parser"), "Orr Dvori", 0x0100, + Plugin::Instrument, new PluginPixmapLoader("logo"), NULL, NULL }; } @@ -257,7 +257,6 @@ public: setCenterPointY(14.5); setInnerRadius(4); setOuterRadius(9); - setOuterColor(QColor(0x519fff)); setTotalAngle(300.0); setLineWidth(3); } @@ -277,14 +276,18 @@ XpressiveView::XpressiveView(Instrument * _instrument, QWidget * _parent) : InstrumentViewFixedSize(_instrument, _parent) { - const int COL_KNOBS = 194; - const int ROW_KNOBSA1 = 26; - const int ROW_KNOBSA2 = 26 + 32; - const int ROW_KNOBSA3 = 26 + 64; - const int ROW_KNOBSP1 = 126; - const int ROW_KNOBSP2 = 126 + 32; - const int ROW_KNOBREL = 126 + 64; - const int ROW_WAVEBTN = 234; + const int COL_KNOBS = 191; + const int BASE_START = 2; + const int ROW_KNOBSA1 = BASE_START; + const int ROW_KNOBSA2 = BASE_START + 32; + const int ROW_KNOBSA3 = BASE_START + 64; + const int ROW_KNOBSP1 = BASE_START + 100; + const int ROW_KNOBSP2 = BASE_START + 100 + 32; + const int ROW_KNOBREL = BASE_START + 100 + 64; + const int ROW_BTN = BASE_START + 85; + const int ROW_WAVEBTN = BASE_START + 233 - 26; + const int EXPR_TEXT_Y = BASE_START + 102; + const int EXPR_TEXT_H = 90; setAutoFillBackground(true); QPalette pal; @@ -293,7 +296,7 @@ XpressiveView::XpressiveView(Instrument * _instrument, QWidget * _parent) : setPalette(pal); m_graph = new Graph(this, Graph::LinearStyle, 180, 81); - m_graph->move(9, 27); + m_graph->move(3, BASE_START + 1); m_graph->setAutoFillBackground(true); m_graph->setGraphColor(QColor(255, 255, 255)); m_graph->setEnabled(false); @@ -313,37 +316,37 @@ XpressiveView::XpressiveView(Instrument * _instrument, QWidget * _parent) : PixmapButton * m_helpBtn; m_w1Btn = new PixmapButton(this, NULL); - m_w1Btn->move(9, 111); + m_w1Btn->move(3, ROW_BTN); m_w1Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("w1_active")); m_w1Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("w1_inactive")); ToolTip::add(m_w1Btn, tr("Select oscillator W1")); m_w2Btn = new PixmapButton(this, NULL); - m_w2Btn->move(32, 111); + m_w2Btn->move(26, ROW_BTN); m_w2Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("w2_active")); m_w2Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("w2_inactive")); ToolTip::add(m_w2Btn, tr("Select oscillator W2")); m_w3Btn = new PixmapButton(this, NULL); - m_w3Btn->move(55, 111); + m_w3Btn->move(49, ROW_BTN); m_w3Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("w3_active")); m_w3Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("w3_inactive")); ToolTip::add(m_w3Btn, tr("Select oscillator W3")); m_o1Btn = new PixmapButton(this, NULL); - m_o1Btn->move(85, 111); + m_o1Btn->move(79, ROW_BTN); m_o1Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("o1_active")); m_o1Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("o1_inactive")); ToolTip::add(m_o1Btn, tr("Select output O1")); m_o2Btn = new PixmapButton(this, NULL); - m_o2Btn->move(107, 111); + m_o2Btn->move(101, ROW_BTN); m_o2Btn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("o2_active")); m_o2Btn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("o2_inactive")); ToolTip::add(m_o2Btn, tr("Select output O2")); m_helpBtn = new PixmapButton(this, NULL); - m_helpBtn->move(139, 111); + m_helpBtn->move(133, ROW_BTN); m_helpBtn->setActiveGraphic(PLUGIN_NAME::getIconPixmap("help_active")); m_helpBtn->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("help_inactive")); ToolTip::add(m_helpBtn, tr("Open help window")); @@ -359,38 +362,38 @@ XpressiveView::XpressiveView(Instrument * _instrument, QWidget * _parent) : m_selectedGraphGroup->setModel(&e->selectedGraph()); m_sinWaveBtn = new PixmapButton(this, tr("Sine wave")); - m_sinWaveBtn->move(10, ROW_WAVEBTN); + m_sinWaveBtn->move(4, ROW_WAVEBTN); m_sinWaveBtn->setActiveGraphic(embed::getIconPixmap("sin_wave_active")); m_sinWaveBtn->setInactiveGraphic(embed::getIconPixmap("sin_wave_inactive")); ToolTip::add(m_sinWaveBtn, tr("Sine wave")); m_moogWaveBtn = new PixmapButton(this, tr("Moog-saw wave")); - m_moogWaveBtn->move(10, ROW_WAVEBTN-14); + m_moogWaveBtn->move(4, ROW_WAVEBTN-14); m_moogWaveBtn->setActiveGraphic( embed::getIconPixmap( "moog_saw_wave_active" ) ); m_moogWaveBtn->setInactiveGraphic(embed::getIconPixmap("moog_saw_wave_inactive")); ToolTip::add(m_moogWaveBtn, tr("Moog-saw wave")); m_expWaveBtn = new PixmapButton(this, tr("Exponential wave")); - m_expWaveBtn->move(10 +14, ROW_WAVEBTN-14); + m_expWaveBtn->move(4 +14, ROW_WAVEBTN-14); m_expWaveBtn->setActiveGraphic(embed::getIconPixmap( "exp_wave_active" ) ); m_expWaveBtn->setInactiveGraphic(embed::getIconPixmap( "exp_wave_inactive" ) ); ToolTip::add(m_expWaveBtn, tr("Exponential wave")); m_sawWaveBtn = new PixmapButton(this, tr("Saw wave")); - m_sawWaveBtn->move(10 + 14 * 2, ROW_WAVEBTN-14); + m_sawWaveBtn->move(4 + 14 * 2, ROW_WAVEBTN-14); m_sawWaveBtn->setActiveGraphic(embed::getIconPixmap("saw_wave_active")); m_sawWaveBtn->setInactiveGraphic(embed::getIconPixmap("saw_wave_inactive")); ToolTip::add(m_sawWaveBtn, tr("Saw wave")); m_usrWaveBtn = new PixmapButton(this, tr("User-defined wave")); - m_usrWaveBtn->move(10 + 14 * 3, ROW_WAVEBTN-14); + m_usrWaveBtn->move(4 + 14 * 3, ROW_WAVEBTN-14); m_usrWaveBtn->setActiveGraphic(embed::getIconPixmap("usr_wave_active")); m_usrWaveBtn->setInactiveGraphic(embed::getIconPixmap("usr_wave_inactive")); ToolTip::add(m_usrWaveBtn, tr("User-defined wave")); m_triangleWaveBtn = new PixmapButton(this, tr("Triangle wave")); - m_triangleWaveBtn->move(10 + 14, ROW_WAVEBTN); + m_triangleWaveBtn->move(4 + 14, ROW_WAVEBTN); m_triangleWaveBtn->setActiveGraphic( embed::getIconPixmap("triangle_wave_active")); m_triangleWaveBtn->setInactiveGraphic( @@ -398,14 +401,14 @@ XpressiveView::XpressiveView(Instrument * _instrument, QWidget * _parent) : ToolTip::add(m_triangleWaveBtn, tr("Triangle wave")); m_sqrWaveBtn = new PixmapButton(this, tr("Square wave")); - m_sqrWaveBtn->move(10 + 14 * 2, ROW_WAVEBTN); + m_sqrWaveBtn->move(4 + 14 * 2, ROW_WAVEBTN); m_sqrWaveBtn->setActiveGraphic(embed::getIconPixmap("square_wave_active")); m_sqrWaveBtn->setInactiveGraphic( embed::getIconPixmap("square_wave_inactive")); ToolTip::add(m_sqrWaveBtn, tr("Square wave")); m_whiteNoiseWaveBtn = new PixmapButton(this, tr("White noise")); - m_whiteNoiseWaveBtn->move(10 + 14 * 3, ROW_WAVEBTN); + m_whiteNoiseWaveBtn->move(4 + 14 * 3, ROW_WAVEBTN); m_whiteNoiseWaveBtn->setActiveGraphic( embed::getIconPixmap("white_noise_wave_active")); m_whiteNoiseWaveBtn->setInactiveGraphic( @@ -415,16 +418,16 @@ XpressiveView::XpressiveView(Instrument * _instrument, QWidget * _parent) : m_waveInterpolate = new LedCheckBox("Interpolate", this, tr("WaveInterpolate"), LedCheckBox::Green); - m_waveInterpolate->move(120, 230); + m_waveInterpolate->move(2, 230); m_expressionValidToggle = new LedCheckBox("", this, tr("ExpressionValid"), LedCheckBox::Red); - m_expressionValidToggle->move(174, 216); + m_expressionValidToggle->move(168, EXPR_TEXT_Y+EXPR_TEXT_H-2); m_expressionValidToggle->setEnabled( false ); m_expressionEditor = new QPlainTextEdit(this); - m_expressionEditor->move(9, 128); - m_expressionEditor->resize(180, 90); + m_expressionEditor->move(3, EXPR_TEXT_Y); + m_expressionEditor->resize(180, EXPR_TEXT_H); m_generalPurposeKnob[0] = new XpressiveKnob(this,"A1"); m_generalPurposeKnob[0]->setHintText(tr("General purpose 1:"), ""); @@ -452,9 +455,16 @@ XpressiveView::XpressiveView(Instrument * _instrument, QWidget * _parent) : - m_smoothKnob=new Knob(this,"Smoothness"); + m_smoothKnob=new Knob(knobStyled, this, "Smoothness"); + m_smoothKnob->setFixedSize(25, 25); + m_smoothKnob->setCenterPointX(12.5); + m_smoothKnob->setCenterPointY(12.5); + m_smoothKnob->setInnerRadius(4); + m_smoothKnob->setOuterRadius(9); + m_smoothKnob->setTotalAngle(280.0); + m_smoothKnob->setLineWidth(3); m_smoothKnob->setHintText(tr("Smoothness"), ""); - m_smoothKnob->move(80, 220); + m_smoothKnob->move(66, EXPR_TEXT_Y + EXPR_TEXT_H + 4); connect(m_generalPurposeKnob[0], SIGNAL(sliderMoved(float)), this, SLOT(expressionChanged())); @@ -748,7 +758,7 @@ void XpressiveView::updateLayout() { void XpressiveView::sinWaveClicked() { if (m_output_expr) - m_expressionEditor->appendPlainText("sinew(t*f)"); + m_expressionEditor->appendPlainText("sinew(integrate(f))"); else m_expressionEditor->appendPlainText("sinew(t)"); Engine::getSong()->setModified(); @@ -756,7 +766,7 @@ void XpressiveView::sinWaveClicked() { void XpressiveView::triangleWaveClicked() { if (m_output_expr) - m_expressionEditor->appendPlainText("trianglew(t*f)"); + m_expressionEditor->appendPlainText("trianglew(integrate(f))"); else m_expressionEditor->appendPlainText("trianglew(t)"); Engine::getSong()->setModified(); @@ -764,7 +774,7 @@ void XpressiveView::triangleWaveClicked() { void XpressiveView::sawWaveClicked() { if (m_output_expr) - m_expressionEditor->appendPlainText("saww(t*f)"); + m_expressionEditor->appendPlainText("saww(integrate(f))"); else m_expressionEditor->appendPlainText("saww(t)"); Engine::getSong()->setModified(); @@ -772,7 +782,7 @@ void XpressiveView::sawWaveClicked() { void XpressiveView::sqrWaveClicked() { if (m_output_expr) - m_expressionEditor->appendPlainText("squarew(t*f)"); + m_expressionEditor->appendPlainText("squarew(integrate(f))"); else m_expressionEditor->appendPlainText("squarew(t)"); Engine::getSong()->setModified(); @@ -786,7 +796,7 @@ void XpressiveView::noiseWaveClicked() { void XpressiveView::moogSawWaveClicked() { if (m_output_expr) - m_expressionEditor->appendPlainText("moogsaww(t*f)"); + m_expressionEditor->appendPlainText("moogsaww(integrate(f))"); else m_expressionEditor->appendPlainText("moogsaww(t)"); Engine::getSong()->setModified(); @@ -794,7 +804,7 @@ void XpressiveView::moogSawWaveClicked() void XpressiveView::expWaveClicked() { if (m_output_expr) - m_expressionEditor->appendPlainText("expw(t*f)"); + m_expressionEditor->appendPlainText("expw(integrate(f))"); else m_expressionEditor->appendPlainText("expw(t)"); Engine::getSong()->setModified(); @@ -861,7 +871,7 @@ QString XpressiveHelpView::s_helpText= XpressiveHelpView::XpressiveHelpView():QTextEdit(s_helpText) { - setWindowTitle ( "X-Pressive Help" ); + setWindowTitle ( "Xpressive Help" ); setTextInteractionFlags ( Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse ); gui->mainWindow()->addWindowedWidget( this ); parentWidget()->setAttribute( Qt::WA_DeleteOnClose, false ); diff --git a/plugins/Xpressive/Xpressive.svg b/plugins/Xpressive/Xpressive.svg new file mode 100644 index 000000000..ef3029c0d --- /dev/null +++ b/plugins/Xpressive/Xpressive.svg @@ -0,0 +1,130 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/Xpressive/Xpressive_logo.svg b/plugins/Xpressive/Xpressive_logo.svg new file mode 100644 index 000000000..fca1f0d98 --- /dev/null +++ b/plugins/Xpressive/Xpressive_logo.svg @@ -0,0 +1,106 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/plugins/Xpressive/artwork.png b/plugins/Xpressive/artwork.png index d5b39acee2eb1a99bec7c5581619f7436906b593..1f4e35ad51e06095d738315a49801ca0115195ae 100644 GIT binary patch literal 10950 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 literal 70956 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�F>nWc;KI~6AD!}HbH{Wr z<^A>p|MlB{q*H(nP7dc-x`kRwELMG)cRD#`;tdg9%Yi#3r~($@n$zPG;xNR-B#k0e zSq51q%471h;KTMkqUkFj+p_4omZm5;J~?DG9HHw5s-m)4ZMi(TV(1OYvaH`glb3X& zr^#H`CddP_EN8J=P<0iCp<_B0WnD6|M!Z|SC2tE9S>t|rho)-Ob;B}Ta4?vWMll~A z?~vpU$8phBohB26`;fY+8Q30{VYApTn2+ZS>>*`V^XAnToX*dASl<(65tS%Os{~cm zcw9V^l^L?6pjr~6gAqkrunl|9TalLx2Saq(;{ED9+h9Xlq~uM>e0)rlguH(Fn*Z^S z|4LdUJiEL>X=UoX=Kbm&mxmWDgC*9$rc?WB!`3XCM&M`t1|T6d47>qK)3FFwh^|AE zHI~r^NtSxwp%9!859vPkz7F(3PXrbPn>1iF7?6AfwRF)^mN{jXlT{_6>rj4o^X8Ag zY#+FO_KeANiXZtL9UarOO&=mDa$dc7N!2#I-#l=BbkaZQw6v9=QzeFu$A0fqwKWui zqHAb7iQ#yNND7L&(D!eG|yNk`~QSvPUdr>I>YS@R7GKz z_&j^|2~p8!rA6B#xOtM{rxBlj{yB;yePJvM?nnGDePvUq;xvO_f)qWr|@K)J=lk5M6`*x|Jd{rqQNgCblpIcdi$*HcszUZjBFLN2$ua4M#Df90wEgOrbCq#qAXWb!tpEDDCsn4Q1FHXU4d zz%LKK^by&j#Ifvt8KlvnX*yM25~nd$Q=uyws;Z%(6GZ_sGNxfslqFf75fu@YsJNJ) zGn*a}tU{``BCBI8%jVb5zvbuqpZVm)3*sa~myJG~jzL}2-+%KhMU`V47Ng0K`Qg0BzVj4Y zbyx>0il(6H1jpk;cH2E=nX?afNQ#VR8_dQNcH2E!nKE<7gh|N3c*J78!qH8#G$qVa uPLGawxVuGGB&xDTQB@>KMnhr~2mEjNPV$FS65jd%0000w$$WEky|T&0ftFLK~zY`)s{bN!cY{&e|bKe;9#p? zK*&}olrDm}gbq^7(vRdfs*4VtI=DInDeWdA5?qP~ihuIwbx5jG(pJ&IoavE!b92wT z=e!pUVAbi|0xjSkD3TqtftGIDj+T&k0j|g=F|Sr(#DVBPD1=WTL!5sXGeudlz>_*owy3PV^d2*+d8a0sOm7qwa(^L^BOPB<9A zVv*MBy*!mC(i%PFU4VSGO8)v9f4M}tF6(X=r4*u4A%AlNrb(D=&<_;Fx#&X+0-}$P zczt=f4HyPF(~KvR#8cI?&qwq|!vntqOyz@1uY^X zlbVK5nw%1){CO>gdA*-|r-9n!S-pGCcfNDaJ?EbLNW85ls3k&x3QPT7ZmmN_X{JlkGjq6f<1yZToWiQ04@V;PC@b>vTT51)!m<%UY<8>8 z<5F;NSJ;Fx+IbvC$@)(uQ@B6+8Uw?B&(If-006Gt8pU`rg_g!GxH<9?19zXIx3iU> z2xY4H5;-KuiqlkH>X1O0s;^hLRWxm{$;rWsVfEKE4G&+8BQZIx|6bKPM(I zGy4N;%L;XTPv-#uz^4!IG5viG6{UVI7X<)^tUw|Xmb4`sz|`MFLhQ^{WPMDSuD$vx zG1XqC0DxorcW}8f6;Z^er80`*iYi-67=2VmQM_hT z&U=lC2&xG`|z1xSVV1A2-V?w@jF6gX6rfQCaBEpmz^m(erE0` zo{v2;VXAAwaJs!*d(dBi%BpR;zse|rp^d^34gl-Q0|@v$w!P~2766#jllwF+c0veb z)vd3;ew#)2#d{{q?emrJ2Fkeh=GqN78*a)O!z#lMULjQCM@I)AN8)Wq4O+DQ(C-I_ zNYIuRO+oT`z)X4r$G_wiVXhBe5shD2FkScqfiH5Ny8L+mgdxl2r|}n~M*xs^XF{_8 O0000|W` z)05%g!Dx&Z2t5&=z(?YZs70gdFK2{d%mv{NyOC*YK1VgS@c+=--;AkMv^#N)IQ7nKS^2%P6qz} hFgIzP0BX8v+CPa&s3c`Q-x2@-002ovPDHLkV1gvJ)k6RP delta 698 zcmV;r0!96$1f~X%Q3~M!3KS*_3^Mvtky|T&0*XmQK~zY`-B!Apis&M%`7Yyw<$74j`lce@M`e*Z$5v;mv28Te5G2&(2;ITCF59H%VDFSTeWLOQzNQO zZ5NT(i@5mYRZE=Z12${6YBb|{n{{_$5L6K0_xmAm4xe(hhGe7z zC*x83dqj|A5JF%W26v7HNp6XMiL%SWe=n7h{_v>*b1D{r;JXLUioSK1EMt4MZ(f4S^xk507*qoM6N<$f?7XDOaK4? diff --git a/plugins/Xpressive/logo.png b/plugins/Xpressive/logo.png index 68b613176d684bd586ceb10ad2053fcf8309e7d6..555c3f13e682a44b0ed0ebecbb233f5a47470bd0 100644 GIT binary patch literal 1884 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 diff --git a/plugins/Xpressive/o1_inactive.png b/plugins/Xpressive/o1_inactive.png index 0fd4f8b2989d027df7529e31e3c28a34d7690230..7a6b603e3e79540dc6c86a90980343dcc63c57dc 100644 GIT binary patch delta 471 zcmV;|0Vw|b1AqjO85#xv007MxCy4+600v@9M??Vs0RI60puMM)ks%&`;|dB37y$Q2 zOz{8!03B&mSad^gZEa<4bN~PV002XBWnpw>WFU8GbZ8()Nlj2>E@cM*00Cr4L_t(I z%cYY&io#G7g}+3>pNIrR5V26u`e7w#BXI+>2f+>K00T>R4oKB~|>9RV2<2Wd#Fbo5K%d$wP(^RWf>h(H7 z5U^Y>Bh9J delta 493 zcmVeSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00DMM zL_t(2&z({&%K||Vo?S%^R+GpbDkeejFNjS9llg)MIjhJue}BVS#Bg9T8T1br44W(p zqQzhmlNW^9)!R3$tRL@-;5%WNdEl96cIF|LWx>B93;>Nr;|(Q*NGU(ihQnbP0E7_F zsFacrq7&VMQmS(GKA6YjaWELHRx2SyE|+UIo7rskxufg4%jMGZyvMYhbKmz{t=8po zsZ=VlSZp?%*?+d}x~^duQp){)&lsCdr^#fJbN2x|CkMDLnL?ndt`+WeY*XvSBA;il+RUw4X z+oF^PL2$iZ-|`8Iw4Y1##^_%;|)00000NkvXXu0mjfSBBe- diff --git a/plugins/Xpressive/o2_active.png b/plugins/Xpressive/o2_active.png index 51897412d42493bbe5e5ee71851fe6bee62c6136..4e3b5f214d72036360dec9be83298432cda3d78c 100644 GIT binary patch delta 583 zcmV-N0=WIt1&sxeQGeqK3JW6@rYJ`u0000TX;fHrLvL+uWo~o;00000Lvm$dbY)~9 zcWHEJAV*0}P-HG;2LJ#8@kvBMR5;6}lTS#KVI0Rl&%2D})>sr7jag}EK{~Lo3~|GH zAx4lbg1VTopi4xT==xI8!RSzV5_Yl(>7e0t2Va6h55|Tarhnoe-X`T@y<3}(YI{5E z-QZSY#Aj6W^aeZajkF&3A%_Opcfdm?o#N^Jn*azQaJu&3JL5;bGK9@$1LzkK zRWks_ojv4-&uOHJDfCm4gru_|581d0FtXq05lzJ zt|$ZGX>J7|xw2$|tuB1#Lv#uu1RbaQtguQ9AuL6PVSm*8bUO8w*CUTHN<}UY-KFJN zrxoToe6*~bT%%YlRxj7J<+9Y*oKE01(Z*Etz z|HiWi;XoQdTgNE|?k^R9o%0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJ zAV*0}P*;Ht7XSbPJ4r-AR5;76lUqnsVHAbGf6n>O@rX!K69y@0I^MFtK#WR^$|$sy z$bw1{B+7>nB7=G>ib%+^z*4$s5|oyLP-f5+g4uBQ!W~)BD+tciKxtSTs55`Gkk91i&*n!Tpv>+Zentzm}bT+5#VN2Zi)V6zFwX!BrfQi4+|;5ol8jQi+X90KnyLLpLP4A?X|JWPDw;q;rv+gomH)e6RfM+isQ&C&W;K%^FZqW3!4nWFU8GbZ8()Nlj2>E@cM*00FT{L_t(I z%cYaQisEn-g}>;^_>VylMZ`kElp&}^L>n=MHp13EfY0G0h!3Hp2s=+8i=9^f&@QA9 zL<@_U0SSV^ZPXo+Ep|MA<-OeRo&)zv073{A=mSmQo&VDZ&{tJeNLSErAi?)_02+a- zqgOy&=legd(Kw&aOs7*;s}+aCfp9oXKA%U|b&|;>uIn-w4DQqMcpODh&~=?)FbL3; zgb){i(P)HaS=4GZ>h(I??H0o@2!%rQdOZ?}zvey9!!%87+osijYEi9L0SEwWHXAI< zA{L9$Y&MBTqZErpN~IE>=P{ej9x_ED5z^^20Q>#^UJn3lw_5;GsnpFf0GUjNul<|W z>oxQF8~{a89%28IBuP&-$8j(W1K;=QbUNho`A1kbo4s51egEFv?RI?apH3&n<1wD+ z(QdaXm&*@}0sy&xTn<^5IUbKpCKEi*!?tY}iv^KL1WnVpTrQZV$$r15QmLS6+H(>i zgbTdiPGh-T;<_$xZ*LR|h5KnZj>B*`d;-X_Ot;$w_>_bYzkr{-u8-RX99{$+fPO$# mRRJ`v5BvEYM?gbWRq+R9i>I-$HFU)Q0000eSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00GoV zL_t(2&z+Lb%P~0rpl%eq>>#tR)sx zGbO80GB(OW%7#ey-ZAqo?i+7!Z%;k%S=>(N-p{@Fd(M~1WHRtyVFZ9&F85cJVHjQ4 zzri}4ju8L|A%9kNU1u2PoxHDLS(fH>{gCJLxz%dPvP=kZyWRPG-syA#!2N!2Hk+%} zO4Bs2*IO!;tbbN30I&dnF}_?b#bQwu#c((rjYbtkDVNLp{T^f7Znx+2c`z7EBocxk zG#U+r(1#q4$Jgt%P$;C+>0~lluh&&o?e%&X(@GTw5 aPvaL|eiog_CX>@2HM@dakWG-a~00059 zNkl+ORA2PcP^nuYnsqFVdGx2+8>E-%nu>qyb)D~yiI`mglHmgJpXwAyCSrEs23IbOnQuR_k^lez07*qoM6N<$0fGfI?ScRR delta 650 zcmV;50(Je)1g!-jiBL{Q4GJ0x0000DNk~Le0000K0000E2nGNE058Nm@R1=ff8Yxh z6C@*tXsTlX000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}0006NNkl3!Y+9-q&xUNT52myfWx*MMVjOtndzy>uVV;49xd<<#8IErhd=Qw@kD4)N7 zz&MJ>6E`?@`3TEvxp5Su6F0ed=Oi|$F^>8TsEwjCoMN@ILg`}xr6u#le>4I?{{1Z4 zDDtIQLfcws4(()dX`bhk51DxN6d}BRZK?sSB)RVZ0Qqv7r7tDE{rE~E+DooDO+Z7T zlqC`AL0iey2j_V*eis){s zu3n^+WD99x;Z7PhHPF@?A)R|iDsj+fvVPw~1Y@V!Z24YJ` zL;(K){{a7>y{D6rAs&C@3JMDl3g1gF=Kufz9cffpbVF}#ZDnqB0000007G(RVRU6= zAa`kWXdp*PO;BVmWd{HN0gg#TK~y-)t(3j0;$RSlpCre^1a%dHn#9h2iC3WBfTy*w z*4i8JA_OnN&dnXTy^vsMBNpZp(nL|QkYKhkVb2eoKi_VKnP-3A8TdX4!1KJ{zzApq zdA=_P7}>VHl$cuX9}^m;vX zU1z;s<2VlWdYw+E!*n`jx7($(!C-)@s!7j^E?}lG<*!%WybE z)3o=8^$P?MIRUR8^%^Dsj172*VKH_o-H^SeAtlf+&gz zf`CjWgRbkJ2mim~cDp4A0xZj-R;zJ7pINO|+-^52l?sZYd<~qe=(;XZ6k(cXI&866 zeCZ4TPp=(^VThtAl*?rlMWI+M5{BW6n$LodK)z5Ykjq@3zGCTN;QzuyNqN}lKa0iJoRoaE&l9tb@EBiXj?CD6QoAjh9N1)8>P aFaH63d6FP-C7pf%0000#7ev>NpPhZM_jf zrqd}RerZrj|GxZOtJUg_5F(}g(m+H?X)NMj7-L%NlMzAyU_PG@hr`$F1pu?zY%myv zVF&=O>-PKoFbtJaN-5WMCzA;PD5WA;O4;djlv12?A%ySyl+yivuXQe$OC%DU^YwbY z*=!I|N-2bhJWDBU+a`o?&P~&NKA+ug*YmtyuNMTtXfy(V#bWVzJoLh`%?M5=lc`k7 z^E}fuv)OF3+1%}R=kr-9)oQh*l*{Fk5HcQ*5fK3X@T`=wZToV$oKB}orBW`JgCO9X z8-`J@*YyMKQ%?qf2o^#JAuP+f-|xrcu~aH$G8shNZnup_BYvQLB4Vtg$pBER)fi*9 z+by5ZBVwUYxL&W8Wx=P?aI8OI##pslH4G!2P6I%(SR{n#o&N_@$8p;2cAScDq7r9A n$L4T2{5xSk$hPnMzk}ZaIqgR7(&?4!00000NkvXXu0mjfg1_kQ diff --git a/plugins/Xpressive/w2_active.png b/plugins/Xpressive/w2_active.png index cd4729949e171992a25d089f90a5180649a20d74..17d7b53d935a12a59d14d7b253e0a3ace613f751 100644 GIT binary patch delta 680 zcmV;Z0$2V115123j0013nR9JLFZ*6U5Zgc_CX>@2HM@dakWG-a~0006n zNkl|{}T@(U$L?8{m^2Me+bA#@@_f!KoGC3WM1pzghrcA?dc zP+m%2MBQeaW++|c2VN<`D34(ce?i@_scUVdve~hVoekFRYX6%T{yhBnKhN{NuK+L` z4_*TNKnEc6?+O5ZceN)Z7|I;>2ynVwrlHPEGWC;4EXqn)!)0@!I#jeZjdUhW zc;g$#%T8c3+Y7*2SYvYTe=Pz6t(RL1!2qfwoBGpgh}HG4C=M0noJu^g%iPC#4u2ow zv^sM$1Ym3DJCC0~Lf3Wf-+DmP`KDs9;>gZT z43PSjqSx!Av!%136X|boG#25QREGVm1IZ-OP-i9@i)0sP)abg-e$a~{Hn!HecJ(@4 zZCyooP6CpETwha9O=T^+i5;9aCz46Zr;NrTh@!{^n-hTTAKNS~F99&UFvax36adZ2 z75eY>10;pnc<>EylhP`XdwGcxLKA>rbXR*qK)dmQB>y)l(C)7Gg#G~h+`ll)ZtaQy O0000_CX>@2HM@dakSAh-}0007JNkl1wU|D69<%TcqGgiH}<9H&tkHMImGqAQgx$~J+Liy#oeMbRRnb}bAf zh!kuQghC)j#B{-w!b`=7XkNzge=?3TIDtjjjhy*gj7}N`E&NvJ@O|gwd0$?RQeRPL zu!$uAl6RJD%CdmJFT7A{0!2|Uj4-UCC;%9SvEljeTH6xKTYe+Qh03d3Wf6$&)NHDa_ z!lyZeRGIaAP*CuFoJ48@-@+ux+fwNrdcnJqZVGH=9NmAGL3bYyo;D&iv1XyJlAp5| z0AIkv;?e@&e|{w|yBM$EO_YSWg&FcJMJ#>^kYGxp@>mTg4pb5wy_H$N2dS&;CGXyq z!S=)yy#5JHaVAoe)5xJ1uJF%JbF~!Fb3Ik8x zOA2y}QB{?hISJF#10$xOH4@s3fLw-2ca+McxF>}toHVZ~~;)8l$YcfS)&m+L(Y zlg4AWIv5@sAlqz3N{P*q%lPC6N{hV!Z24YJ` zL;(K){{a7>y{D6rAs&C@3JMDn92u$jGynhq9cffpbVF}#ZDnqB0000007G(RVRU6= zAa`kWXdp*PO;BVmWd{HN0s2WqK~y-)t(479;!qfdpHfVe&^j0zq^%|vNo}7 z+)lgzZ-N`(BHVcq(->Vldtw_|vB3?ei!Q9B5+zN;nZ-~t47-0B-sQ>nJ?DGh^P>QS zVR#PofDWMZ@A843<2WzM0{Rp9#%44DE=!9^Hw9(E>Xm`c)6)|{5a4+puIrLz8Mn8$ zNGZ9wxxp|DMxznF?{j>7jOTgW-Q58orKDP|a(a5o#l;1xsseP%fNoh9K@cE>z;#`s zC_+jJfDi)1Fo=Jm2ms5n&~=?|w+p~*Hsj&pf#>IEG)<%3ZUg8g0Nb_!md#NVv9q(Y z0u(~@w=HTFf>2%6)IAni5pR>QeUu5|E_$L$Y@9&XP za&>jZ;o;#rxUd)m0ePNdS=Ms1e!ssKLzZRuzR%a!7oO+QYPD9Jl>eSMNfK05rO{}h zsw%ZwZJAwBBc+5TPR0+fI2k@QE$}e8tWP{KN&?`BP^8#EhK9KZ( fCj~AY$9ee$YuLwPkeYGq00000NkvXXu0mjf8fzlE literal 628 zcmV-)0*n2LP)C$482~`UdcB^@<*wH& zB0fJqvn+c&9ucwKZfCPuK@ghFCdYC4e7@0WoK7c2QND_0SxzRCilT_3c)Q(}%OxRX zHk+y1ZnwX^y$uF~OeRw(6h@;_tJS*QZja)4JPrV&DDLr^?L2~dOXjwEL$uVpPrr`o)Hld{eC~gFo(mz z;c!q&old7DN#Sr95&Qi<&+~4#+wFEwCX?ZC_~@)EhGBd@-)6J1SS*O>a=CW9ojUV; zJ_i6vlDgfl`r)Zm3IIr@Qi;W4cPjpY%AE}ro5f=Bcf$UI?d5X$v*KUhryjt9k`j*q O0000_CX>@2HM@dakWG-a~0006d zNkl<%?`f4B)gTr%k%Jie!mZ2zQ5;rGysX} z;$nVca0MB1O10eG;!$fp~(4!Fd9^WN88)g6deh2Os0KIINe*wrB^8ge+ zec-Tl*p=(7F1s6mWID-%I}eFHjo~=wWaV9gcw(so)(Zf#vt67k=2S@kiGFNW`w_70 zbOA7admO8IkQOa88VvxaO=na;M1WH#^$eP=lq)4ll`@559+%C9*=S)cyGEngp!j8r zW4hzmtai0|Y;ugfdKG}7e@j;w9vW89gwDq8Xsdp|kzwQWCbGkge8Ek%w#!O-m4n|0 zNarO)tyXQGnVKOsHH*jXA+`RNx%k{su+u1w{k7O_#oyp^r9_{o!+zF*s1;R<09;B+Ww3G=xDMzo zCJQFR0K2tsNHz&kE2=8Xl@fv=aM30KAlW1e+XW_HJYlz9Wx!x!^!hDA*G4_CX>@2HM@dakSAh-}0007ONkl4TBaws{=3R;d##c<4Dz|l{y;uh8GC^ z2%rd=p`aHD3IEqVgsR{V^%1{0fw74oEgcOM<{skUo-%p{-{XE#hfr4=YBG+D-2nJU zy?mbzG52$Z>~t4{!5*Rn1VTQtEqNGCMv4ncDcN66QQiRngb)Z#URjD}6ztrQ%$7}C z84UIk8xu=Hd?MLaCoenOe;FMQu(0?Whs}i}!->P@P$T>8lSX)^$ zsN~r4>GyjW81BKGWW|!2$-rFefX`5A<&F#l_od(HJsPLE?Wn3$QJBExJ))x_F2 zTuK^8mNkbDpSws;vm%7RX0hYx>!u)YFPc%Xudo>Z$N-Pp+|15RlWWhX^3=shLaDm6 zQZG4vA_Ar)Nrc1UHwd)L!2b{6O?T>-5-!JGk-Y8&DGKy3|C~iC-@jeEVV}bvfda_n TSmoI300000NkvXXu0mjfXQo6i diff --git a/plugins/Xpressive/w3_inactive.png b/plugins/Xpressive/w3_inactive.png index e5b0bc7d9e1c94ab1cbaaf9733c12fffc4a46489..d45d8b497ab51e777c96856de43f5b2c8f5930c8 100644 GIT binary patch delta 635 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

aCA@j!VGXO8EgAlu;)c1g)$M1Vb*@D&h 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 diff --git a/data/projects/shorties/DirtyLove.mmpz b/data/projects/shorties/DirtyLove.mmpz index 177c05ce5162094d4fa92b51ee6cd1be0755baee..37b766f4d29fd4c1a110ff642c0b3b5014c0de79 100644 GIT binary patch literal 8595 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 z z$d9g}l$fVHXBN`{x(@I7v4SZHx>Y9BB# zD?~rD=0}TG5QvQ5pd}i%dy4pRPQOnQpIdglTtF>4uhI!THMW+nLEh51VgF1A7aW&K zIwQu?9xm6W#)pZTL4zZ_6oYDdL4bBxGoka%xgEkL;#3=z?g)b&fm2{(8!4aiCniA0-Jpwi50 z;hVU1yp;xV)PeuIlLr1zCsq90NvEuT^VS&9@DI+UZxTEPBD|O;#OQ)Nx zmZj0zHe`GmKHW6D4!5amR9&qx}1_?^NZX3tR(Kv&gk zO-%4i8iVj*f)mh}7d^2_)F;hm$AU0zkew3PL4jBrUEpl{bq958utF;(*J4?4yGur$ zZ{2pAf%9uX)1HSZt?((iWzyjwVwrQwXdTVe$MeMe;KsfCu_o!(I2|Z7aVX?Azaf|6 z&BdG~I2*ZSQ?JYH7SAui*)G|+QtUwM+)Nm)8!qxRK1k zIzQ6?@}x9yP?ZblK^Wd?t#aNm4xiHLmAfZfrw+wJUdiB`#3X)Sx&=FM#1Sohol_H{ zu+*nGdZpdru6<3pe_#5Vav|_+#MMrsB`V*&Eu=2N`kwNjecf`rwEfDt#cv!0)uP?b*u;+BXZPLCD+A5jW!-mfMS-qNwQf!#UhT8&x1e-#adGPX6Idyij$31NJL7agN5_SZV)e zDvG2x$A3Wn3HQ<%Yyr_P4e&4%7wPE%W%%QgW%{Q8ssM9>@cmlNQHlPem*ZitEnQ`LfB%FGj0Y%`gNi{z2Z zlRt`Pm?tLeWnm)Xf8%po<@%K$7dJr{>L!dxDu+iY!v#hkcZ%FBDRO9vgU>5(Csi`` zEinO!D4t29Dp@Zo?0@f@>o?wE@-!1UsD7^t4h0UzxGsLOl;5o@!#Y&X$H*@0%iuT7 zLTXS4CCY-77uts4OC#+y4I=khP7r(y%@i^tkn7%N8WS-d~&iW`WSSxGBxTa@=h$uC+GKqmQx?myb@d#H?!BoLN^{1qxn0 zNKY1F-QIa?h5;mrGmW^voj?%&A>V1dsVvn4BoyS68CQg4-F$Re6kSvCPSs-I@M@BB z-qP=B{f1dC=Qy6h%0dH8t9UIjt7DFsrDzAjjkD`@32&#YAC{dFwoBqJpTA}9^sdvX zwgE49yZ`Vc)G=|VY?#rX0qT59=}FCxOjla;XjfNR$2gT0By&Q|t+g9n zuX{Y{ae+XWQ=W{D5~s`Hw`pj{2aV1tG+U)W8>UFYMjkl3-~8=w9D^`s5;9_IB?~bG zg>?-6a0DF_HCoNlW)PHCDyUlzaJ!BAmnCqa{rrQD1+~RUaQXfQr$g|hMg=J6%dB=x zK>BJf08i~tYTsijd0bw$PV{ci44i8BNaugzK)y0M2@guO$sMfZ`ATOVR*&40PUeB!;l&VSmyCcd0=vDeM zqO;KXc}UQ5sAC0t5lVaRK2kEK!MBy^WAt?-;%swMu~%wk&+3jx_XRqeM8tp>Q8ei6 zA((E^mohxuqK!Kfp=t|XlGS9Qf5F`X>3f2miv+NiX&UKC?WUfyq?W46faWq_yF1en!6x-(qeOJL!tPk3 zDeOo?5YbStb~ZS)iNOEPq_ABHlhac0{d24%6My7WbC}ChvuD}QUe5g}|KB^Xz zuGW-VP>jb~Y@Jppj4xIB)?%O?%3dn<6Iy7)j}y#o=$*BEXoSp5pyAe|u%pr+0ID$K z{z87W`?y`942t+`xul`hG81)f@N}_1Lj^4zhY7`&t}m1bY_KVG{CIqg;2&04f{OC| z8bFuhSA=<YN-`R=Tgm!5yj3(FcRZt}?xY4T*q07mVo&yau6tucNqR z5^bI_CB=EZ!dr|~@wzWR1FFr$eu1qgqdk7?js2nrJI2N=%S=C`l2Dq!XoNK=-;`-a zMRk0!{v=_K>RK+c&#WzEA2=OjJ7O}qnhsx7QbY33 zyu=A{WwyaXmt`u?O`n2x#;i464&QED<9AZA(4k@L!~Q%W1NS-q)j)zxD(gJZm5Qaa;= zEu~Da%#lPAm$xn)wM>Fa9!kW|Z;tq@9Zz%ZunoIr-e?kkl|~<7eJ^tD&AOq9A#@`U zak-x_*t_WUegHWNnO5drQ8!N2Tn?=S(azr_fNUWLE|$Je7k9)m!)%T^dEH*^aRe_k zP6i*&l?*XHRC@2`0##>vs3dqtC(rqVSJPnt#y8n0 z8MOCrpmIrDE*}HIH`oo|Vbt~*OMdN5PSccb2AgWx z+7i}D)&t0IB^IyTUV`O@aWH*2+H6{wCLTX#wXi^Aeh~RJc8s)(u4V(i4gg_`+Zb13 zNusI71C>+ysw~dFT`0={bfR$kh=#bn0?WF7BD+w+Yj1Ic1s?i7-l9iTmR~`%7#ML$ z_06X4WUJyiOzfI_OrD;jRKx~VsA=fnmW1NnUD*)*4ZT%%OF&}xUYyZK355F=Aqs#z zQ32}4mXV1d3r23Dh^z(4my=+W%B4ZKJ8=!nPEv1$U_4*w4rQpwbbvx53c)bf2t{K4 zk|dU9edOT@yf^K1hHa2Az3=9U!x&y$wJql`mW%M^7%;Zrrcc|Tvq0CR=qy$CcdmTs zkhtI0NBrLMYFY)YXX+)o%h|LS*>jvEq=O+Qb`62R{S2ecee!K%GnAJ_iu43B1h0B2^wE$#f1`Q8Q5U{77KG;1in!4PU;0rN7{# zr0FWWAh<^r?i1=uct~@$aGdB^Z>ac#0KKVK;TD9?R=`8n z_T$(4h99hFN{h)ZpgzMIVJ))vlJ!5Pw7CnXX$Bph&$NRA+A4YYzJ%VhBC>>g5 z3u%`fT7!#;kvFVFj_MNzcHxwrVtnI$e-Gl&^wxg z_Czr5vfq6hRPgYuZ&O`__S5nLm|4YQ0s>!RdmlnsU_23pWYYWfvJS%{j?pqUfVgD5 z&&^HuItP7Tkvxk=gPY2EwckfFN93opKbg@rluv7`{wOB=mEL3ZlxBXP5>p+uxdJ7)q+k0v;0exMdDrW3Iw?DZ4%8E({R&F z)hQt3&sgiqtG{b~L1rzRW>tNqmuu}zL59@|L927mt*43G>$X?`a5lad_PV2|nX`rF z3oo8b*n18=>8S%2B2uMw_0cw87dnn*CReQg$Tf}d2aS$l&^%n(KRhx`awav!pw`;r zf0hQzPX#nO=-fJrO`AP%{5Sy(m#zl- z%V^#IKKt(Oz^HfBHR55Y?v{|bzz16-tW5Ov9)-~k>Qd}1wubZxVX*))HA^OH zm0i9eXP6|ZH+}$4pDEluOxZoCJ*vgoK;IHli4g;!Qbg&Fzrv;ri-F6H+l_~k?aLAo zi$vCagV4NFlKq&}$!VpN)%Ioy^riEKq;${&N7V;}Eykp7UbK@Vd$HUluzl4wlSR@+ Z#p(RV*qTLUG8W(K_SY*y(nBWnzW~JK7#IKm literal 8660 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 diff --git a/data/projects/shorties/Root84-TrancyLoop.mmpz b/data/projects/shorties/Root84-TrancyLoop.mmpz index 22bd5f2fad7d02e5c3d1ab85514b923889a26b5d..f5eb032acbe4c5b31c57709bb4983443300ea619 100644 GIT binary patch literal 4386 zcmV+-5#8ob4U$lB34)zn=o@kCUoM%c7fa6!AVx4O2zFPiW&f;%db+23x@Yb( z`uf!uvoGI#|N8vr4{s%Jvx&!H6#VAQ6S!XdDkZm}^Kuji{%XWykmiwNCqeXb^zQxp zAM>vT7zLnSeIZG+wPP=&#N9ZtySi97ez0+UHdGr)m*ED0Rdpn7>^O0v&`sv+m!q+j zUAPK7004p+27kM8qHMfODUkV*5AZRG?D@xe;3u~0JCStd#_pvDEZ~uJ?Jg2PZK(Q4 zT08D)oxB_=CJ-tzc>|#E`z;-@v2Was``KB%9Ki%&+PiOzTt+ZOL56IT6x_EraOqnR zi~Ow}#~#c_g3EE>1w{ma;_{Lr*x1mR|`HYZ_+EF?bH94b_`0A0Dj#ZN!!@rGz0jc zpCa2|QF-jsb>g&fLB&83DV>DK@(XXtA17WFi4v4E*y_7bM_(oX&rcrlnN&`So!GMzH*i>QG7sQCu~5xjT0&ZI>yUM z#OpBq5H3nGrWbh;-(ZC3fQZg$!qz86n-Z%KCuJ7I@qCyCHFy@x&SYi_6~D~aL9|E@ zIf;JBHz4+vlB1u-j&H+Wy$}(xqtIEcT#5-kFWiU;EecmQv0;qZH*(;WnC0XMKt*EY z`)*bl23|67wKzQcPaqlPsu^$Gg&PJ@BDsFJg}vAI{dA?5?v1mcSFao|n7hd>y&P;4 z0tiP?6nLH!6)$F^aXOk^=7xiq7dAca5C_EexG~OfftRw1>I4jp;@^p z>;UzqfQIO20H6m@JhwgPf*n3y0KS;JATEHeQiHg%y{+hgOR>oHbl5b^gQlUX$U?f+ zVj4m^Y#P=<)3A`KS(chlqfY2@JsmcU>0PTglX?9SKz(#>g@j=3_Jyk3c(Sa)tTcl`)BZJ8}@71gq8IS(E7ns5U6- zkoB-stXt~zv9lhEqQf74?5u~0Ow~~DA?s1Ie#aiP-bdc!fnrw9nd=<4_7vkhY^Yck zLAP-6ID~LeM6`C-c5(qxf$uDk(k(E;N_}KR#B^ejQI+^;fP{5@2#|&VX$X*p0BH!2 z?khk-g#f8yT)%!()mGoxeNvj8_;;Z(drIvp=onJFeJxBkr*2r9etpcj7l5DPCQmKzIuppFjrEza6C9PqM&P#Lt2PxVjKgXT#QpGKGtbu4vF+3 z$Qgp1A;=kmoafnTq$sC)ca=HCnnG?Jf80JJ6KTej_>_$seD0;s$S|gsiOk{ds*~w5 z+IQ%lako*WD4tu_Q64QhH=zd`eb+e2Ql3vOC_Ss?J<+8x66!NX!g-9OWHFLHG4dEm zo$5n~G=xZ}$?Om!4I$DK43Uh}y%_^*Q&rcM#}1OPW=^$MvD&=^Ns6hPn$jj#8*aup z;xK8?n>&(PZ(luY4;p4wiE`)wJdSwpvmGL}W8>)v(G6Z=;kawbWu*VPbR9!K&!ae4X6y#YLVGBS09rwDWn%WTL zok);Z@Z*joz*GBaAUv`MoS~iyVo$U!vY#+|Us;c#iFZ)f=cBF%-C;QQKx@0+S*W3h zc^kss~t6i4mMKqMJq!j8wSQgon!6-{nf9k}Iurs@0X9Xzx-*`^Gz?7p1HD@&b+} z=Inazf}DHwxW?p(p70}cM6)-Ckq?)O#=zHhDhfJ~{Rrm=V-1E<#}$!gNb-&0<&9S4 zAB#L=GxLnqiJE!Fs#>bP9qbYlCna;8klNmN>d|w`{U)+GS36G6#2J1TZg77h` zl$_pY;qD&r+OEf}qgACHTD;t+=CwX`6)r{7b+mhh6`rVSWidwdHlMo+G}WbaV(M6_FAs{#q%{T7y2ex0#MHfPK(qpP zO*yoVsDV_K+}zTDXa(*&Zv#9oo2n^sHZ-Y=Bt0#sUn(f^<111mhibMsHB`-_@tC@8b<=IDlWyxuC*9VyPP&~BKTx-K z;}6sAocngVJuN=O^r3Z|&k~7PG)wx?Mz_nOTj_Rrcq`pDOX6*%+vU}1rQ2odt#rFQ zyq#`WiN1|)SI~bt`!=62zGvOu3FuLDTj`|R+Ce^vSz6pj((S{1k_y{6aNkxA)$Nv< z_YV-39FlpzqlZOn`{cL-x>pYATft5HR$wx&zl!}38~7LO68}5|@)Q|S8%x^+ zJ<4y6nUHsJu?)S2jNUTzPbsH6Wav+c&2}037I(l58TzM@p|88&O&`ItM7|A zEIn(1o1+vSrzYqQ>o+}%HC5LUYDBcR^sF(}G}&b+y}Y)OL8+V6h;bU9eauAFCUKdbi=YvwT_x9Pi*zIwat*N&&~1YxU9e z2Wj;|`>j5OP9Ho`^sLzjXU#sSqS*)UHT$HvQ2B9Zv$Pk8-xgipv7@v^r|Oz+?w)0d zCPryK>ZUmvEl(O4iXiH*sgi0&DQ8fsFxL#HPguRpm z+dZ)LSR$!Wk0J*%r$TgvWFUbP zfoVl1OihSRFLGgumVx>kyF#pRQR#c51qIt8*tEz5OhKSYsK|sa!bY8u9842pQ;Ixj znoxac*S#KxJm5Q?*EB;0c}&Z=wRII|YR>8J@0I&Q*)u2@aPt81vyYH_bg5-+~a zS+y99Giss6>6}rE71%(H?7`rST5N>|Z`8s~-QcZScpw_QRf~=$gR^Sk$!~C0t%!xf zS+#JdGp3F9SCg}9Rj4N>XVt23b|z=ms!+xzXV#*XH951^L~3VpcCGEnB)I&Il&Xq7 zR(JcPd8(5yNiVNu&o_;wPr0YH=x`jiQGVhiR)_LxEuF#8W?U| zfA=k)04*et77NnJkUP9-M_J%)(_2}JemRRJc|20fM+c@A3_>_#IAt>Z`a18u_yOeb zlj~epaZd_yIsfz!1_@YX`)nYCbTYHhwf%t5s-j?M1qyUyz9Ih9lv0@DMg(?i>?~Z; z!E+~_loM5FoY0n(CY(e8(KV8ch<8MAPDCZIpUsFUDG`%wU$^Ad-t`(Y`|_99Z@xMI z=9k%*Z@zzh{_}^o(%;VCzmq=v^V@fSe=Uv1vivXgwJg6mf5U#zCPm&)! zWcm8~dUCB!f@me5{~-VH_Vsw3Y&;Fg}LBU-O)0a)t^QB1(r|8GlN~ zmtHXcIClL72;&TB6Xx@;00fH$Z2Q$bo!e{BN}eTUpC!;l!1A6bg6+9+;?AY>$oA)s zeD2KGejtB{Z^u6duuN;$UrFzRAe?|$fhb5deDaKwHZjmN>GD>Jf*`Rp=}&g@XW0L? z(cD>rB0Ce`NeT?lWTHewqlgm!`YX9uFv=`>2S*2e9-on85`Ni!J_Em0DC z6v-nge_W?;lV|7)QS1i(%MqTS z(buoOn0@)?hu7!7e0VE)n@v0pqu}4pJc0J&S1Gv-otL9H@K+;#1Zf^Qb`nG{NAKRh z|0(}kfKdSI)fbX9TRZkbO5BYTyQ_T#*Pyw3f*MBemNRj zS;JM}0RSM(M)0>AC(8QE6a$$b`2Zi2$ew?k2YzC^z7t7TZtPxqKmr~~*X|;Lp$%0Z zNo&Vlt&^7{#RNn}B5wc`e!rzXHujCXaX&kYmm`<}Ondi@q011aLy#`pBn9{F4K#fV zY>~gUgX~(G(V$DW*iJSZPF71#zfM z+#6?UZ@r|7sB{3=kCO-%%um=*>GHw|bX_g@u)IlILffbRFYOqFB!TgDb0lqJhm#DT zgMNx^e?|GRkCVfiPV}QY{|KBYg90%7O>+DzI{3l`WIj*{jPe6FW|Z&b8i-BoC|O3% zCxAhS^`PL;jWxqs#JB!@6D(No*b7qeSU7Y0wxk5Cl@n~%2E$@C#mHC!qpe_BDUP`Z zQ>RUUIr~|z;D@|pNX4&?x3CjiT3$N|9c-DeH&7G9hY8?X&bRO@)(|SMaykmEsN}^V z5s(RxI!`>{sl8!?df~$H*fM7yvY*z0w@9&YT!WR5uI(#l=@P+*A?$>8h_`V7{$)ENJVM;{|g!xuwm) zHX(p;1Vw@8IZ?4O>y6XiteNW$Y+l&(xI-Ke+vCPK8w;$IRb+42sTjFQ-iI6^yAiPh z=LnlRH=`<2$!P=@~1E`KTWVL!^GIQDdn+5))6Q&1mMttKp;&bia>By zZVEd!4{^$kZ%L&8Jbvbh#c6o5u96)tkw@{0N{vI=4bZu-``RC76z>pp#uc zr(nKGCUHSs$9Jx(GGNt z(Lti7Xu49+I}9i1U9u)XbnGHzZ^8@WU^v1t4v?XloSq~lmq_08iAn$=%-4zhDz^)! z8Ilz@N*-7k#LPl+$N@A}s@x)Sd`dtGbF5Ow8twXK4j3I{Oa`esA!|p`tX_th8odmI zHLcM&Ais>~J+1{oG^_@<8miLIIC@X>F`BVQARRNgLVfRwn8dyvIS5aJ)#~u5$@Gq> ziP2Nk#NIC4fNZs3XV0BD4g?XDG8|aj1UJPSk@GoDx!?ssnCZ_lqF6}l?xT}_BnM;! z9@_$D6w4gjV814D5vqb)vM@u~V+eZ;VUHo~F@!yO4twB(!X6LhC|UOv^Qd#~xtIs4 zb&5JfJuDULmO6dxsE4BH@P{8e>R}>NHPm~Edep4nu{*8z5%+i?pOrJ_I{U3X`8W^j zDwbK$&0RbWCLH7ut=+YqT!2^LI}4y`otS4-#XjmFVO<{_q`^TN9HhZP z8XTnia*$BLL8|E2uiaF&)ps_Zlx8RXUBj3?g?1Hm458h=7N(m~H!MxRHs;(5z}V^< ze8>7TwJ~}2F&h)1!NweH%)!PSY|O#NJRuvC-|CN~w4^6psSNZN{DKF90Q-6k5kD$R%v7o zf%L)28JwKK$r+rS=UHi_D5rY6%A8_NAy>yAx6a5!nlU9dW#a;$d#N)rjHzWJbGTh~ zGF3+V2Hi8RHmYRBbE`Vay(Q-+^kAd!>L*#s^T`FJXSKY?y3|KPefmf^_mPy$N75%o z?jxyFeQ=Qm7wI&K9bBZrMS6lRl5x71F|amObzOOECkbojRBPp{-HVf?n7XMcZG5%i zGR6_RNqg4Zk>q;&s#$wbH>--3Lj~Y*_5HvI@6K|vcW0I4N1B7JMYaOPQZ#I8$Se|YI1bg)9smn32X$EX zxZUohW4P|6W1R@WDIvOP^gu|3SxsoDoc&#YuWvr^D?AyU6F)>my(+R2VZKobBr`&ELn{&0{^h}K5XJH0c8Nj`m zzE8>MeHP~K0k7?P%sg6E*rCPCeQI9oQyR2qRmtU+21qN$zVjO3ap_b|inF0gRU|ZP!U=nBG_G}{nJ-WqLMV8=Bx93C z)ipsX2=95j^}X?a5oNRPil~%R(VBD@I{h`>2`uZbTA~WjM%eT2rG!&E+RKTiM*V5h ztvbQfj(O!!MluPAl0iV{awf z`yDkbTH7bb9Zh}^)xU`_n<5Xe(xL}e^( z1N11r95W&B;$jhc4H>;f=$}$dcZkrR5}EBH^et|{3=#UL5uvZU@A833Ej(*XHI0^x_7R?~T!SG%+t?jqCLgitr@E%74_q^(DDeJvjV5O0V<|F)FM})M;bD8fr-@_SWWHFd zpXQOt|0Ni>_U#3Zk1;00yy~Vg87&VQ7>dB_ugQ{XMk!`c$}rb-r%zbD!|emTQjH~(@tt(;+QG=C$nY?`*HPN<+?!7VcURsD??^jFEQ z)q?(t^;g?eXJ}>qtF4qL3y0}hfr46kW=Tu*ZImxZZ|2=g@Zfz(p{u#Emr?a(X?3?D@A9!cu5+T)>++l+5fL zgumBa_#xY0N#yKhmV+r^`PU!6uRSN)ZI6lLvmAXzW#f#*3vP?>z9=fBbLVWpcewjhGRy zet!Me@!vtvmXY&m>-e8V6P$8+t!nN~$SWG;N~q$6xrwR@pvcykLn(%6Fx4o6VF8p@ zyzYrj(O^cA0Az{4%pw6u5kOfx0?=eC9IRNMGMOqurWHem6HCN3YEk51=2SRbAs9&D zL||Hx2vZXdrx&R(Maw|#ja?#ExTy5K(Sn3+5o}r{0;V94Bvd3q7mY@ZksM4Dj;0i8 z&@`d=7D>>sh*YKcLY0YXiolE_4XRK~6thSKOjQ786^RgzrWWg%CW;si7l}}Wny)HF zDzIpFs#+uh>%!qQi-Qwx5k)GnXvI{sNCZ}e!*Pm@MVhE`ij76PgvRML780Rxij9RE z9jDh=xDpzt*uv2`wH88gT8)Hzj>c(q4IHP|VmKW&p+Uz@XwVg_343)7HCiq1HA&*d z*Ey{ggK_?sUeq(f(?3TCED@#N@PE70%A&)LIqt*yPk&w6Z3r)|yD{Oir)0J)Q)Y|0b!b zVvW_^HYx7{E^jvOjT1>%ZtP}73)k)h3YW?WI8F;ilzyRf(Cr!~8TcGW| zyKr~K7*hVGPrkqeR~MM<3PAQMOaP9h=5q4Bd-I(%Ut?*WL>{?<)vyL-jEhAm`2LDe zc&mp<$sV_6a+#}XvWSq7$yO>)>DSjeh95!Xes-PfDnTPT&s@}~y#vB#k&~){xTUk6 zg|6)f1XmRXLn~mQXW$JnU8fYo6gNV!QzwuEQY>{Ro|F<*XOvLJH=!g7h+327jdw_J zjzlGI`pu9iDH4;M6u0Cp>h;Pw`|{V`v{>z8A(%;VCzmq=v5xF@?7aZ()HR+oH0qYI%nWQJLBuf4qr(B{bDB5p08#yLv|S~Zl(08fzlFijFjF(S$YOXa|S>LIRmNM*xn05Q<#stv7?pikCPxg z!%BGbB5Sw|5|9$U&2yH?87eeH6c23~e@e!epqU@XuD<|goB?h^eEt=HV9|hVznZ3V zdks>_lcemE1d<4&yeEQSdv2V#bLl*?{kbEbJM*<4$RFa{@lOFP)7te{(z_rCC%{%f z3S14JJmF+B1WA)FZ>1;*5=)c*WG8=yqh=e;oh1meGx43IK=4c^LPR8r2=Q;fk;Z~j zW^qzDrRk$5y%6PD?GW$IZ7+-yRzjKU_HN6KX%ip~{1tFm_BNY%oML(P#s2{*C8+U2 C1&MP2 diff --git a/data/projects/shorties/Skiessi-222.mmpz b/data/projects/shorties/Skiessi-222.mmpz index a5683364580a8351c71e27bfb67090dab78786e7..a7076949cf62b5e3a8869ce74a888a735da7f76f 100644 GIT binary patch literal 4747 zcmV;65_IhV0PGETob5f?a@#tx@8>IcbgS+>=t?BGGm$gpcuDNzMYd(J;Jt!%9D?jH?iSf#kI^{C0zs6cA)B6&R*s0{QM?dPM# z)#yXDLwTA3U9I=415L}&%m9_IP!G0&fEiSwp}HP)Y|U%;_bT!8(9-uRic*OyFb4*7 zB6Qks0Cx}nKtDZ4Z9law(^EAQI@C~ewFezh04mf->v(=~K{L)L>Wx1{!!FxTzYb=n!_*f$mi(*V3&dB0|+n*K-gx zrWaH)CEX{QL)__(!xCFH{r?|S7ctO7H49RO8n`gUHPmPSm!q0JpXh08srJIod5&i5 z&~n?Fu49g-zNKp5s`o6Ad`P|F z_9`qAs%Q5*&>MtA#g8EU7+@k{Ik-PvO~-vr7l3R5iwh9r7@u);N|5walBsg2cT`WM zx+CcMyyymMi4>*lKo@nQj+oGG571kQVVJDAp^n<4bl1iTTu1nAPlx7EH9Wuny4`_# zz^mwo{|W*2ExqIaa3^LPaR}xJ#?&Ak3Tko(E*_s@hxE7sw{M3(>`u;5_=Ty#PmPh? z@DUupKXrzyP#xF~x)!uW=V(OaFHd7FCX(4Okr9P;Y{h00iNw7;kxWb@?(t?t31T{D zklCOEZBLc8`JQ4&0(=|j&^ zjld#1niu0>|23@P%2wNFf@Rn)wurJ|s9qh@8Vf zIQSg{LRdT)kgDU+z-9;g6q?OLOTuh$t^iyXI7Oa~!WW?M3Ol-wraa|*DCB)7SYxRJl=mra2pRm#qWk}#1b@!}jHu0%zV3e~uI zBTgsoGcBxi5LW(2|^@Z*{DCzF~isf zNX9mhj@#Izi@7j|ZJ}~Wl#y~nq>7xJ7J36u6e-kOqz!Ty=Mb3?O$5_8hmW1{@d;!B zgvkD6JZO~7U;}O@`m}91#Fm8&wm7?OIoGx#X4__GqKi>{$M3M^dq$;n<06-99I#Bb zb$&KJo5$z*ReH}y=r|CSLYEfvecC!JaO+5&6?2_0A@&5ml|)Lz!G~*?C~7F6MIbT@$T5;0_t=2 zSlM24EMQ&{b4<)}4m+=zK+IXRIlY(i_)1RhC3>GQYG4W36&Xc7$Nky(#2pcLw1e(w z*Ovzh%MgD={Lvh~6MIbT@$T5;jV})xbSjqqhI<5AFn5oj!mYhW@Imu5bEtM;Zg=4H z4P{!6q3YU8;CbRbp#C-<&BSe6y6S0Ra>`W=TZcD&74w6AvU@}Aq}hMr?ymOFtJdk$ zWFXr=9Y>hZEtM9`{&=Wd9e1T_+vZf7?q68L(aqP^L-q3Vx=Ooj>tyH*j!w^n%L#j; z93I}BG>smV4*B!DF+dUkSg=ogee9dRQGvCl9hD-wf!#zxT#N?m$16s@B=d4gI}& zG8yte^)rXQAK(0-N7sxxe6fBWK2-nuKCD)+ubs!Cb#gX#q{*EKtA~?=<6(b%dnxhN zo~$bRKBo^R$0yG(%t5<#UVUy}o;07U*WRNj_Xhjb>eJI<6Fh!DK9tY($rU|3;3rMF zFEv~A&+*YcJ$UY1G!@IeZ7DzQ^dtJf6PisyY_}fev3ASQFJJAm=F7qP^`mmb-|o{# zKW?R_^wPR$q52MZdjH4hsY!q3j$dfz`Km|%?4FIA&hy_sLzd8>JSx^@x zzJLwuZsXhvp_h>PHg4w3ZFpF6Gbbq6%*m0>oW+|t*^-+%w{C08TAMk!?2w;AZ}(=- z*&QdFIbU@%=T>iLi}$h#@m4k*fe!Yv;k|CFZfD!TMkO34FCT^|znUyS2HC}=FcZ5d zAfF4Mp{8AZ>f^o52^SOaBXIK^_(thi} zNNl3q>5)O^ie#=x=8AdnEt@NHiY!an#J&$iCW~aUxFwTCz+qx{-zRS6Y_R}6r`c;x zHs{P1OO1>RdM6B~8n5{XMB zE|Ivzw|9wxA}fkqz!BmSiA&rTm*{Kt?z_aTjJ=Rd-3|v&1W6CdVE{-BClqe@CyOw$2-})P7(;v_@rlGI5})`Rd?L#OzzAel81aeQ z>=PySU3^uyl>rzMncU$B3JU;<*^`m+K1arqhhDj+>cC%W+Zwo@){f3!S^fkp;9o&G z=bB7@?IW<%K}WOj`2c9G(}u2_zbG>g5gvQxx8*>5B34MfZdrC@ExL|he{gZ3o_d1e z6aH4;Y424!s7Eec%rw=oL&>?`0Lui|o)-0z=MwP+H%9Uz`&!2mF}rlpAhq&&M7u{O zxi*qq8~M&p8e&o>4W%5~>zpuBY@>q}Y?SKT~S=_GqCqXa;aSS`y#niSm%9_Tq?Wsu1GEyqSykGmt1Z>Y3-+9ea-G$ z_8MzVX2Duh+Wxg>Vxc)}m07^6*I#0S=@QdF#M)nDa%6@1&dDSzOtQlKKr2kb3Z^SL}>R?u##@5KnS)(m_S_pk!9R}HxmX0PO6$dvwfF?;1O z^M_*gk}>YS)>pk>ZQXKVhv8NYa*N_eh;bM3>a~L0O#Xhi#6Bv(GYkoHzjHE4n45&T z-+7pOORsE`^VXHh-P#sj)&}yBRCqfY6J9&Ui@D)F1&S_26Xw7~_n~oM4iHzOqWB`T z*&xDV5OFbx6oM3gjp&2Oi)&G4*YXxOwt1@k3nIg^;;n5MJ-F%2ucfHZxlX;w?QL&+ zTVbg8g&*CfwAH@^R4M)*F{QEowR|O%w$Ad3JnsfWVG6kem;53B3)ykuhnS`G{DzM%Z^KwGtwY9_NclOOz`%-&Ff@S}2jGa14U%57psexG7*B*pkanZ215 zTCVl-V0fk$zNeZzf0jQMtXDBgJI3t|9X!D<_!tOtaoZE6b%w7b z51!yReeeVqB~0UVsYJ4+@19JOEhX8~cb+W;A0k^iH^~VWCk@#$SyygxJtSAU1G&;S z%z-(Y@hV@&<&Mr*bS!FQj``)*9!{&YyC>~~{nUj3f)wr~>-Vd21 z6GD+p$otQPfTEi#vzZX`-B=!kX- zl|$t_OYo{u=?XxaoK6KO`rBdOfi5m6M^alY$*TvU2|F7rZ+Oyd=&TdzynH}u(t9Q8t4cpo-(VzPfLOedv)OWiC9Cpo* zS-!Cp)8?f+Hqe?KF-3DVe?^WL$6Ckhqjjq&RH#1GdVPF<0=_tV92i<;=XeIaGt{wW zXfL7VL96HKQ``%G@qvQ~c&-id;{gD?)7TUQngQY z9(FVwu3Oj$vwS0H5aWB(vDbG?Hy|+qpBAv`OXJUf9UShr_W#xR^YHSZb>BRqzPHZL zsOIh0vy%g=Qlse~+yPA=whn_Ae4U}`ql*ev>3g32iKa)RQGLYKEvHAfuIcNegIeD+ zbe^HnnqO;s^^Vs;`q{vRUmAU=cD^(W=&7OJKO>mF2ghE;cQ?=sh7J7%De(k(onX#^ z0qC~tqKfSQqjZh>f9#YzSi?aS_zC-_+Q?Du&(weZXwW|9mj)d)_F#1;lwY)0p}MGz zT30nRee&rachKpmruvW1L9vUN@(BRj3!g_mOFxMW69M2#J|T57RQ)ri$&TwaRHvtz zHP5m?G4}X#^!#9XNI_CXI_!F>0>^K~FR49ywFlj5Kh-o7*$Y(qnZl&Uj|d2f3=wS> zQ*@)6E_DMPt(ziB$j{rjx{o=i8XMjQ0u5b?fS@|)DdS< z%ZRZy`it3$d5p#S?|xQmn~7Y9Zi8S!!1m Z2(@aNJ;ZHVHw?EHHuL3={{pKE-FCwDViW)X literal 4825 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 diff --git a/data/projects/shorties/Surrender-Main.mmpz b/data/projects/shorties/Surrender-Main.mmpz index a94df2497ef56987ee7b0a6e93a42bc43edc1a32..5565811708f410837b3146c81294bb11fc6b7dcc 100644 GIT binary patch delta 2325 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 delta 2392 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 literal 3906 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 Rbv-X0i&;)y{U1;NJZl}9VPOCO literal 3924 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 From 9eb6e3fa33346402520576ae815f5cbce5bd53a0 Mon Sep 17 00:00:00 2001 From: Hussam al-Homsi Date: Fri, 13 Sep 2019 14:03:26 -0400 Subject: [PATCH 384/445] Update .mailmap --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 71b6697c8..ce10c7d24 100644 --- a/.mailmap +++ b/.mailmap @@ -29,3 +29,4 @@ grejppi Johannes Lorenz Johannes Lorenz <1042576+JohannesLorenz@users.noreply.github.com> Noah Brecht +Hussam al-Homsi Hussam Eddin Alhomsi From b07c007a27d660fe576cb5c852e01db7560c9e73 Mon Sep 17 00:00:00 2001 From: Kevin Zander Date: Sat, 14 Sep 2019 11:57:44 -0500 Subject: [PATCH 385/445] Add save/load of PianoRoll marked semitones (#5146) --- include/PianoRoll.h | 1 + src/gui/editors/PianoRoll.cpp | 42 ++++++++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/include/PianoRoll.h b/include/PianoRoll.h index 4451a07c5..f56d791f4 100644 --- a/include/PianoRoll.h +++ b/include/PianoRoll.h @@ -95,6 +95,7 @@ public: void setCurrentPattern( Pattern* newPattern ); void setGhostPattern( Pattern* newPattern ); void loadGhostNotes( const QDomElement & de ); + void loadMarkedSemiTones(const QDomElement & de); inline void stopRecording() { diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 5edc5d47c..a1fcdc6d8 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -24,6 +24,8 @@ * */ +#include "PianoRoll.h" + #include #include #include @@ -46,7 +48,6 @@ #include "AutomationEditor.h" #include "ActionGroup.h" #include "ConfigManager.h" -#include "PianoRoll.h" #include "BBTrackContainer.h" #include "Clipboard.h" #include "ComboBox.h" @@ -655,6 +656,32 @@ void PianoRoll::clearGhostPattern() } +void PianoRoll::loadMarkedSemiTones(const QDomElement & de) +{ + // clear marked semitones to prevent leftover marks + m_markedSemiTones.clear(); + if (de.isElement()) + { + QDomNode node = de.firstChild(); + while (!node.isNull()) + { + bool ok; + int key = node.toElement().attribute( + QString("key"), QString("-1")).toInt(&ok, 10); + if (ok && key >= 0) + { + m_markedSemiTones.append(key); + } + node = node.nextSibling(); + } + } + // from markSemiTone, required otherwise marks will not show + std::sort(m_markedSemiTones.begin(), m_markedSemiTones.end(), std::greater()); + QList::iterator new_end = std::unique(m_markedSemiTones.begin(), m_markedSemiTones.end()); + m_markedSemiTones.erase(new_end, m_markedSemiTones.end()); +} + + void PianoRoll::setCurrentPattern( Pattern* newPattern ) { if( hasValidPattern() ) @@ -4697,6 +4724,18 @@ void PianoRollWindow::saveSettings( QDomDocument & doc, QDomElement & de ) de.appendChild( ghostNotesRoot ); } + if (m_editor->m_markedSemiTones.length() > 0) + { + QDomElement markedSemiTonesRoot = doc.createElement("markedSemiTones"); + for (int ix = 0; ix < m_editor->m_markedSemiTones.size(); ++ix) + { + QDomElement semiToneNode = doc.createElement("semiTone"); + semiToneNode.setAttribute("key", m_editor->m_markedSemiTones.at(ix)); + markedSemiTonesRoot.appendChild(semiToneNode); + } + de.appendChild(markedSemiTonesRoot); + } + MainWindow::saveWidgetState( this, de ); } @@ -4706,6 +4745,7 @@ void PianoRollWindow::saveSettings( QDomDocument & doc, QDomElement & de ) void PianoRollWindow::loadSettings( const QDomElement & de ) { m_editor->loadGhostNotes( de.firstChildElement("ghostnotes") ); + m_editor->loadMarkedSemiTones(de.firstChildElement("markedSemiTones")); MainWindow::restoreWidgetState( this, de ); } From 0059c6e71f6431b4ed13d8e444f133642bbe933d Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Sat, 14 Sep 2019 20:35:54 +0300 Subject: [PATCH 386/445] Fix #4188 - Check for failed qFind (#5184) --- src/gui/editors/PianoRoll.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index b65a6b56b..7ba01f983 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -537,7 +537,10 @@ void PianoRoll::markSemiTone( int i ) for (int ix = 0; ix < aok.size(); ++ix) { i = qFind(m_markedSemiTones.begin(), m_markedSemiTones.end(), aok.at(ix)); - m_markedSemiTones.erase(i); + if (i != m_markedSemiTones.end()) + { + m_markedSemiTones.erase(i); + } } } else From 8fdf6c4d120430194ee9c4303b6d8a7bcad99c32 Mon Sep 17 00:00:00 2001 From: Kevin Zander Date: Sat, 14 Sep 2019 12:36:06 -0500 Subject: [PATCH 387/445] Fix #4188 - Check for failed std::find (#5137) --- src/gui/editors/PianoRoll.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index a1fcdc6d8..36505e982 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -550,7 +550,10 @@ void PianoRoll::markSemiTone( int i ) for (int ix = 0; ix < aok.size(); ++ix) { i = std::find(m_markedSemiTones.begin(), m_markedSemiTones.end(), aok.at(ix)); - m_markedSemiTones.erase(i); + if (i != m_markedSemiTones.end()) + { + m_markedSemiTones.erase(i); + } } } else From ffa03df72bae81aa886f444e90204246e854cbb1 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Sun, 15 Sep 2019 10:18:47 -0400 Subject: [PATCH 388/445] Fix $PATH value in AppImage Closes #5187 --- 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 0dec715f4..b838237b7 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -103,7 +103,7 @@ mv "${APPDIR}usr/bin/lmms" "${APPDIR}usr/bin/lmms.real" cat >"${APPDIR}usr/bin/lmms" < /dev/null 2>&1; then CARLAPATH="\$(which carla)" CARLAPREFIX="\${CARLAPATH%/bin*}" From 419321dd0146d9893f7934ef852cb54994ffd26f Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Mon, 16 Sep 2019 07:09:42 +0200 Subject: [PATCH 389/445] Only MacOS and Windows are case insensitive (#4768) --- src/core/Song.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 943524e6d..6bd94a484 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -1414,7 +1414,12 @@ void Song::exportProject( bool multiExport ) // Get first extension from selected dropdown. // i.e. ".wav" from "WAV-File (*.wav), Dummy-File (*.dum)" suffix = efd.selectedNameFilter().mid( stx + 2, etx - stx - 2 ).split( " " )[0].trimmed(); - exportFileName.remove( "." + suffix, Qt::CaseInsensitive ); + + Qt::CaseSensitivity cs = Qt::CaseSensitive; +#if defined(LMMS_BUILD_APPLE) || defined(LMMS_BUILD_WIN32) + cs = Qt::CaseInsensitive; +#endif + exportFileName.remove( "." + suffix, cs ); if ( efd.selectedFiles()[0].endsWith( suffix ) ) { if( VersionedSaveDialog::fileExistsQuery( exportFileName + suffix, From 90dec52db00b20ec986748da571a72df5145a200 Mon Sep 17 00:00:00 2001 From: Hussam al-Homsi Date: Thu, 19 Sep 2019 12:02:11 -0400 Subject: [PATCH 390/445] Add missing icons of File menu actions (#5183) --- src/gui/MainWindow.cpp | 7 ++++--- src/gui/menus/TemplatesMenu.cpp | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index bdb3a7472..08bc90852 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -291,7 +291,7 @@ void MainWindow::finalize() tr( "&Save" ), this, SLOT( saveProject() ), QKeySequence::Save ); - project_menu->addAction( embed::getIconPixmap( "project_saveas" ), + project_menu->addAction( embed::getIconPixmap( "project_save" ), tr( "Save &As..." ), this, SLOT( saveProjectAs() ), Qt::CTRL + Qt::SHIFT + Qt::Key_S ); @@ -300,8 +300,9 @@ void MainWindow::finalize() this, SLOT( saveProjectAsNewVersion() ), Qt::CTRL + Qt::ALT + Qt::Key_S ); - project_menu->addAction( tr( "Save as default template" ), - this, SLOT( saveProjectAsDefaultTemplate() ) ); + project_menu->addAction( embed::getIconPixmap( "project_save" ), + tr( "Save as default template" ), + this, SLOT( saveProjectAsDefaultTemplate() ) ); project_menu->addSeparator(); project_menu->addAction( embed::getIconPixmap( "project_import" ), diff --git a/src/gui/menus/TemplatesMenu.cpp b/src/gui/menus/TemplatesMenu.cpp index 5fb740203..b944b7cf1 100644 --- a/src/gui/menus/TemplatesMenu.cpp +++ b/src/gui/menus/TemplatesMenu.cpp @@ -11,6 +11,8 @@ TemplatesMenu::TemplatesMenu(QWidget *parent) : QMenu(tr("New from template"), parent) { + setIcon(embed::getIconPixmap("project_new")); + connect( this, SIGNAL( aboutToShow() ), SLOT( fillTemplatesMenu() ) ); connect( this, SIGNAL( triggered( QAction * ) ), SLOT( createNewProjectFromTemplate( QAction * ) ) ); From 1324cf48c16a91898a8cdec8af43f0f0ce41bc82 Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Mon, 12 Aug 2019 12:35:12 +0300 Subject: [PATCH 391/445] Enable automatic dll installation for RemoteVstPlugin32 Co-Authored-By: Hyunjin Song --- plugins/vst_base/CMakeLists.txt | 30 +++++++++----- .../vst_base/RemoteVstPlugin/CMakeLists.txt | 15 +++++++ plugins/vst_base/RemoteVstPlugin32.cmake | 40 +++++++++---------- plugins/vst_base/RemoteVstPlugin64.cmake | 1 - 4 files changed, 54 insertions(+), 32 deletions(-) diff --git a/plugins/vst_base/CMakeLists.txt b/plugins/vst_base/CMakeLists.txt index 44ed0dcb3..873ed5f8e 100644 --- a/plugins/vst_base/CMakeLists.txt +++ b/plugins/vst_base/CMakeLists.txt @@ -11,23 +11,35 @@ SET(REMOTE_VST_PLUGIN_FILEPATH_64 "RemoteVstPlugin64" CACHE STRING "Relative fil ADD_SUBDIRECTORY(vstbase) -SET(LMMS_BINARY_DIR ${CMAKE_BINARY_DIR}) -SET(LMMS_SOURCE_DIR ${CMAKE_SOURCE_DIR}) - SET(EXTERNALPROJECT_ARGS SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin" - INSTALL_COMMAND "" + #INSTALL_COMMAND "" BUILD_ALWAYS ON + # Skip the install step. + INSTALL_COMMAND "" ) +set(export_variables + "LMMS_SOURCE_DIR" + "LMMS_BINARY_DIR" + "CMAKE_MODULE_PATH" + "CMAKE_RUNTIME_OUTPUT_DIRECTORY" + "CMAKE_BUILD_TYPE" + "LMMS_BUILD_LINUX" + "LMMS_BUILD_WIN32" + "PLUGIN_DIR") + SET(EXTERNALPROJECT_CMAKE_ARGS - "-DLMMS_SOURCE_DIR=${CMAKE_SOURCE_DIR}" - "-DLMMS_BINARY_DIR=${CMAKE_BINARY_DIR}" - "-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" - "-DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}" - "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" + "-DBUILD_WITH_EXTERNALPROJECT=ON" ) +macro(_export_var_to_external var_name) + list(APPEND EXTERNALPROJECT_CMAKE_ARGS "-D${var_name}=${${var_name}}") +endmacro() +foreach(var ${export_variables}) + _export_var_to_external(${var}) +endforeach() + # build 32 bit version of RemoteVstPlugin IF(WANT_VST_32) INCLUDE("${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin32.cmake") diff --git a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt index 59dd19a0a..f4023fd42 100644 --- a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt +++ b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt @@ -76,3 +76,18 @@ endif() IF(STRIP) ADD_CUSTOM_COMMAND(TARGET ${EXE_NAME} POST_BUILD COMMAND "${STRIP}" "$") ENDIF() + +if(BITNESS EQUAL 32) + INSTALL(TARGETS ${EXE_NAME} RUNTIME DESTINATION "${PLUGIN_DIR}/32") +else() + INSTALL(TARGETS ${EXE_NAME} RUNTIME DESTINATION "${PLUGIN_DIR}") +endif() + +if(BUILD_WITH_EXTERNALPROJECT) + include(InstallTargetDependencies) + INSTALL_TARGET_DEPENDENCIES(TARGETS ${EXE_NAME} + DESTINATION "${PLUGIN_DIR}/32") +else() + # Needed to deploy dependencies of RemoteVstPlugin + SET_PROPERTY(GLOBAL APPEND PROPERTY PLUGINS_BUILT "${EXE_NAME}") +endif() diff --git a/plugins/vst_base/RemoteVstPlugin32.cmake b/plugins/vst_base/RemoteVstPlugin32.cmake index 9a8f04529..efbd00ee9 100644 --- a/plugins/vst_base/RemoteVstPlugin32.cmake +++ b/plugins/vst_base/RemoteVstPlugin32.cmake @@ -1,14 +1,21 @@ +# INSTALL_EXTERNAL_PROJECT: install a project created with ExternalProject_Add in the +# parent project's install time. +# +# Description: +# In a regular scenario, cmake will install external projects +# BEFORE actually building the parent project. Since the building +# process may use installed components from the project. +# We want to give the external project the ability to install +# files directly to the parent's install. Therefore, we have to +# manually trigger the install stage with the parent's INSTALL_PREFIX. +MACRO(INSTALL_EXTERNAL_PROJECT name) + ExternalProject_Get_Property(${name} BINARY_DIR) + + install(CODE "include(\"${BINARY_DIR}/cmake_install.cmake\")") +ENDMACRO() + 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}/../32/RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32") ELSEIF(LMMS_BUILD_WIN64 AND MSVC) SET(MSVC_VER ${CMAKE_CXX_COMPILER_VERSION}) @@ -46,16 +53,7 @@ ELSEIF(LMMS_BUILD_WIN64 AND MSVC) "-DCMAKE_PREFIX_PATH=${QT_32_PREFIX}" ) - 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") - - 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") - + INSTALL_EXTERNAL_PROJECT(RemoteVstPlugin32) ELSEIF(LMMS_BUILD_LINUX) # Use winegcc INCLUDE(CheckWineGcc) @@ -82,9 +80,7 @@ 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}/../32/RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32") + INSTALL_EXTERNAL_PROJECT(RemoteVstPlugin32) ELSE() MESSAGE(WARNING "Can't build RemoteVstPlugin32, unknown environment. Please supply CMAKE_TOOLCHAIN_FILE_32 and optionally CMAKE_PREFIX_PATH_32") RETURN() diff --git a/plugins/vst_base/RemoteVstPlugin64.cmake b/plugins/vst_base/RemoteVstPlugin64.cmake index 4b02bf8ab..65b33a162 100644 --- a/plugins/vst_base/RemoteVstPlugin64.cmake +++ b/plugins/vst_base/RemoteVstPlugin64.cmake @@ -1,6 +1,5 @@ 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) From ae9d619abd0410e642c50f48a2095c4fcb82ee7a Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Wed, 21 Aug 2019 21:32:39 +0300 Subject: [PATCH 392/445] BuildPlugin: Always remove 'lib' suffix from the DLL name --- cmake/modules/BuildPlugin.cmake | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmake/modules/BuildPlugin.cmake b/cmake/modules/BuildPlugin.cmake index e285e05bb..675433e63 100644 --- a/cmake/modules/BuildPlugin.cmake +++ b/cmake/modules/BuildPlugin.cmake @@ -75,9 +75,11 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) ENDIF() ADD_DEPENDENCIES(${PLUGIN_NAME} lmms) ENDIF(LMMS_BUILD_APPLE) - IF(LMMS_BUILD_WIN32 AND STRIP) + IF(LMMS_BUILD_WIN32) + IF(STRIP) + ADD_CUSTOM_COMMAND(TARGET ${PLUGIN_NAME} POST_BUILD COMMAND ${STRIP} "$") + ENDIF() SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES PREFIX "") - ADD_CUSTOM_COMMAND(TARGET ${PLUGIN_NAME} POST_BUILD COMMAND ${STRIP} "$") ENDIF() SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${RCC_OUT} ${plugin_MOC_out}") From 2f64c461e8dcf4d5ac185a763a500cbdd0aec4bf Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Sat, 24 Aug 2019 11:13:49 +0900 Subject: [PATCH 393/445] Fix missing system libraries in MSVC installations * Install UCRT libraries * Install debug libraries in debug builds --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 36e35bf4c..a08a9c8f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -709,4 +709,9 @@ MESSAGE( "\n\n") SET(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION "${BIN_DIR}") +if(MSVC) + # We can't set this on the install time according to the configuration + SET(CMAKE_INSTALL_DEBUG_LIBRARIES TRUE) + SET(CMAKE_INSTALL_UCRT_LIBRARIES TRUE) +endif() INCLUDE(InstallRequiredSystemLibraries) From 94354e305342d894332b9ac919dd9252b39c9422 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Sat, 31 Aug 2019 09:14:36 +0900 Subject: [PATCH 394/445] Support deploying dependencies in MSVC builds with CMake < 3.14 --- cmake/modules/CreateTempFile.cmake | 7 +++++-- cmake/modules/DefineInstallVar.cmake | 13 +++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/cmake/modules/CreateTempFile.cmake b/cmake/modules/CreateTempFile.cmake index ceefa4928..5210342ac 100644 --- a/cmake/modules/CreateTempFile.cmake +++ b/cmake/modules/CreateTempFile.cmake @@ -1,5 +1,5 @@ function(CreateTempFilePath) - set(options) + set(options CONFIG_SUFFIX) set(oneValueArgs OUTPUT_VAR TAG) set(multiValueArgs CONTENT) cmake_parse_arguments(TEMP "${options}" "${oneValueArgs}" @@ -10,9 +10,12 @@ function(CreateTempFilePath) string(SHA1 hashed_content "${TEMP_CONTENT}") set(file_name "${CMAKE_BINARY_DIR}/${TEMP_TAG}_${hashed_content}") + set(${TEMP_OUTPUT_VAR} "${file_name}" PARENT_SCOPE) + if(CONFIG_SUFFIX) + set(file_name "${file_name}_$") + endif() file(GENERATE OUTPUT "${file_name}" CONTENT "${TEMP_CONTENT}") - set(${TEMP_OUTPUT_VAR} "${file_name}" PARENT_SCOPE) endfunction() diff --git a/cmake/modules/DefineInstallVar.cmake b/cmake/modules/DefineInstallVar.cmake index 36f221410..b13cb1d52 100644 --- a/cmake/modules/DefineInstallVar.cmake +++ b/cmake/modules/DefineInstallVar.cmake @@ -14,13 +14,14 @@ function(DEFINE_INSTALL_VAR) # install(CODE) does not support generator expression in ver<3.14 if(VAR_GENERATOR_EXPRESSION AND ${CMAKE_VERSION} VERSION_LESS "3.14.0") - if(MSVC) - message(FATAL_ERROR "Installing is not supported with msvc and cmake<3.14") - endif() - include(CreateTempFile) - CreateTempFilePath(OUTPUT_VAR file_path TAG "${VAR_NAME}" CONTENT "${VAR_CONTENT}") - install(CODE "file(READ \"${file_path}\" \"${VAR_NAME}\")") + if(CMAKE_CONFIGURATION_TYPES) # in case of multi-config generators like MSVC generators + CreateTempFilePath(OUTPUT_VAR file_path TAG "${VAR_NAME}" CONTENT "${VAR_CONTENT}" CONFIG_SUFFIX) + install(CODE "file(READ \"${file_path}_\${CMAKE_INSTALL_CONFIG_NAME}\" \"${VAR_NAME}\")") + else() + CreateTempFilePath(OUTPUT_VAR file_path TAG "${VAR_NAME}" CONTENT "${VAR_CONTENT}") + install(CODE "file(READ \"${file_path}\" \"${VAR_NAME}\")") + endif() else() if(VAR_GENERATOR_EXPRESSION) cmake_policy(SET CMP0087 NEW) From 867639929ac882c867e87aa6e06101912638861b Mon Sep 17 00:00:00 2001 From: Kevin Zander Date: Mon, 30 Sep 2019 21:36:45 -0500 Subject: [PATCH 395/445] Add close button to SideBarWidget (#5133) --- include/SideBarWidget.h | 5 +++++ src/gui/widgets/SideBar.cpp | 3 +++ src/gui/widgets/SideBarWidget.cpp | 13 +++++++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/SideBarWidget.h b/include/SideBarWidget.h index 229f07df0..37acc9770 100644 --- a/include/SideBarWidget.h +++ b/include/SideBarWidget.h @@ -28,6 +28,7 @@ #include #include #include +#include class SideBarWidget : public QWidget @@ -47,6 +48,8 @@ public: return m_title; } +signals: + void closeButtonClicked(); protected: virtual void paintEvent( QPaintEvent * _pe ); @@ -75,6 +78,8 @@ private: QVBoxLayout * m_layout; QString m_title; QPixmap m_icon; + QPushButton * m_closeBtn; + const QSize m_buttonSize; } ; diff --git a/src/gui/widgets/SideBar.cpp b/src/gui/widgets/SideBar.cpp index 01ea58919..cc83abae4 100644 --- a/src/gui/widgets/SideBar.cpp +++ b/src/gui/widgets/SideBar.cpp @@ -121,6 +121,9 @@ void SideBar::appendTab( SideBarWidget *widget ) widget->setMinimumWidth( 200 ); ToolTip::add( button, widget->title() ); + + connect(widget, &SideBarWidget::closeButtonClicked, + [=]() { button->click(); }); } diff --git a/src/gui/widgets/SideBarWidget.cpp b/src/gui/widgets/SideBarWidget.cpp index c1b46cfa6..41647a4fd 100644 --- a/src/gui/widgets/SideBarWidget.cpp +++ b/src/gui/widgets/SideBarWidget.cpp @@ -22,23 +22,31 @@ * */ +#include "SideBarWidget.h" + #include #include #include -#include "SideBarWidget.h" +#include "embed.h" SideBarWidget::SideBarWidget( const QString & _title, const QPixmap & _icon, QWidget * _parent ) : QWidget( _parent ), m_title( _title ), - m_icon( _icon ) + m_icon(_icon), + m_buttonSize(17, 17) { m_contents = new QWidget( this ); m_layout = new QVBoxLayout( m_contents ); m_layout->setSpacing( 5 ); m_layout->setMargin( 0 ); + m_closeBtn = new QPushButton(embed::getIconPixmap("close"), QString(), this); + m_closeBtn->resize(m_buttonSize); + m_closeBtn->setToolTip(tr("Close")); + connect(m_closeBtn, &QPushButton::clicked, + [=]() { this->closeButtonClicked(); }); } @@ -80,6 +88,7 @@ void SideBarWidget::resizeEvent( QResizeEvent * ) const int MARGIN = 6; m_contents->setGeometry( MARGIN, 40 + MARGIN, width() - MARGIN * 2, height() - MARGIN * 2 - 40 ); + m_closeBtn->move(m_contents->geometry().width() - MARGIN - 5, 5); } From 5132d91bfc7fa05d2fa559c7a96399efa0ae89b6 Mon Sep 17 00:00:00 2001 From: "https://gitlab.com/users/CYBERDEViLNL" <1148379+CYBERDEViLNL@users.noreply.github.com> Date: Wed, 2 Oct 2019 01:00:11 +0200 Subject: [PATCH 396/445] Give focus to AutomationEditor when the window gets the foucs (#5170) This will make shortcuts work on opening the editor. --- include/AutomationEditor.h | 3 +++ src/gui/editors/AutomationEditor.cpp | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h index 9705c5efa..968bb34be 100644 --- a/include/AutomationEditor.h +++ b/include/AutomationEditor.h @@ -297,6 +297,9 @@ public slots: signals: void currentPatternChanged(); +protected: + virtual void focusInEvent(QFocusEvent * event); + protected slots: void play(); void stop(); diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 94e9d5cc8..7583501c7 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -198,6 +198,8 @@ AutomationEditor::AutomationEditor() : setCurrentPattern( NULL ); setMouseTracking( true ); + setFocusPolicy( Qt::StrongFocus ); + setFocus(); } @@ -2516,6 +2518,11 @@ void AutomationEditorWindow::clearCurrentPattern() setCurrentPattern(nullptr); } +void AutomationEditorWindow::focusInEvent(QFocusEvent * event) +{ + m_editor->setFocus( event->reason() ); +} + void AutomationEditorWindow::play() { m_editor->play(); From ca8871455e97bee0274e1c6c4081a0fe82dfeb72 Mon Sep 17 00:00:00 2001 From: "https://gitlab.com/users/CYBERDEViLNL" <1148379+CYBERDEViLNL@users.noreply.github.com> Date: Wed, 2 Oct 2019 01:00:59 +0200 Subject: [PATCH 397/445] Make undo for PianoRoll cut action possible (#5214) --- 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 36505e982..065234aa4 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -4095,6 +4095,8 @@ void PianoRoll::cutSelectedNotes() if( ! selected_notes.empty() ) { + m_pattern->addJournalCheckPoint(); + copyToClipboard( selected_notes ); Engine::getSong()->setModified(); From 9f0baab93ae18f88c07dff76a0563f73200b649f Mon Sep 17 00:00:00 2001 From: Hussam al-Homsi Date: Tue, 1 Oct 2019 21:14:55 -0400 Subject: [PATCH 398/445] Fix regression of some default settings The regression was introduced in #3820. --- src/gui/SetupDialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/SetupDialog.cpp b/src/gui/SetupDialog.cpp index f23b5b271..885f43dec 100644 --- a/src/gui/SetupDialog.cpp +++ b/src/gui/SetupDialog.cpp @@ -125,9 +125,9 @@ SetupDialog::SetupDialog(ConfigTabs tab_to_open) : m_vstAlwaysOnTop(ConfigManager::inst()->value( "ui", "vstalwaysontop").toInt()), m_syncVSTPlugins(ConfigManager::inst()->value( - "ui", "syncvstplugins").toInt()), + "ui", "syncvstplugins", "1").toInt()), m_disableAutoQuit(ConfigManager::inst()->value( - "ui", "disableautoquit").toInt()), + "ui", "disableautoquit", "1").toInt()), m_NaNHandler(ConfigManager::inst()->value( "app", "nanhandler", "1").toInt()), m_hqAudioDev(ConfigManager::inst()->value( From 15fe551b1da9863db6b127665dd390473615513d Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Thu, 3 Oct 2019 11:47:49 -0400 Subject: [PATCH 399/445] Submodules: Only fetch required (#5182, closes #5105) + Non-shallow fallback (hotfix) * Retry updating submodules non-shallow if shallow clone fails (master hotfix) * Add `PLUGIN_LIST` support to CheckSubmodules (#5105) * Remove `SKIP_SUBMODULES` switch (it's redundant to specifying `PLUGIN_LIST`) * Add `NO_SHALLOW_CLONE` switch --- CMakeLists.txt | 1 + cmake/modules/CheckSubmodules.cmake | 129 ++++++++++++++++++---------- cmake/modules/PluginList.cmake | 104 ++++++++++++++++++++++ plugins/CMakeLists.txt | 84 +----------------- 4 files changed, 188 insertions(+), 130 deletions(-) create mode 100644 cmake/modules/PluginList.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index a08a9c8f7..b63900dda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ IF(COMMAND CMAKE_POLICY) CMAKE_POLICY(SET CMP0057 NEW) ENDIF(COMMAND CMAKE_POLICY) +INCLUDE(PluginList) INCLUDE(CheckSubmodules) INCLUDE(AddFileDependencies) INCLUDE(CheckIncludeFiles) diff --git a/cmake/modules/CheckSubmodules.cmake b/cmake/modules/CheckSubmodules.cmake index 65e5be08b..d2475826b 100644 --- a/cmake/modules/CheckSubmodules.cmake +++ b/cmake/modules/CheckSubmodules.cmake @@ -7,12 +7,12 @@ # INCLUDE(CheckSubmodules) # # Options: -# SET(SKIP_SUBMODULES "foo;bar") +# SET(PLUGIN_LIST "zynaddsubfx;...") # skips submodules for plugins not explicitely listed # # Or via command line: -# cmake -DSKIP_SUBMODULES=foo;bar +# cmake -PLUGIN_LIST=foo;bar # -# Copyright (c) 2017, Tres Finocchiaro, +# Copyright (c) 2019, Tres Finocchiaro, # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. @@ -20,13 +20,15 @@ # Files which confirm a successful clone SET(VALID_CRUMBS "CMakeLists.txt;Makefile;Makefile.in;Makefile.am;configure.ac;configure.py;autogen.sh;.gitignore;LICENSE;Home.md") +OPTION(NO_SHALLOW_CLONE "Disable shallow cloning of submodules" OFF) + # Try and use the specified shallow clone on submodules, if supported SET(DEPTH_VALUE 100) # Number of times git commands will retry before failing SET(MAX_ATTEMPTS 2) -MESSAGE("\nValidating submodules...") +MESSAGE("\nChecking submodules...") IF(NOT EXISTS "${CMAKE_SOURCE_DIR}/.gitmodules") MESSAGE("Skipping the check because .gitmodules not detected." "Please make sure you have all submodules in the source tree!" @@ -41,74 +43,110 @@ SET(LANG_BACKUP "$ENV{LANG}") SET(ENV{LC_ALL} "C") SET(ENV{LANG} "en_US") -# Assume alpha-numeric paths -STRING(REGEX MATCHALL "path = [-0-9A-Za-z/]+" SUBMODULE_LIST ${SUBMODULE_DATA}) -STRING(REGEX MATCHALL "url = [.:%-0-9A-Za-z/]+" SUBMODULE_URL_LIST ${SUBMODULE_DATA}) +# Submodule list pairs, unparsed (WARNING: Assumes alpha-numeric paths) +STRING(REGEX MATCHALL "path = [-0-9A-Za-z/]+" SUBMODULE_LIST_RAW ${SUBMODULE_DATA}) +STRING(REGEX MATCHALL "url = [.:%-0-9A-Za-z/]+" SUBMODULE_URL_RAW ${SUBMODULE_DATA}) -FOREACH(_part ${SUBMODULE_LIST}) - STRING(REPLACE "path = " "" SUBMODULE_PATH ${_part}) +# Submodule list pairs, parsed +SET(SUBMODULE_LIST "") +SET(SUBMODULE_URL "") - LIST(FIND SUBMODULE_LIST ${_part} SUBMODULE_INDEX) - LIST(GET SUBMODULE_URL_LIST ${SUBMODULE_INDEX} _url) - STRING(REPLACE "url = " "" SUBMODULE_URL ${_url}) +FOREACH(_path ${SUBMODULE_LIST_RAW}) + # Parse SUBMODULE_PATH + STRING(REPLACE "path = " "" SUBMODULE_PATH "${_path}") + + # Grab index for matching SUBMODULE_URL + LIST(FIND SUBMODULE_LIST_RAW "${_path}" SUBMODULE_INDEX) + LIST(GET SUBMODULE_URL_RAW ${SUBMODULE_INDEX} _url) + + # Parse SUBMODULE_URL + STRING(REPLACE "url = " "" SUBMODULE_URL "${_url}") - # Remove submodules from validation as specified in -DSKIP_SUBMODULES=foo;bar SET(SKIP false) + + # Loop over skipped plugins, add to SKIP_SUBMODULES (e.g. -DPLUGIN_LIST=foo;bar) + IF(${SUBMODULE_PATH} MATCHES "^plugins/") + SET(REMOVE_PLUGIN true) + FOREACH(_plugin ${PLUGIN_LIST}) + IF(_plugin STREQUAL "") + CONTINUE() + ENDIF() + IF(${SUBMODULE_PATH} MATCHES "${_plugin}") + SET(REMOVE_PLUGIN false) + ENDIF() + ENDFOREACH() + + IF(REMOVE_PLUGIN) + LIST(APPEND SKIP_SUBMODULES "${SUBMODULE_PATH}") + ENDIF() + ENDIF() + + # Finally, loop and mark "SKIP" on match IF(SKIP_SUBMODULES) FOREACH(_skip ${SKIP_SUBMODULES}) - IF(${SUBMODULE_PATH} MATCHES ${_skip}) - MESSAGE("-- Skipping ${SUBMODULE_PATH} matches \"${_skip}\"") + IF("${SUBMODULE_PATH}" MATCHES "${_skip}") + MESSAGE("-- Skipping ${SUBMODULE_PATH} matches \"${_skip}\" (absent in PLUGIN_LIST)") SET(SKIP true) + BREAK() ENDIF() ENDFOREACH() ENDIF() - IF(NOT SKIP) - LIST(INSERT SUBMODULE_LIST ${SUBMODULE_INDEX} ${SUBMODULE_PATH}) - LIST(INSERT SUBMODULE_URL_LIST ${SUBMODULE_INDEX} ${SUBMODULE_URL}) - ENDIF() - LIST(REMOVE_ITEM SUBMODULE_LIST ${_part}) - LIST(REMOVE_ITEM SUBMODULE_URL_LIST ${_url}) -ENDFOREACH() + IF(NOT SKIP) + LIST(APPEND SUBMODULE_LIST "${SUBMODULE_PATH}") + LIST(APPEND SUBMODULE_URL "${SUBMODULE_URL}") + ENDIF() +ENDFOREACH() # Once called, status is stored in GIT_RESULT respectively. # Note: Git likes to write to stderr. Don't assume stderr is error; Check GIT_RESULT instead. -MACRO(GIT_SUBMODULE SUBMODULE_PATH FORCE_DEINIT FORCE_REMOTE) +MACRO(GIT_SUBMODULE SUBMODULE_PATH FORCE_DEINIT FORCE_REMOTE FULL_CLONE) FIND_PACKAGE(Git REQUIRED) # Handle missing commits SET(FORCE_REMOTE_FLAG "${FORCE_REMOTE}") + SET(FULL_CLONE_FLAG "${FULL_CLONE}") IF(FORCE_REMOTE_FLAG) MESSAGE("-- Adding remote submodulefix to ${SUBMODULE_PATH}") EXECUTE_PROCESS( - COMMAND ${GIT_EXECUTABLE} remote rm submodulefix - COMMAND ${GIT_EXECUTABLE} remote add submodulefix ${FORCE_REMOTE} - COMMAND ${GIT_EXECUTABLE} fetch submodulefix - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/${SUBMODULE_PATH} + COMMAND "${GIT_EXECUTABLE}" remote rm submodulefix + COMMAND "${GIT_EXECUTABLE}" remote add submodulefix ${FORCE_REMOTE} + COMMAND "${GIT_EXECUTABLE}" fetch submodulefix + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/${SUBMODULE_PATH}" OUTPUT_QUIET ERROR_QUIET ) # Recurse - GIT_SUBMODULE(${SUBMODULE_PATH} false false) + GIT_SUBMODULE(${SUBMODULE_PATH} false false ${FULL_CLONE_FLAG}) ELSEIF(${FORCE_DEINIT}) MESSAGE("-- Resetting ${SUBMODULE_PATH}") EXECUTE_PROCESS( - COMMAND ${GIT_EXECUTABLE} submodule deinit -f ${CMAKE_SOURCE_DIR}/${SUBMODULE_PATH} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMAND "${GIT_EXECUTABLE}" submodule deinit -f "${CMAKE_SOURCE_DIR}/${SUBMODULE_PATH}" + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" OUTPUT_QUIET ) # Recurse - GIT_SUBMODULE(${SUBMODULE_PATH} false false) + GIT_SUBMODULE(${SUBMODULE_PATH} false false ${FULL_CLONE_FLAG}) ELSE() # Try to use the depth switch - SET(DEPTH_CMD "") + IF(NO_SHALLOW_CLONE OR GIT_VERSION_STRING VERSION_LESS "1.8.4") + # Shallow submodules were introduced in 1.8.4 MESSAGE("-- Fetching ${SUBMODULE_PATH}") - IF(DEPTH_VALUE) - SET(DEPTH_CMD "--depth" ) + SET(DEPTH_CMD "") + SET(DEPTH_VAL "") + ELSEIF(FULL_CLONE_FLAG) + # Depth doesn't revert easily... It should be "--no-recommend-shallow" + # but it's ignored by nested submodules, use the highest value instead. + MESSAGE("-- Fetching ${SUBMODULE_PATH}") + SET(DEPTH_CMD "--depth") + SET(DEPTH_VAL "2147483647") + ELSE() MESSAGE("-- Fetching ${SUBMODULE_PATH} @ --depth ${DEPTH_VALUE}") + SET(DEPTH_CMD "--depth") + SET(DEPTH_VAL "${DEPTH_VALUE}") ENDIF() EXECUTE_PROCESS( - COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive ${DEPTH_CMD} ${DEPTH_VALUE} ${CMAKE_SOURCE_DIR}/${SUBMODULE_PATH} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMAND "${GIT_EXECUTABLE}" submodule update --init --recursive ${DEPTH_CMD} ${DEPTH_VAL} "${CMAKE_SOURCE_DIR}/${SUBMODULE_PATH}" + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" RESULT_VARIABLE GIT_RESULT OUTPUT_VARIABLE GIT_STDOUT ERROR_VARIABLE GIT_STDERR @@ -124,7 +162,7 @@ SET(RETRY_PHRASES "Failed to recurse;cannot create directory;already exists;${MI # Attempt to do lazy clone FOREACH(_submodule ${SUBMODULE_LIST}) - STRING(REPLACE "/" ";" PATH_PARTS ${_submodule}) + STRING(REPLACE "/" ";" PATH_PARTS "${_submodule}") LIST(REVERSE PATH_PARTS) LIST(GET PATH_PARTS 0 SUBMODULE_NAME) @@ -138,7 +176,7 @@ FOREACH(_submodule ${SUBMODULE_LIST}) ENDIF() ENDFOREACH() IF(NOT CRUMB_FOUND) - GIT_SUBMODULE(${_submodule} false false) + GIT_SUBMODULE("${_submodule}" false false false) SET(COUNTED 0) SET(COUNTING "") @@ -154,25 +192,22 @@ FOREACH(_submodule ${SUBMODULE_LIST}) ENDIF() ENDFOREACH() FOREACH(_phrase ${RETRY_PHRASES}) - IF(${MISSING_COMMIT}) + IF(${MISSING_COMMIT} AND COUNTED LESS 2) LIST(FIND SUBMODULE_LIST ${_submodule} SUBMODULE_INDEX) LIST(GET SUBMODULE_URL_LIST ${SUBMODULE_INDEX} SUBMODULE_URL) MESSAGE("-- Retrying ${_submodule} using 'remote add submodulefix' (attempt ${COUNTED} of ${MAX_ATTEMPTS})...") - GIT_SUBMODULE(${_submodule} false "${SUBMODULE_URL}") + GIT_SUBMODULE("${_submodule}" false "${SUBMODULE_URL}" false) BREAK() ELSEIF("${GIT_MESSAGE}" MATCHES "${_phrase}") MESSAGE("-- Retrying ${_submodule} using 'deinit' (attempt ${COUNTED} of ${MAX_ATTEMPTS})...") - - # Shallow submodules were introduced in 1.8.4 - # Shallow commits can fail to clone from non-default branches, only try once - IF(GIT_VERSION_STRING VERSION_GREATER "1.8.3" AND COUNTED LESS 2) - # Try a shallow submodule clone + IF(COUNTED LESS 2) + SET(FULL_CLONE false) ELSE() - UNSET(DEPTH_VALUE) + SET(FULL_CLONE true) ENDIF() - GIT_SUBMODULE(${_submodule} true false) + GIT_SUBMODULE("${_submodule}" true false ${FULL_CLONE}) BREAK() ENDIF() ENDFOREACH() diff --git a/cmake/modules/PluginList.cmake b/cmake/modules/PluginList.cmake new file mode 100644 index 000000000..c82bba329 --- /dev/null +++ b/cmake/modules/PluginList.cmake @@ -0,0 +1,104 @@ +# Provides a fast mechanism for filtering the plugins used at build-time +SET(PLUGIN_LIST "" CACHE STRING "List of plug-ins to build") +STRING(REPLACE " " ";" PLUGIN_LIST "${PLUGIN_LIST}") +OPTION(LMMS_MINIMAL "Build a minimal list of plug-ins" OFF) +OPTION(LIST_PLUGINS "Lists the available plugins for building" OFF) + +SET(MINIMAL_LIST + audio_file_processor + kicker + triple_oscillator +) + +IF(LMMS_MINIMAL) + IF("${PLUGIN_LIST}" STREQUAL "") + STRING(REPLACE ";" " " MINIMAL_LIST_STRING "${MINIMAL_LIST}") + MESSAGE( +"-- Using minimal plug-ins: ${MINIMAL_LIST_STRING}\n" +" Note: You can specify specific plug-ins using -DPLUGIN_LIST=\"foo bar\"" + ) + ENDIF() + SET(PLUGIN_LIST ${MINIMAL_LIST} ${PLUGIN_LIST}) +ENDIF() + +SET(LMMS_PLUGIN_LIST + ${MINIMAL_LIST} + Amplifier + BassBooster + bit_invader + Bitcrush + carlabase + carlapatchbay + carlarack + CrossoverEQ + Delay + DualFilter + dynamics_processor + Eq + Flanger + HydrogenImport + ladspa_browser + LadspaEffect + lb302 + MidiImport + MidiExport + MultitapEcho + monstro + nes + OpulenZ + organic + FreeBoy + patman + peak_controller_effect + GigPlayer + ReverbSC + sf2_player + sfxr + sid + SpectrumAnalyzer + stereo_enhancer + stereo_matrix + stk + vst_base + vestige + VstEffect + watsyn + waveshaper + vibed + Xpressive + zynaddsubfx +) + +IF("${PLUGIN_LIST}" STREQUAL "") + SET(PLUGIN_LIST ${LMMS_PLUGIN_LIST}) +ENDIF() + +MACRO(LIST_ALL_PLUGINS) + MESSAGE("\n\nAll possible -DPLUGIN_LIST values") + MESSAGE("\n KEYWORD:") + MESSAGE(" -DLMMS_MINIMAL=True") + FOREACH(item IN LISTS MINIMAL_LIST) + MESSAGE(" ${item}") + ENDFOREACH() + MESSAGE("\n NAME:") + FOREACH(item IN LISTS LMMS_PLUGIN_LIST) + MESSAGE(" ${item}") + ENDFOREACH() + MESSAGE("\nNote: This value also impacts the fetching of git submodules.\n") + MESSAGE(FATAL_ERROR "Information was requested, aborting build!") +ENDMACRO() + +IF(LIST_PLUGINS) + UNSET(LIST_PLUGINS CACHE) + LIST_ALL_PLUGINS() +ENDIF() + +IF(MSVC) + SET(MSVC_INCOMPATIBLE_PLUGINS + LadspaEffect + zynaddsubfx + ) + message(WARNING "Compiling with MSVC. The following plugins are not available: ${MSVC_INCOMPATIBLE_PLUGINS}") + LIST(REMOVE_ITEM PLUGIN_LIST ${MSVC_INCOMPATIBLE_PLUGINS}) +ENDIF() + diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 4f139f8b3..a4e56921f 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -14,89 +14,7 @@ INCLUDE_DIRECTORIES( "${CMAKE_BINARY_DIR}/src" ) -SET(PLUGIN_LIST "" CACHE STRING "List of plug-ins to build") - -STRING(REPLACE " " ";" PLUGIN_LIST "${PLUGIN_LIST}") - -OPTION(LMMS_MINIMAL "Build a minimal list of plug-ins" OFF) - -SET(MINIMAL_LIST - audio_file_processor - kicker - triple_oscillator -) - -IF(LMMS_MINIMAL) - IF("${PLUGIN_LIST}" STREQUAL "") - STRING(REPLACE ";" " " MINIMAL_LIST_STRING "${MINIMAL_LIST}") - MESSAGE( -"-- Using minimal plug-ins: ${MINIMAL_LIST_STRING}\n" -" Note: You can specify specific plug-ins using -DPLUGIN_LIST=\"foo bar\"" - ) - ENDIF() - SET(PLUGIN_LIST ${MINIMAL_LIST} ${PLUGIN_LIST}) -ENDIF() - -IF("${PLUGIN_LIST}" STREQUAL "") - SET(PLUGIN_LIST - ${MINIMAL_LIST} - Amplifier - BassBooster - bit_invader - Bitcrush - carlabase - carlapatchbay - carlarack - CrossoverEQ - Delay - DualFilter - dynamics_processor - Eq - Flanger - HydrogenImport - ladspa_browser - LadspaEffect - lb302 - MidiImport - MidiExport - MultitapEcho - monstro - nes - OpulenZ - organic - FreeBoy - patman - peak_controller_effect - GigPlayer - ReverbSC - sf2_player - sfxr - sid - SpectrumAnalyzer - stereo_enhancer - stereo_matrix - stk - vst_base - vestige - VstEffect - watsyn - waveshaper - vibed - Xpressive - zynaddsubfx - ) - -ENDIF("${PLUGIN_LIST}" STREQUAL "") - -IF(MSVC) - SET(MSVC_INCOMPATIBLE_PLUGINS - LadspaEffect - zynaddsubfx - ) - message(WARNING "Compiling with MSVC. The following plugins are not available: ${MSVC_INCOMPATIBLE_PLUGINS}") - LIST(REMOVE_ITEM PLUGIN_LIST ${MSVC_INCOMPATIBLE_PLUGINS}) -ENDIF() - +# See cmake/modules/PluginList.cmake FOREACH(PLUGIN ${PLUGIN_LIST}) ADD_SUBDIRECTORY(${PLUGIN}) ENDFOREACH() From da09b2a941a0067d6b6a59dfd0be043134efa780 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Sun, 6 Oct 2019 01:05:53 -0400 Subject: [PATCH 400/445] CheckSubmodules: Workaround submodules failing (#5222) Workaround git's inability to recover from a shallow clone --- cmake/modules/CheckSubmodules.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/modules/CheckSubmodules.cmake b/cmake/modules/CheckSubmodules.cmake index d2475826b..32a2f9951 100644 --- a/cmake/modules/CheckSubmodules.cmake +++ b/cmake/modules/CheckSubmodules.cmake @@ -123,8 +123,10 @@ MACRO(GIT_SUBMODULE SUBMODULE_PATH FORCE_DEINIT FORCE_REMOTE FULL_CLONE) WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" OUTPUT_QUIET ) + MESSAGE("-- Deleting ${CMAKE_SOURCE_DIR}/.git/${SUBMODULE_PATH}") + FILE(REMOVE_RECURSE "${CMAKE_SOURCE_DIR}/.git/modules/${SUBMODULE_PATH}") # Recurse - GIT_SUBMODULE(${SUBMODULE_PATH} false false ${FULL_CLONE_FLAG}) + GIT_SUBMODULE(${SUBMODULE_PATH} false false true) ELSE() # Try to use the depth switch IF(NO_SHALLOW_CLONE OR GIT_VERSION_STRING VERSION_LESS "1.8.4") @@ -179,11 +181,9 @@ FOREACH(_submodule ${SUBMODULE_LIST}) GIT_SUBMODULE("${_submodule}" false false false) SET(COUNTED 0) - SET(COUNTING "") # Handle edge-cases where submodule didn't clone properly or re-uses a non-empty directory WHILE(NOT GIT_RESULT EQUAL 0 AND COUNTED LESS MAX_ATTEMPTS) - LIST(APPEND COUNTING "x") - LIST(LENGTH COUNTING COUNTED) + MATH(EXPR COUNTED "${COUNTED}+1") SET(MISSING_COMMIT false) FOREACH(_phrase ${MISSING_COMMIT_PHRASES}) IF("${GIT_MESSAGE}" MATCHES "${_phrase}") From 16390f61a51c2134d05e4029ca809cf528ce769f Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 7 Oct 2019 08:01:48 +0900 Subject: [PATCH 401/445] Work around a winegcc bug of Wine >= 4.14 (#5210) See https://bugs.winehq.org/show_bug.cgi?id=47710 for details --- plugins/vst_base/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/vst_base/CMakeLists.txt b/plugins/vst_base/CMakeLists.txt index 84920d9be..441b961f4 100644 --- a/plugins/vst_base/CMakeLists.txt +++ b/plugins/vst_base/CMakeLists.txt @@ -54,6 +54,8 @@ SET(WINE_CXX_ARGS -I${WINE_INCLUDE_BASE_DIR} -I${WINE_INCLUDE_DIR}/windows -L${WINE_LIBRARY_DIR} + # Work around https://bugs.winehq.org/show_bug.cgi?id=47710 + -D__WIDL_objidl_generated_name_0000000C="" ${CMAKE_CURRENT_SOURCE_DIR}/RemoteVstPlugin.cpp -std=c++0x -mwindows -lpthread -lole32 ${EXTRA_FLAGS} -fno-omit-frame-pointer From 2df4fff1c0f83f96e64cd8b4c6af30de2aba9016 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 7 Oct 2019 08:02:03 +0900 Subject: [PATCH 402/445] Work around a winegcc bug of Wine >= 4.14 (#5211) See https://bugs.winehq.org/show_bug.cgi?id=47710 for details --- cmake/modules/winegcc_wrapper.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/modules/winegcc_wrapper.in b/cmake/modules/winegcc_wrapper.in index d32aec664..7677e4c37 100755 --- a/cmake/modules/winegcc_wrapper.in +++ b/cmake/modules/winegcc_wrapper.in @@ -58,6 +58,9 @@ if [ "$win64" = true ] && [ "$no_link" != true ]; then extra_args="$extra_args @WINE_64_FLAGS@" fi +# Work around https://bugs.winehq.org/show_bug.cgi?id=47710 +extra_args="$extra_args -D__WIDL_objidl_generated_name_0000000C=" + # Run winegcc export WINEBUILD=@WINE_BUILD@ @WINE_CXX@ $extra_args $args From 770e8cc777406d42aab2fafe079b9104852e369b Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Tue, 1 Oct 2019 12:12:25 +0300 Subject: [PATCH 403/445] CircleCI: Use xenial for linux.gcc builds AppImage will fail otherwise. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 99b987f86..981034ffb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -101,7 +101,7 @@ jobs: - *save_cache linux.gcc: docker: - - image: lmmsci/linux.gcc:18.04 + - image: lmmsci/linux.gcc:xenial environment: <<: *common_environment steps: From 45cb7f21c5246cd2ca9bf895b86653fc1eefaff5 Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Tue, 1 Oct 2019 22:27:36 +0300 Subject: [PATCH 404/445] linuxdeployqt: drop -unsupported-allow-new-glibc --- cmake/linux/package_linux.sh.in | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index b838237b7..9f233d401 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -175,10 +175,9 @@ 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 -unsupported-allow-new-glibc -bundle-non-qt-libs -verbose=$VERBOSITY $STRIP >> "$LOGFILE" 2>&1 +"$LINUXDEPLOYQT" "$DESKTOPFILE" $executables -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 5aa87886c9c098b1e37c1eeb7e9383a1c8e1a069 Mon Sep 17 00:00:00 2001 From: Steffen Baranowsky Date: Mon, 7 Oct 2019 18:13:44 +0200 Subject: [PATCH 405/445] Rubberband fix for selecting large area in Songeditor (#5003) --- include/SongEditor.h | 17 +++ include/Track.h | 12 ++- include/TrackContainerView.h | 14 +-- src/gui/TrackContainerView.cpp | 59 ++-------- src/gui/editors/SongEditor.cpp | 189 +++++++++++++++++++++++++++++++-- src/gui/widgets/Rubberband.cpp | 12 --- 6 files changed, 218 insertions(+), 85 deletions(-) diff --git a/include/SongEditor.h b/include/SongEditor.h index e03c63280..de149e9a4 100644 --- a/include/SongEditor.h +++ b/include/SongEditor.h @@ -75,6 +75,9 @@ public: public slots: void scrolled( int new_pos ); + void selectRegionFromPixels(int xStart, int xEnd); + void stopSelectRegion(); + void updateRubberband(); void setEditMode( EditMode mode ); void setEditModeDraw(); @@ -85,6 +88,9 @@ public slots: protected: virtual void closeEvent( QCloseEvent * ce ); + virtual void mousePressEvent(QMouseEvent * me); + virtual void mouseMoveEvent(QMouseEvent * me); + virtual void mouseReleaseEvent(QMouseEvent * me); private slots: void setHighQuality( bool ); @@ -109,6 +115,9 @@ private: virtual bool allowRubberband() const; + int trackIndexFromSelectionPoint(int yPos); + int indexOfTrackView(const TrackView* tv); + Song * m_song; @@ -135,6 +144,14 @@ private: bool m_smoothScroll; EditMode m_mode; + QPoint m_origin; + QPoint m_scrollPos; + QPoint m_mousePos; + int m_rubberBandStartTrackview; + MidiTime m_rubberbandStartMidipos; + int m_currentZoomingValue; + int m_trackHeadWidth; + bool m_selectRegion; friend class SongEditorWindow; diff --git a/include/Track.h b/include/Track.h index f548168b7..f3b6c5e4c 100644 --- a/include/Track.h +++ b/include/Track.h @@ -210,6 +210,12 @@ public: { return m_tco; } + + inline TrackView * getTrackView() + { + return m_trackView; + } + // qproperty access func QColor mutedColor() const; QColor mutedBackgroundColor() const; @@ -229,7 +235,7 @@ public: // access needsUpdate member variable bool needsUpdate(); void setNeedsUpdate( bool b ); - + public slots: virtual bool close(); void cut(); @@ -256,10 +262,6 @@ protected: float pixelsPerTact(); - inline TrackView * getTrackView() - { - return m_trackView; - } DataFile createTCODataFiles(const QVector & tcos) const; diff --git a/include/TrackContainerView.h b/include/TrackContainerView.h index bf6ada409..e0c9d11f7 100644 --- a/include/TrackContainerView.h +++ b/include/TrackContainerView.h @@ -133,27 +133,21 @@ public slots: virtual void dropEvent( QDropEvent * _de ); virtual void dragEnterEvent( QDragEnterEvent * _dee ); - /// - /// \brief selectRegionFromPixels - /// \param x - /// \param y - /// Use the rubber band to select TCO from all tracks using x, y pixels - void selectRegionFromPixels(int xStart, int xEnd); /// /// \brief stopRubberBand /// Removes the rubber band from display when finished with. void stopRubberBand(); + protected: static const int DEFAULT_PIXELS_PER_TACT = 16; - virtual void mousePressEvent( QMouseEvent * _me ); - virtual void mouseMoveEvent( QMouseEvent * _me ); - virtual void mouseReleaseEvent( QMouseEvent * _me ); + virtual void resizeEvent( QResizeEvent * ); MidiTime m_currentPosition; + RubberBand *rubberBand() const; private: @@ -187,7 +181,7 @@ private: float m_ppt; RubberBand * m_rubberBand; - QPoint m_origin; + signals: diff --git a/src/gui/TrackContainerView.cpp b/src/gui/TrackContainerView.cpp index 4c7498ab0..255fb1a02 100644 --- a/src/gui/TrackContainerView.cpp +++ b/src/gui/TrackContainerView.cpp @@ -55,8 +55,7 @@ TrackContainerView::TrackContainerView( TrackContainer * _tc ) : m_trackViews(), m_scrollArea( new scrollArea( this ) ), m_ppt( DEFAULT_PIXELS_PER_TACT ), - m_rubberBand( new RubberBand( m_scrollArea ) ), - m_origin() + m_rubberBand( new RubberBand( m_scrollArea ) ) { m_tc->setHook( this ); //keeps the direction of the widget, undepended on the locale @@ -346,12 +345,8 @@ void TrackContainerView::dragEnterEvent( QDragEnterEvent * _dee ) arg( Track::SampleTrack ) ); } -void TrackContainerView::selectRegionFromPixels(int xStart, int xEnd) -{ - m_rubberBand->setEnabled( true ); - m_rubberBand->show(); - m_rubberBand->setGeometry( min( xStart, xEnd ), 0, max( xStart, xEnd ) - min( xStart, xEnd ), std::numeric_limits::max() ); -} + + void TrackContainerView::stopRubberBand() { @@ -427,46 +422,6 @@ void TrackContainerView::dropEvent( QDropEvent * _de ) -void TrackContainerView::mousePressEvent( QMouseEvent * _me ) -{ - if( allowRubberband() == true ) - { - m_origin = m_scrollArea->mapFromParent( _me->pos() ); - m_rubberBand->setEnabled( true ); - m_rubberBand->setGeometry( QRect( m_origin, QSize() ) ); - m_rubberBand->show(); - } - QWidget::mousePressEvent( _me ); -} - - - - -void TrackContainerView::mouseMoveEvent( QMouseEvent * _me ) -{ - if( rubberBandActive() == true ) - { - m_rubberBand->setGeometry( QRect( m_origin, - m_scrollArea->mapFromParent( _me->pos() ) ). - normalized() ); - } - QWidget::mouseMoveEvent( _me ); -} - - - - -void TrackContainerView::mouseReleaseEvent( QMouseEvent * _me ) -{ - m_rubberBand->hide(); - m_rubberBand->setEnabled( false ); - QWidget::mouseReleaseEvent( _me ); -} - - - - - void TrackContainerView::resizeEvent( QResizeEvent * _re ) { realignTracks(); @@ -476,6 +431,14 @@ void TrackContainerView::resizeEvent( QResizeEvent * _re ) +RubberBand *TrackContainerView::rubberBand() const +{ + return m_rubberBand; +} + + + + TrackContainerView::scrollArea::scrollArea( TrackContainerView * _parent ) : QScrollArea( _parent ), m_trackContainerView( _parent ) diff --git a/src/gui/editors/SongEditor.cpp b/src/gui/editors/SongEditor.cpp index 286b01f15..31cb142c0 100644 --- a/src/gui/editors/SongEditor.cpp +++ b/src/gui/editors/SongEditor.cpp @@ -51,8 +51,7 @@ #include "TimeDisplayWidget.h" #include "AudioDevice.h" #include "PianoRoll.h" - - +#include "Track.h" positionLine::positionLine( QWidget * parent ) : QWidget( parent ) @@ -80,15 +79,21 @@ SongEditor::SongEditor( Song * song ) : m_zoomingModel(new ComboBoxModel()), m_scrollBack( false ), m_smoothScroll( ConfigManager::inst()->value( "ui", "smoothscroll" ).toInt() ), - m_mode(DrawMode) + m_mode(DrawMode), + m_origin(), + m_scrollPos(), + m_mousePos(), + m_rubberBandStartTrackview(0), + m_rubberbandStartMidipos(0), + m_currentZoomingValue(m_zoomingModel->value()), + m_trackHeadWidth(ConfigManager::inst()->value("ui", "compacttrackbuttons").toInt()==1 + ? DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT + : DEFAULT_SETTINGS_WIDGET_WIDTH + TRACK_OP_WIDTH), + m_selectRegion(false) { m_zoomingModel->setParent(this); // create time-line - int widgetTotal = ConfigManager::inst()->value( "ui", - "compacttrackbuttons" ).toInt()==1 ? - DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT : - DEFAULT_SETTINGS_WIDGET_WIDTH + TRACK_OP_WIDTH; - m_timeLine = new TimeLineWidget( widgetTotal, 32, + m_timeLine = new TimeLineWidget( m_trackHeadWidth, 32, pixelsPerTact(), m_song->m_playPos[Song::Mode_PlaySong], m_currentPosition, this ); @@ -239,6 +244,10 @@ SongEditor::SongEditor( Song * song ) : this, SLOT( scrolled( int ) ) ); connect( m_song, SIGNAL( lengthChanged( int ) ), this, SLOT( updateScrollBar( int ) ) ); + connect(m_leftRightScroll, SIGNAL(valueChanged(int)),this, SLOT(updateRubberband())); + connect(contentWidget()->verticalScrollBar(), SIGNAL(valueChanged(int)),this, SLOT(updateRubberband())); + connect(m_timeLine, SIGNAL(selectionFinished()), this, SLOT(stopSelectRegion())); + // Set up zooming model for( float const & zoomLevel : m_zoomLevels ) @@ -293,6 +302,99 @@ void SongEditor::scrolled( int new_pos ) +void SongEditor::selectRegionFromPixels(int xStart, int xEnd) +{ + if (!m_selectRegion) + { + m_selectRegion = true; + + //deselect all tcos + for (auto &it : findChildren()) { it->setSelected(false); } + + rubberBand()->setEnabled(true); + rubberBand()->show(); + + //we save the position of scrollbars, mouse position and zooming level + m_origin = QPoint(xStart, 0); + m_scrollPos = QPoint(m_leftRightScroll->value(), contentWidget()->verticalScrollBar()->value()); + m_currentZoomingValue = zoomingModel()->value(); + + //calculate the song position where the mouse was clicked + m_rubberbandStartMidipos = MidiTime((xStart - m_trackHeadWidth) + / pixelsPerTact() * MidiTime::ticksPerTact()) + + m_currentPosition; + m_rubberBandStartTrackview = 0; + } + //the current mouse position within the borders of song editor + m_mousePos = QPoint(qMax(m_trackHeadWidth, qMin(xEnd, width())) + , std::numeric_limits::max()); + updateRubberband(); +} + + + + +void SongEditor::stopSelectRegion() +{ + m_selectRegion = false; +} + + + + +void SongEditor::updateRubberband() +{ + if (rubberBandActive()) + { + int originX = m_origin.x(); + + //take care of the zooming + if (m_currentZoomingValue != m_zoomingModel->value()) + { + originX = m_trackHeadWidth + (originX - m_trackHeadWidth) + * m_zoomLevels[m_zoomingModel->value()] / m_zoomLevels[m_currentZoomingValue]; + } + + //take care of the scrollbar position + int hs = (m_leftRightScroll->value() - m_scrollPos.x()) * pixelsPerTact(); + int vs = contentWidget()->verticalScrollBar()->value() - m_scrollPos.y(); + + //the adjusted origin point + QPoint origin = QPoint(qMax(originX - hs, m_trackHeadWidth), m_origin.y() - vs); + + //paint the rubber band rect + rubberBand()->setGeometry(QRect(origin, + contentWidget()->mapFromParent(QPoint(m_mousePos.x(), m_mousePos.y())) + ).normalized()); + + //the index of the TrackView the mouse is hover + int rubberBandTrackview = trackIndexFromSelectionPoint(m_mousePos.y()); + + //the miditime the mouse is hover + MidiTime rubberbandMidipos = MidiTime((qMin(m_mousePos.x(), width()) - m_trackHeadWidth) + / pixelsPerTact() * MidiTime::ticksPerTact()) + + m_currentPosition; + + //are tcos in the rect of selection? + for (auto &it : findChildren()) + { + TrackContentObjectView * tco = dynamic_cast(it); + if (tco) + { + auto indexOfTrackView = trackViews().indexOf(tco->getTrackView()); + bool isBeetweenRubberbandViews = indexOfTrackView >= qMin(m_rubberBandStartTrackview, rubberBandTrackview) + && indexOfTrackView <= qMax(m_rubberBandStartTrackview, rubberBandTrackview); + bool isBeetweenRubberbandMidiPos = tco->getTrackContentObject()->endPosition() >= qMin(m_rubberbandStartMidipos, rubberbandMidipos) + && tco->getTrackContentObject()->startPosition() <= qMax(m_rubberbandStartMidipos, rubberbandMidipos); + it->setSelected(isBeetweenRubberbandViews && isBeetweenRubberbandMidiPos); + } + } + } +} + + + + void SongEditor::setEditMode( EditMode mode ) { m_mode = mode; @@ -394,7 +496,7 @@ void SongEditor::wheelEvent( QWheelEvent * we ) void SongEditor::closeEvent( QCloseEvent * ce ) - { +{ if( parentWidget() ) { parentWidget()->hide(); @@ -404,7 +506,53 @@ void SongEditor::closeEvent( QCloseEvent * ce ) hide(); } ce->ignore(); - } +} + + + + +void SongEditor::mousePressEvent(QMouseEvent *me) +{ + if (allowRubberband()) + { + //we save the position of scrollbars, mouse position and zooming level + m_scrollPos = QPoint(m_leftRightScroll->value(), contentWidget()->verticalScrollBar()->value()); + m_origin = contentWidget()->mapFromParent(QPoint(me->pos().x(), me->pos().y())); + m_currentZoomingValue = zoomingModel()->value(); + + //paint the rubberband + rubberBand()->setEnabled(true); + rubberBand()->setGeometry(QRect(m_origin, QSize())); + rubberBand()->show(); + + //the trackView(index) and the miditime where the mouse was clicked + m_rubberBandStartTrackview = trackIndexFromSelectionPoint(me->y()); + m_rubberbandStartMidipos = MidiTime((me->x() - m_trackHeadWidth) + / pixelsPerTact() * MidiTime::ticksPerTact()) + + m_currentPosition; + } + QWidget::mousePressEvent(me); +} + + + + +void SongEditor::mouseMoveEvent(QMouseEvent *me) +{ + m_mousePos = me->pos(); + updateRubberband(); + QWidget::mouseMoveEvent(me); +} + + + + +void SongEditor::mouseReleaseEvent(QMouseEvent *me) +{ + rubberBand()->hide(); + rubberBand()->setEnabled(false); + QWidget::mouseReleaseEvent(me); +} @@ -602,6 +750,7 @@ void SongEditor::zoomingChanged() m_song->m_playPos[Song::Mode_PlaySong].m_timeLine-> setPixelsPerTact( pixelsPerTact() ); realignTracks(); + updateRubberband(); } @@ -615,6 +764,26 @@ bool SongEditor::allowRubberband() const +int SongEditor::trackIndexFromSelectionPoint(int yPos) +{ + const TrackView * tv = trackViewAt(yPos - m_timeLine->height()); + return tv ? indexOfTrackView(tv) + : yPos < m_timeLine->height() ? 0 + : trackViews().count(); +} + + + + +int SongEditor::indexOfTrackView(const TrackView *tv) +{ + return static_cast(std::distance(trackViews().begin(), + std::find(trackViews().begin(), trackViews().end(), tv))); +} + + + + ComboBoxModel *SongEditor::zoomingModel() const { return m_zoomingModel; diff --git a/src/gui/widgets/Rubberband.cpp b/src/gui/widgets/Rubberband.cpp index 6bf702edc..0a4e891b5 100644 --- a/src/gui/widgets/Rubberband.cpp +++ b/src/gui/widgets/Rubberband.cpp @@ -66,18 +66,6 @@ QVector RubberBand::selectedObjects() const void RubberBand::resizeEvent( QResizeEvent * _re ) { QRubberBand::resizeEvent( _re ); - if( isEnabled() ) - { - QVector so = selectableObjects(); - for( QVector::iterator it = so.begin(); - it != so.end(); ++it ) - { - ( *it )->setSelected( QRect( pos(), size() ).intersects( - QRect( ( *it )->mapTo( parentWidget(), - QPoint() ), - ( *it )->size() ) ) ); - } - } } From e1d311730b5de201c7b02360d5caa7e22b204af0 Mon Sep 17 00:00:00 2001 From: Kevin Zander Date: Mon, 7 Oct 2019 14:33:11 -0500 Subject: [PATCH 406/445] Fix regression introduced in #5170 (#5224) --- src/gui/editors/AutomationEditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 7583501c7..bb00a1bd1 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -1484,7 +1484,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) m_leftRightScroll->setPageStep( l ); } - if( validPattern() && GuiApplication::instance()->automationEditor()->hasFocus() ) + if(validPattern() && GuiApplication::instance()->automationEditor()->m_editor->hasFocus()) { drawCross( p ); From 91a38a922d349e6f0b9beabfe25f1f5b2d0fc0a1 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Thu, 10 Oct 2019 10:06:14 +0900 Subject: [PATCH 407/445] Add back '-Wl,-E' (#5233) --- src/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 10ce72ae6..2fa72a401 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -198,8 +198,12 @@ IF(LMMS_BUILD_WIN32) ) ENDIF() ELSE() + IF(NOT LMMS_BUILD_APPLE) + SET_TARGET_PROPERTIES(lmms PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Wl,-E") + ENDIF(NOT LMMS_BUILD_APPLE) + INSTALL(FILES "${CMAKE_BINARY_DIR}/lmms.1.gz" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/man/man1/" PERMISSIONS OWNER_READ GROUP_READ WORLD_READ) ENDIF() -INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") \ No newline at end of file +INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}") From d7a78fe1212af26bdbfa38802bc3038eded0814f Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Thu, 10 Oct 2019 14:22:42 +0900 Subject: [PATCH 408/445] Specify timeout for transfer.sh uploads Prevents "No output has been received in the last 10m0s" errors on Travis CI. --- .travis/script.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis/script.sh b/.travis/script.sh index 70391a762..b723f5dd0 100755 --- a/.travis/script.sh +++ b/.travis/script.sh @@ -42,5 +42,7 @@ else fi echo "Uploading $PACKAGE to transfer.sh..." - curl --upload-file "$PACKAGE" "https://transfer.sh/$PACKAGE" || true + # Limit the connection time to 3 minutes and total upload time to 5 minutes + # Otherwise the build may hang + curl --connect-timeout 180 --max-time 300 --upload-file "$PACKAGE" "https://transfer.sh/$PACKAGE" || true fi From e321dff733061597869821de6c37c1683d6f06c4 Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Thu, 10 Oct 2019 19:01:17 +0200 Subject: [PATCH 409/445] Translation Fixes (Continuation of #4482) (#5185) Fix some formatting issues with some translations. * Russian * Polish * Swedish * Ukrainian --- data/locale/pl.ts | 2 +- data/locale/ru.ts | 4 ++-- data/locale/sv.ts | 4 ++-- data/locale/uk.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/data/locale/pl.ts b/data/locale/pl.ts index 2e8f989ce..4cbc95441 100644 --- a/data/locale/pl.ts +++ b/data/locale/pl.ts @@ -3002,7 +3002,7 @@ You can remove and move FX channels in the context menu, which is accessed by ri VELOCITY - PRĘDKOŚĆ UDERZENIA + PRĘDKOŚĆ ENABLE MIDI OUTPUT diff --git a/data/locale/ru.ts b/data/locale/ru.ts index 9946e5cfd..1d1c2d73e 100644 --- a/data/locale/ru.ts +++ b/data/locale/ru.ts @@ -1664,7 +1664,7 @@ Oe Ai <oeai/at/symbiants/dot/com> W/D - НАСЫЩ + @@ -1679,7 +1679,7 @@ Oe Ai <oeai/at/symbiants/dot/com> DECAY - ЗАТУХАНИЕ + diff --git a/data/locale/sv.ts b/data/locale/sv.ts index 7b2557cfd..6e3e4f9af 100644 --- a/data/locale/sv.ts +++ b/data/locale/sv.ts @@ -1658,7 +1658,7 @@ If you're interested in translating LMMS in another language or want to imp W/D - B/T + @@ -1673,7 +1673,7 @@ If you're interested in translating LMMS in another language or want to imp DECAY - FÖRFALL + diff --git a/data/locale/uk.ts b/data/locale/uk.ts index 39403714f..fa0eede63 100644 --- a/data/locale/uk.ts +++ b/data/locale/uk.ts @@ -1678,7 +1678,7 @@ If you're interested in translating LMMS in another language or want to imp DECAY - ЗГАСАННЯ + From 6dee6a4418b7e541b548170fb32d4f15aab8ef9e Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Sat, 12 Oct 2019 17:41:30 +0200 Subject: [PATCH 410/445] Show icon on 'Turn off all notes' button (#5237) Backporting fix from 2815da28057788ba420d8e128958698a8c3d2d6d by @karmux --- plugins/vestige/vestige.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index fc07e46d5..143c9dc37 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -607,7 +607,7 @@ VestigeInstrumentView::VestigeInstrumentView( Instrument * _instrument, QPushButton * note_off_all_btn = new QPushButton( tr( "Turn off all " "notes" ), this ); note_off_all_btn->setGeometry( 20, 160, 200, 24 ); - note_off_all_btn->setIcon( embed::getIconPixmap( "state_stop" ) ); + note_off_all_btn->setIcon( embed::getIconPixmap( "stop" ) ); note_off_all_btn->setFont( pointSize<8>( note_off_all_btn->font() ) ); connect( note_off_all_btn, SIGNAL( clicked() ), this, SLOT( noteOffAll() ) ); From 95c46a805d4673b6ebbaf7a549b278fab478c249 Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 15 Oct 2019 11:18:46 +0900 Subject: [PATCH 411/445] RemoteVstPlugin: fix crashes when failed to open a file (#5235) --- plugins/vst_base/RemoteVstPlugin.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp index 4a147f7c9..d12ccd88a 100644 --- a/plugins/vst_base/RemoteVstPlugin.cpp +++ b/plugins/vst_base/RemoteVstPlugin.cpp @@ -718,6 +718,7 @@ void RemoteVstPlugin::init( const std::string & _plugin_file ) static void close_check( FILE* fp ) { + if (!fp) {return;} if( fclose( fp ) ) { perror( "close" ); @@ -1115,6 +1116,12 @@ void RemoteVstPlugin::saveChunkToFile( const std::string & _file ) if( len > 0 ) { FILE* fp = F_OPEN_UTF8( _file, "wb" ); + if (!fp) + { + fprintf( stderr, + "Error opening file for saving chunk.\n" ); + return; + } if ( fwrite( chunk, 1, len, fp ) != len ) { fprintf( stderr, @@ -1280,6 +1287,12 @@ void RemoteVstPlugin::savePreset( const std::string & _file ) pBank->numPrograms = endian_swap( uIntToFile ); FILE * stream = F_OPEN_UTF8( _file, "w" ); + if (!stream) + { + fprintf( stderr, + "Error opening file for saving preset.\n" ); + return; + } fwrite ( pBank, 1, 28, stream ); fwrite ( progName, 1, isPreset ? 28 : 128, stream ); if ( chunky ) { @@ -1332,6 +1345,12 @@ void RemoteVstPlugin::loadPresetFile( const std::string & _file ) unsigned int len = 0; sBank * pBank = (sBank*) new char[ sizeof( sBank ) ]; FILE * stream = F_OPEN_UTF8( _file, "r" ); + if (!stream) + { + fprintf( stderr, + "Error opening file for loading preset.\n" ); + return; + } if ( fread ( pBank, 1, 56, stream ) != 56 ) { fprintf( stderr, "Error loading preset file.\n" ); @@ -1433,6 +1452,12 @@ void RemoteVstPlugin::loadChunkFromFile( const std::string & _file, int _len ) char * chunk = new char[_len]; FILE* fp = F_OPEN_UTF8( _file, "rb" ); + if (!fp) + { + fprintf( stderr, + "Error opening file for loading chunk.\n" ); + return; + } if ( fread( chunk, 1, _len, fp ) != _len ) { fprintf( stderr, "Error loading chunk from file.\n" ); From 170d28ffbd39b1f0406e437eaeac39a07389f525 Mon Sep 17 00:00:00 2001 From: Kevin Zander Date: Mon, 14 Oct 2019 21:22:41 -0500 Subject: [PATCH 412/445] Remove global automation from MIDI import (#5223) --- plugins/MidiImport/MidiImport.cpp | 35 +++++++++++++++++-------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/plugins/MidiImport/MidiImport.cpp b/plugins/MidiImport/MidiImport.cpp index 1f2ab1f57..b8653fe18 100644 --- a/plugins/MidiImport/MidiImport.cpp +++ b/plugins/MidiImport/MidiImport.cpp @@ -309,10 +309,20 @@ bool MidiImport::readSMF( TrackContainer* tc ) smfMidiChannel chs[256]; MeterModel & timeSigMM = Engine::getSong()->getTimeSigModel(); - AutomationPattern * timeSigNumeratorPat = - AutomationPattern::globalAutomationPattern( &timeSigMM.numeratorModel() ); - AutomationPattern * timeSigDenominatorPat = - AutomationPattern::globalAutomationPattern( &timeSigMM.denominatorModel() ); + AutomationTrack * nt = dynamic_cast( + Track::create(Track::AutomationTrack, Engine::getSong())); + nt->setName(tr("MIDI Time Signature Numerator")); + AutomationTrack * dt = dynamic_cast( + Track::create(Track::AutomationTrack, Engine::getSong())); + dt->setName(tr("MIDI Time Signature Denominator")); + AutomationPattern * timeSigNumeratorPat = + new AutomationPattern(nt); + timeSigNumeratorPat->setDisplayName(tr("Numerator")); + timeSigNumeratorPat->addObject(&timeSigMM.numeratorModel()); + AutomationPattern * timeSigDenominatorPat = + new AutomationPattern(dt); + timeSigDenominatorPat->setDisplayName(tr("Denominator")); + timeSigDenominatorPat->addObject(&timeSigMM.denominatorModel()); // TODO: adjust these to Time.Sig changes double beatsPerTact = 4; @@ -323,19 +333,12 @@ bool MidiImport::readSMF( TrackContainer* tc ) for( int s = 0; s < timeSigs->length(); ++s ) { Alg_time_sig timeSig = (*timeSigs)[s]; - // Initial timeSig, set song-default value - if(/* timeSig.beat == 0*/ true ) - { - // TODO set song-global default value - printf("Another timesig at %f\n", timeSig.beat); - timeSigNumeratorPat->putValue( timeSig.beat*ticksPerBeat, timeSig.num ); - timeSigDenominatorPat->putValue( timeSig.beat*ticksPerBeat, timeSig.den ); - } - else - { - } - + timeSigNumeratorPat->putValue(timeSig.beat * ticksPerBeat, timeSig.num); + timeSigDenominatorPat->putValue(timeSig.beat * ticksPerBeat, timeSig.den); } + // manually call otherwise the pattern shows being 1 bar + timeSigNumeratorPat->updateLength(); + timeSigDenominatorPat->updateLength(); pd.setValue( 2 ); From f1831ffdc614b44f051de6e345af134bdaf8241f Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Thu, 17 Oct 2019 08:50:12 +0900 Subject: [PATCH 413/445] Export TrackContentObject class Fix a build error introduced in #5223. --- include/Track.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Track.h b/include/Track.h index b00c50248..6c98de10e 100644 --- a/include/Track.h +++ b/include/Track.h @@ -73,7 +73,7 @@ const int DEFAULT_TRACK_HEIGHT = 32; const int TCO_BORDER_WIDTH = 2; -class TrackContentObject : public Model, public JournallingObject +class LMMS_EXPORT TrackContentObject : public Model, public JournallingObject { Q_OBJECT MM_OPERATORS From d005eec1aab1d3252c20b426ac43561ec0e75149 Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Thu, 17 Oct 2019 03:03:26 +0300 Subject: [PATCH 414/445] MSVC: Move MSVC year detection to DetectMachine.cmake. --- cmake/modules/DetectMachine.cmake | 19 ++++++++++++++++ plugins/vst_base/RemoteVstPlugin32.cmake | 28 +++++++----------------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/cmake/modules/DetectMachine.cmake b/cmake/modules/DetectMachine.cmake index f3458165b..08e8745cd 100644 --- a/cmake/modules/DetectMachine.cmake +++ b/cmake/modules/DetectMachine.cmake @@ -30,6 +30,25 @@ IF(WIN32) ELSE(WIN64) SET(IS_X86 TRUE) ENDIF(WIN64) + + if(MSVC) + SET(MSVC_VER ${CMAKE_CXX_COMPILER_VERSION}) + + IF(MSVC_VER VERSION_GREATER 19.20 OR MSVC_VER VERSION_EQUAL 19.20) + SET(LMMS_MSVC_GENERATOR "Visual Studio 16 2019") + SET(LMMS_MSVC_YEAR 2019) # Qt only provides binaries for MSVC 2017, but 2019 is binary compatible + ELSEIF(MSVC_VER VERSION_GREATER 19.10 OR MSVC_VER VERSION_EQUAL 19.10) + SET(LMMS_MSVC_GENERATOR "Visual Studio 15 2017") + SET(LMMS_MSVC_YEAR 2017) + ELSEIF(MSVC_VER VERSION_GREATER 19.0 OR MSVC_VER VERSION_EQUAL 19.0) + SET(LMMS_MSVC_GENERATOR "Visual Studio 14 2015") + SET(LMMS_MSVC_YEAR 2015) + ELSE() + MESSAGE(SEND_WARNING "Can't detect MSVC version: ${MSVC_VER}") + ENDIF() + + unset(MSVC_VER) + endif() ELSE(WIN32) EXEC_PROGRAM( ${CMAKE_C_COMPILER} ARGS "-dumpmachine ${CMAKE_C_FLAGS}" OUTPUT_VARIABLE Machine ) MESSAGE("Machine: ${Machine}") diff --git a/plugins/vst_base/RemoteVstPlugin32.cmake b/plugins/vst_base/RemoteVstPlugin32.cmake index 1cac65e15..cba9a26c8 100644 --- a/plugins/vst_base/RemoteVstPlugin32.cmake +++ b/plugins/vst_base/RemoteVstPlugin32.cmake @@ -17,27 +17,15 @@ ENDMACRO() IF(LMMS_BUILD_WIN32 AND NOT LMMS_BUILD_WIN64) ADD_SUBDIRECTORY(RemoteVstPlugin) ELSEIF(LMMS_BUILD_WIN64 AND MSVC) - SET(MSVC_VER ${CMAKE_CXX_COMPILER_VERSION}) - - IF(NOT CMAKE_GENERATOR_32) - IF(MSVC_VER VERSION_GREATER 19.20 OR MSVC_VER VERSION_EQUAL 19.20) - SET(CMAKE_GENERATOR_32 "Visual Studio 16 2019") - SET(MSVC_YEAR 2017) # Qt only provides binaries for MSVC 2017, but 2019 is binary compatible - ELSEIF(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) + SET(LMMS_MSVC_YEAR_FOR_QT ${LMMS_MSVC_YEAR}) + + if(LMMS_MSVC_YEAR_FOR_QT EQUAL 2019) + SET(LMMS_MSVC_YEAR_FOR_QT 2017) # Qt only provides binaries for MSVC 2017, but 2019 is binary compatible + endif() + GET_FILENAME_COMPONENT(QT_BIN_DIR ${QT_QMAKE_EXECUTABLE} DIRECTORY) - SET(QT_32_PREFIX "${QT_BIN_DIR}/../../msvc${MSVC_YEAR}") + SET(QT_32_PREFIX "${QT_BIN_DIR}/../../msvc${LMMS_MSVC_YEAR_FOR_QT}") ENDIF() #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. @@ -48,7 +36,7 @@ ELSEIF(LMMS_BUILD_WIN64 AND MSVC) ExternalProject_Add(RemoteVstPlugin32 "${EXTERNALPROJECT_ARGS}" - CMAKE_GENERATOR "${CMAKE_GENERATOR_32}" + CMAKE_GENERATOR "${LMMS_MSVC_GENERATOR}" CMAKE_GENERATOR_PLATFORM Win32 #CMAKE_GENERATOR_TOOLSET "${CMAKE_GENERATOR_TOOLSET}" CMAKE_ARGS From a22b6d75750800123dd68119a66737fe52078075 Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Thu, 17 Oct 2019 03:04:18 +0300 Subject: [PATCH 415/445] NSIS: Add compiler to installer name --- cmake/nsis/CMakeLists.txt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cmake/nsis/CMakeLists.txt b/cmake/nsis/CMakeLists.txt index ac628d549..3fcb4b2f3 100644 --- a/cmake/nsis/CMakeLists.txt +++ b/cmake/nsis/CMakeLists.txt @@ -1,3 +1,8 @@ +SET(WIN_PLATFORM mingw) +if(LMMS_MSVC_YEAR) + SET(WIN_PLATFORM "msvc${LMMS_MSVC_YEAR}") +endif() + SET(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis/nsis_branding.bmp") IF(MSVC) STRING(REPLACE "/" "\\\\" CPACK_PACKAGE_ICON ${CPACK_PACKAGE_ICON}) @@ -15,7 +20,7 @@ SET(CPACK_NSIS_DEFINES " !include FileAssociation.nsh !include LogicLib.nsh !include WinVer.nsh") -SET(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${VERSION}-win32") +SET(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${VERSION}-${WIN_PLATFORM}-win32") SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS " \\\${registerExtension} \\\"$INSTDIR\\\\${CMAKE_PROJECT_NAME}.exe\\\" \\\".mmp\\\" \\\"${PROJECT_NAME_UCASE} Project\\\" \\\${registerExtension} \\\"$INSTDIR\\\\${CMAKE_PROJECT_NAME}.exe\\\" \\\".mmpz\\\" \\\"${PROJECT_NAME_UCASE} Project (compressed)\\\" @@ -31,7 +36,7 @@ SET(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS " " PARENT_SCOPE) IF(WIN64) - SET(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${VERSION}-win64") + SET(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${VERSION}-${WIN_PLATFORM}-win64") SET(CPACK_INSTALL_FIX "$PROGRAMFILES64\\\\${CPACK_PACKAGE_INSTALL_DIRECTORY}\\\\") SET(CPACK_NSIS_DEFINES " ${CPACK_NSIS_DEFINES} From 2d17bf07f3e575a1a5a5da00df57a01d0956cf3d Mon Sep 17 00:00:00 2001 From: Lost Robot <34612565+DouglasDGI@users.noreply.github.com> Date: Thu, 17 Oct 2019 01:44:55 -0600 Subject: [PATCH 416/445] Allow mid-note automation of BitInvader sample length (#4705) --- plugins/bit_invader/bit_invader.cpp | 20 ++++++++------------ plugins/bit_invader/bit_invader.h | 5 ++--- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/plugins/bit_invader/bit_invader.cpp b/plugins/bit_invader/bit_invader.cpp index f8a8423ad..caa272fa7 100644 --- a/plugins/bit_invader/bit_invader.cpp +++ b/plugins/bit_invader/bit_invader.cpp @@ -64,17 +64,16 @@ Plugin::Descriptor PLUGIN_EXPORT bitinvader_plugin_descriptor = } -bSynth::bSynth( float * _shape, int _length, NotePlayHandle * _nph, bool _interpolation, +bSynth::bSynth( float * _shape, NotePlayHandle * _nph, bool _interpolation, float _factor, const sample_rate_t _sample_rate ) : sample_index( 0 ), sample_realindex( 0 ), nph( _nph ), - sample_length( _length ), sample_rate( _sample_rate ), interpolation( _interpolation) { - sample_shape = new float[sample_length]; - for (int i=0; i < _length; ++i) + sample_shape = new float[200]; + for (int i=0; i < 200; ++i) { sample_shape[i] = _shape[i] * _factor; } @@ -87,7 +86,7 @@ bSynth::~bSynth() } -sample_t bSynth::nextStringSample() +sample_t bSynth::nextStringSample( float sample_length ) { float sample_step = static_cast( sample_length / ( sample_rate / nph->frequency() ) ); @@ -140,10 +139,12 @@ sample_t bSynth::nextStringSample() bitInvader::bitInvader( InstrumentTrack * _instrument_track ) : Instrument( _instrument_track, &bitinvader_plugin_descriptor ), m_sampleLength( 128, 4, 200, 1, this, tr( "Sample length" ) ), - m_graph( -1.0f, 1.0f, 128, this ), + m_graph( -1.0f, 1.0f, 200, this ), m_interpolation( false, this ), m_normalize( false, this ) { + + lengthChanged(); m_graph.setWaveToSine(); @@ -278,7 +279,6 @@ void bitInvader::playNote( NotePlayHandle * _n, _n->m_pluginData = new bSynth( const_cast( m_graph.samples() ), - m_graph.length(), _n, m_interpolation.value(), factor, Engine::mixer()->processingSampleRate() ); @@ -290,7 +290,7 @@ void bitInvader::playNote( NotePlayHandle * _n, bSynth * ps = static_cast( _n->m_pluginData ); for( fpp_t frame = offset; frame < frames + offset; ++frame ) { - const sample_t cur = ps->nextStringSample(); + const sample_t cur = ps->nextStringSample( m_graph.length() ); for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl ) { _working_buffer[frame][chnl] = cur; @@ -572,7 +572,3 @@ PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * ) } - - - - diff --git a/plugins/bit_invader/bit_invader.h b/plugins/bit_invader/bit_invader.h index 793831e4a..ae9c92cb2 100644 --- a/plugins/bit_invader/bit_invader.h +++ b/plugins/bit_invader/bit_invader.h @@ -42,12 +42,12 @@ class bSynth { MM_OPERATORS public: - bSynth( float * sample, int length, NotePlayHandle * _nph, + bSynth( float * sample, NotePlayHandle * _nph, bool _interpolation, float factor, const sample_rate_t _sample_rate ); virtual ~bSynth(); - sample_t nextStringSample(); + sample_t nextStringSample( float sample_length ); private: @@ -55,7 +55,6 @@ private: float sample_realindex; float* sample_shape; NotePlayHandle* nph; - const int sample_length; const sample_rate_t sample_rate; bool interpolation; From 732448c3921d9ef2e4297d6670ecfcade42e8572 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 2 Jun 2019 08:18:36 +0100 Subject: [PATCH 417/445] FreeBSD build version --- CMakeLists.txt | 4 ++-- cmake/modules/DetectMachine.cmake | 2 ++ include/versioninfo.h | 4 ++++ plugins/zynaddsubfx/CMakeLists.txt | 2 +- src/core/Mixer.cpp | 2 +- src/core/ProjectRenderer.cpp | 2 +- src/core/main.cpp | 2 +- src/gui/PianoView.cpp | 2 +- src/lmmsconfig.h.in | 1 + 9 files changed, 14 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 057cfa281..5dab2ab13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -431,9 +431,9 @@ If(WANT_GIG) ENDIF(WANT_GIG) # check for pthreads -IF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE OR LMMS_BUILD_OPENBSD) +IF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE OR LMMS_BUILD_OPENBSD OR LMMS_BUILD_FREEBSD) FIND_PACKAGE(Threads) -ENDIF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE OR LMMS_BUILD_OPENBSD) +ENDIF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE OR LMMS_BUILD_OPENBSD OR LMMS_BUILD_FREEBSD) IF(WANT_SNDIO) FIND_PACKAGE(Sndio) diff --git a/cmake/modules/DetectMachine.cmake b/cmake/modules/DetectMachine.cmake index 60c4a0953..c764b5507 100644 --- a/cmake/modules/DetectMachine.cmake +++ b/cmake/modules/DetectMachine.cmake @@ -4,6 +4,8 @@ ELSEIF(APPLE) SET(LMMS_BUILD_APPLE 1) ELSEIF(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") SET(LMMS_BUILD_OPENBSD 1) +ELSEIF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") + SET(LMMS_BUILD_FREEBSD 1) ELSEIF(HAIKU) SET(LMMS_BUILD_HAIKU 1) ELSE() diff --git a/include/versioninfo.h b/include/versioninfo.h index 8477a61c0..664fc80e6 100644 --- a/include/versioninfo.h +++ b/include/versioninfo.h @@ -28,6 +28,10 @@ #define PLATFORM "OpenBSD" #endif +#ifdef LMMS_BUILD_FREEBSD +#define PLATFORM "FreeBSD" +#endif + #ifdef LMMS_BUILD_WIN32 #define PLATFORM "win32" #endif diff --git a/plugins/zynaddsubfx/CMakeLists.txt b/plugins/zynaddsubfx/CMakeLists.txt index 9d90c5e38..4c170a987 100644 --- a/plugins/zynaddsubfx/CMakeLists.txt +++ b/plugins/zynaddsubfx/CMakeLists.txt @@ -2,7 +2,7 @@ INCLUDE(BuildPlugin) # definitions for ZynAddSubFX -IF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE OR LMMS_BUILD_OPENBSD) +IF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE OR LMMS_BUILD_OPENBSD OR LMMS_BUILD_FREEBSD) FIND_PACKAGE(X11) INCLUDE_DIRECTORIES(${X11_INCLUDE_DIR}) ADD_DEFINITIONS(-DOS_LINUX) diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index ac1aa2564..38ee5c46d 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -1242,7 +1242,7 @@ void Mixer::fifoWriter::run() disable_denormals(); #if 0 -#ifdef LMMS_BUILD_LINUX +#if defined(LMMS_BUILD_LINUX) || defined(LMMS_BUILD_FREEBSD) #ifdef LMMS_HAVE_SCHED_H cpu_set_t mask; CPU_ZERO( &mask ); diff --git a/src/core/ProjectRenderer.cpp b/src/core/ProjectRenderer.cpp index 95ed1bd8d..edf7a88a3 100644 --- a/src/core/ProjectRenderer.cpp +++ b/src/core/ProjectRenderer.cpp @@ -162,7 +162,7 @@ void ProjectRenderer::run() { MemoryManager::ThreadGuard mmThreadGuard; Q_UNUSED(mmThreadGuard); #if 0 -#ifdef LMMS_BUILD_LINUX +#if defined(LMMS_BUILD_LINUX) || defined(LMMS_BUILD_FREEBSD) #ifdef LMMS_HAVE_SCHED_H cpu_set_t mask; CPU_ZERO( &mask ); diff --git a/src/core/main.cpp b/src/core/main.cpp index cc9cb4f2a..1f400e91a 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -666,7 +666,7 @@ int main( int argc, char * * argv ) // try to set realtime priority -#ifdef LMMS_BUILD_LINUX +#if defined(LMMS_BUILD_LINUX) || defined(LMMS_BUILD_FREEBSD) #ifdef LMMS_HAVE_SCHED_H #ifndef __OpenBSD__ struct sched_param sparam; diff --git a/src/gui/PianoView.cpp b/src/gui/PianoView.cpp index 2a64e72dd..596a2c212 100644 --- a/src/gui/PianoView.cpp +++ b/src/gui/PianoView.cpp @@ -200,7 +200,7 @@ int PianoView::getKeyFromKeyEvent( QKeyEvent * _ke ) case 27: return 31; // ] } #endif -#if defined(LMMS_BUILD_LINUX) || defined(LMMS_BUILD_OPENBSD) +#if defined(LMMS_BUILD_LINUX) || defined(LMMS_BUILD_OPENBSD) || defined(LMMS_BUILD_FREEBSD) switch( k ) { case 52: return 0; // Z = C diff --git a/src/lmmsconfig.h.in b/src/lmmsconfig.h.in index aa4505dbb..7e37be8bd 100644 --- a/src/lmmsconfig.h.in +++ b/src/lmmsconfig.h.in @@ -3,6 +3,7 @@ #cmakedefine LMMS_BUILD_WIN64 #cmakedefine LMMS_BUILD_APPLE #cmakedefine LMMS_BUILD_OPENBSD +#cmakedefine LMMS_BUILD_FREEBSD #cmakedefine LMMS_BUILD_HAIKU #cmakedefine LMMS_HOST_X86 From a9262b9613cc786d797f437184e630c5e2563bab Mon Sep 17 00:00:00 2001 From: Oskar Wallgren Date: Sat, 19 Oct 2019 11:40:06 +0200 Subject: [PATCH 418/445] Fix Organic offset glitch (#5252) --- plugins/organic/organic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/organic/organic.cpp b/plugins/organic/organic.cpp index b062e5b11..d61072aaf 100644 --- a/plugins/organic/organic.cpp +++ b/plugins/organic/organic.cpp @@ -307,7 +307,7 @@ void organicInstrument::playNote( NotePlayHandle * _n, // fxKnob is [0;1] float t = m_fx1Model.value(); - for (int i=0 ; i < frames ; i++) + for (int i=0 ; i < frames + offset ; i++) { _working_buffer[i][0] = waveshape( _working_buffer[i][0], t ) * m_volModel.value() / 100.0f; From 4f11cf1b23c6ba8490c23a863b5b94804b017dc9 Mon Sep 17 00:00:00 2001 From: "Raine M. Ekman" Date: Sat, 19 Oct 2019 22:41:51 +0300 Subject: [PATCH 419/445] Make SampleBuffer adjust its members when resampling Fixes #5218. --- src/core/SampleBuffer.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/core/SampleBuffer.cpp b/src/core/SampleBuffer.cpp index 7f0980fe9..872b8cfac 100644 --- a/src/core/SampleBuffer.cpp +++ b/src/core/SampleBuffer.cpp @@ -382,11 +382,14 @@ void SampleBuffer::directFloatWrite ( sample_t * & _fbuf, f_cnt_t _frames, int _ void SampleBuffer::normalizeSampleRate( const sample_rate_t _src_sr, bool _keep_settings ) { + const sample_rate_t old_rate = m_sampleRate; // do samplerate-conversion to our default-samplerate if( _src_sr != mixerSampleRate() ) { SampleBuffer * resampled = resample( _src_sr, mixerSampleRate() ); + + m_sampleRate = mixerSampleRate(); MM_FREE( m_data ); m_frames = resampled->frames(); m_data = MM_ALLOC( sampleFrame, m_frames ); @@ -401,6 +404,16 @@ void SampleBuffer::normalizeSampleRate( const sample_rate_t _src_sr, m_loopStartFrame = m_startFrame = 0; m_loopEndFrame = m_endFrame = m_frames; } + else if( old_rate != mixerSampleRate() ) + { + auto old_rate_to_new_rate_ratio = static_cast(mixerSampleRate()) / old_rate; + + m_startFrame = qBound(0, f_cnt_t(m_startFrame*old_rate_to_new_rate_ratio), m_frames); + m_endFrame = qBound(m_startFrame, f_cnt_t(m_endFrame*old_rate_to_new_rate_ratio), m_frames); + m_loopStartFrame = qBound(0, f_cnt_t(m_loopStartFrame*old_rate_to_new_rate_ratio), m_frames); + m_loopEndFrame = qBound(m_loopStartFrame, f_cnt_t(m_loopEndFrame*old_rate_to_new_rate_ratio), m_frames); + m_sampleRate = mixerSampleRate(); + } } From dbf5f47149fbb7584bf48ce9e767b9e90ee2df7e Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 21 Oct 2019 09:27:12 +0900 Subject: [PATCH 420/445] Bump version to 1.2.1 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5dab2ab13..d82ace4ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,7 @@ SET(PROJECT_DESCRIPTION "${PROJECT_NAME_UCASE} - Free music production software" SET(PROJECT_COPYRIGHT "2008-${PROJECT_YEAR} ${PROJECT_AUTHOR}") SET(VERSION_MAJOR "1") SET(VERSION_MINOR "2") -SET(VERSION_RELEASE "0") +SET(VERSION_RELEASE "1") SET(VERSION_STAGE "") SET(VERSION_BUILD "0") SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE}") From 13c4f4a99541a75c8ef4e9cc1d1b63064382a11e Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Tue, 22 Oct 2019 11:30:36 +0900 Subject: [PATCH 421/445] Let Travis Mac builds use the Xcode 9.4 image --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b3cb8aa7c..ab2a8ae85 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ matrix: git: depth: false - os: osx - osx_image: xcode8.3 + osx_image: xcode9.4 before_install: # appdmg doesn't work with old Node.js - if [ "$TRAVIS_OS_NAME" = osx ]; then nvm install 10; fi From 3745bfbd7fb7b90f682eecd7cd9c7c264122f95f Mon Sep 17 00:00:00 2001 From: Mark-Agent003 Date: Fri, 25 Oct 2019 02:20:02 -0500 Subject: [PATCH 422/445] Increase File Browser Spacing (#4252) Increase File Browser Spacing --- data/themes/default/style.css | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/data/themes/default/style.css b/data/themes/default/style.css index c5a449128..f95469201 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -9,16 +9,23 @@ QLabel, QTreeWidget, QListWidget, QGroupBox, QMenuBar { QTreeView { outline: none; + font-size: 12px; +} + +QTreeWidget::item { + padding: 1px; } QTreeWidget::item:hover, QTreeWidget::branch:hover { background-color: #3C444E; + padding-left: 0px; } QTreeWidget::item:selected, QTreeWidget::branch:selected { background-color: #17793b; + padding-left: 0px; } QTreeView::branch:has-children:open { From eeaaf6d1da6b8b74b5bf28cf633245c47a365ec6 Mon Sep 17 00:00:00 2001 From: nia <29542929+niacat@users.noreply.github.com> Date: Mon, 28 Oct 2019 00:56:34 +0000 Subject: [PATCH 423/445] Support CMAKE_INSTALL_MANDIR (#5276) --- src/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2fa72a401..ed0deefd1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -202,7 +202,13 @@ ELSE() SET_TARGET_PROPERTIES(lmms PROPERTIES LINK_FLAGS "${LINK_FLAGS} -Wl,-E") ENDIF(NOT LMMS_BUILD_APPLE) - INSTALL(FILES "${CMAKE_BINARY_DIR}/lmms.1.gz" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/man/man1/" + if(CMAKE_INSTALL_MANDIR) + SET(INSTALL_MANDIR ${CMAKE_INSTALL_MANDIR}) + ELSE(CMAKE_INSTALL_MANDIR) + SET(INSTALL_MANDIR ${CMAKE_INSTALL_PREFIX}/share/man) + ENDIF(CMAKE_INSTALL_MANDIR) + INSTALL(FILES "${CMAKE_BINARY_DIR}/lmms.1.gz" + DESTINATION "${INSTALL_MANDIR}/man1/" PERMISSIONS OWNER_READ GROUP_READ WORLD_READ) ENDIF() From 1b45ce5a9856f16afc286b70508fb611b47e080c Mon Sep 17 00:00:00 2001 From: Shmuel H Date: Thu, 17 Oct 2019 15:28:49 +0300 Subject: [PATCH 424/445] CircleCI: Add macOS support. --- .circleci/config.yml | 55 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 981034ffb..c1a8ea7ff 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,6 +12,18 @@ shared: key: ccache-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ .Branch }}-{{ .BuildNum }} paths: - ~/.ccache + restore_homebrew_cache: &restore_homebrew_cache + restore_cache: + keys: + - homebrew-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ .Branch }} + - homebrew-{{ arch }}-{{ .Environment.CIRCLE_JOB }} + - homebrew-{{ arch }} + save_homebrew_cache: &save_homebrew_cache + save_cache: + key: homebrew-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ .Branch }}-{{ .BuildNum }} + paths: + - ~/Library/Caches/Homebrew + - /usr/local/Homebrew ccache_stats: &ccache_stats run: @@ -143,10 +155,53 @@ jobs: - run: name: Shellcheck command: shellcheck $(find "./cmake/" -type f -name '*.sh' -o -name "*.sh.in") + macos: + environment: + <<: *common_environment + macos: + xcode: "9.3.1" + steps: + - checkout + - *init + - *restore_homebrew_cache + - *restore_cache + - run: + name: Install Homebrew dependencies + command: brew update && brew install ccache fftw cmake pkg-config libogg libvorbis lame libsndfile libsamplerate jack sdl libgig libsoundio stk fluid-synth portaudio fltk qt5 carla + - run: + name: Install nodejs dependencies + command: npm install -g appdmg + - run: + name: Building + command: | + mkdir build && cd build + cmake .. -DCMAKE_INSTALL_PREFIX="../target" -DCMAKE_PREFIX_PATH="$(brew --prefix qt5)" $CMAKE_OPTS -DUSE_WERROR=OFF + make + - run: + name: Build tests + command: cd build && make tests + - run: + name: Run tests + command: build/tests/tests + - run: + name: Build DMG + command: | + cd build + make install + make dmg + cp ./lmms-*.dmg /tmp/artifacts/ + - store_artifacts: + path: /tmp/artifacts/ + destination: / + - *save_cache + - *save_homebrew_cache + + workflows: version: 2 build-and-test: jobs: + - macos - mingw32 - mingw64 - linux.gcc From 4a9e9da78c7fcc5e77546ebebcdcc0736a0c359a Mon Sep 17 00:00:00 2001 From: Lukas W Date: Tue, 29 Oct 2019 22:42:20 +0100 Subject: [PATCH 425/445] Issue templates improvements * Ask users to search the tracker first * Ask for the LMMS version in bug reports --- .github/ISSUE_TEMPLATE/bug_report.md | 6 +++++- .github/ISSUE_TEMPLATE/feature_request.md | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 3ca71ce76..2c22146ae 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,6 +7,8 @@ assignees: '' --- +# Please search the issue tracker for existing bug reports before submitting your own. Delete this line to confirm no similar report has been posted yet. + ### Bug Summary #### Steps to reproduce @@ -17,10 +19,12 @@ assignees: '' #### Screenshot +#### LMMS version used + #### Logs

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 EALL?rr2qf` literal 0 HcmV?d00001 diff --git a/cmake/apple/package_apple.json.in b/cmake/apple/package_apple.json.in index 76c487599..1d1147cbf 100644 --- a/cmake/apple/package_apple.json.in +++ b/cmake/apple/package_apple.json.in @@ -1,9 +1,9 @@ { "title": "@MACOSX_BUNDLE_BUNDLE_NAME@ @MACOSX_BUNDLE_LONG_VERSION_STRING@", "background": "@CMAKE_SOURCE_DIR@/cmake/apple/dmg_branding.png", - "icon-size": 72, + "icon-size": 128, "contents": [ - { "x": 460, "y": 260, "type": "link", "path": "/Applications" }, - { "x": 220, "y": 260, "type": "file", "path": "@CMAKE_BINARY_DIR@/@MACOSX_BUNDLE_BUNDLE_NAME@.app" } + { "x": 139, "y": 200, "type": "file", "path": "@CMAKE_BINARY_DIR@/@MACOSX_BUNDLE_BUNDLE_NAME@.app" }, + { "x": 568, "y": 200, "type": "link", "path": "/Applications" } ] } From bfa8a4bc8cbd80786c7dc374ecd4cf0eb726c790 Mon Sep 17 00:00:00 2001 From: Rebecca DeField Date: Sat, 8 Jun 2019 02:57:56 -0700 Subject: [PATCH 330/445] fix color profile error (#5019) --- data/themes/default/splash.png | Bin 110016 -> 112040 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/data/themes/default/splash.png b/data/themes/default/splash.png index bca810bbada26dbb66ce10223719266dbb530298..74f9fdef48c184532b0bdcbc6cb6a36b9d113771 100644 GIT binary patch literal 112040 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 TMdh(J2>9qcHGEQ~4vG3dU@Q{+ literal 110016 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≻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