hydrogen 1.2.6
LadspaFXProperties.cpp
Go to the documentation of this file.
1/*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 * Copyright(c) 2008-2025 The hydrogen development team [hydrogen-devel@lists.sourceforge.net]
5 *
6 * http://www.hydrogen-music.org
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY, without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see https://www.gnu.org/licenses
20 *
21 */
22
23#include <core/Hydrogen.h>
25#include <core/Basics/Song.h>
26#include <core/FX/Effects.h>
28#include <core/IO/AudioOutput.h>
29
30
31#include "LadspaFXProperties.h"
32#include "HydrogenApp.h"
33#include "LadspaFXSelector.h"
34#include "Skin.h"
35#include "Widgets/Fader.h"
36#include "Widgets/LCDDisplay.h"
37
38#include "Mixer/Mixer.h"
39#include "Mixer/MixerLine.h"
40
41using namespace H2Core;
42
43LadspaFXProperties::LadspaFXProperties(QWidget* parent, uint nLadspaFX)
44 : QWidget( parent )
45 , Object()
46{
47//
48
49 m_nLadspaFX = nLadspaFX;
50
51 resize( 500, 200 );
52 setMinimumSize( width(), height() );
53 setFixedHeight( height() );
54
55 QHBoxLayout *hbox = new QHBoxLayout();
56 hbox->setSpacing( 0 );
57 hbox->setContentsMargins( 0, 0, 0, 0 );
58 setLayout( hbox );
59
60
61 // Background image
62 QPixmap background;
63 bool ok = background.load( Skin::getImagePath() + "/mixerPanel/mixer_background.png" );
64 if( !ok ){
65 ERRORLOG( "Error loading pixmap" );
66 }
67
68
69 m_pScrollArea = new QScrollArea( nullptr );
70 hbox->addWidget( m_pScrollArea );
71
72 m_pScrollArea->move( 0, 0 );
73 m_pScrollArea->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
74 m_pScrollArea->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
75 m_pScrollArea->resize( width(), height() );
76
77 m_pFrame = new QFrame( this );
78 m_pFrame->resize( width(), height() );
79
80 m_pScrollArea->setWidget( m_pFrame );
81
82 m_pNameLbl = new QLabel(this);
83 m_pNameLbl->move( 10, 10 );
84 m_pNameLbl->resize( 270, 24 );
85
86 QFont boldFont;
87 boldFont.setBold(true);
88 m_pNameLbl->setFont( boldFont );
89
90 m_pSelectFXBtn = new QPushButton( tr("Select FX"), this);
91 m_pSelectFXBtn->move( 170, 10 );
92 m_pSelectFXBtn->resize( 100, 24 );
93 connect( m_pSelectFXBtn, SIGNAL(clicked()), this, SLOT(selectFXBtnClicked()) );
94
95 m_pRemoveFXBtn = new QPushButton( tr("Remove FX"), this);
96 m_pRemoveFXBtn->move( 280, 10 );
97 m_pRemoveFXBtn->resize( 100, 24 );
98 connect( m_pRemoveFXBtn, SIGNAL(clicked()), this, SLOT(removeFXBtnClicked()) );
99
100
101 m_pActivateBtn = new QPushButton( tr("Activate"), this);
102 m_pActivateBtn->move( 390, 10 );
103 m_pActivateBtn->resize( 100, 24 );
104 connect( m_pActivateBtn, SIGNAL(clicked()), this, SLOT(activateBtnClicked()) );
105
106
107 m_pTimer = new QTimer( this );
108 connect(m_pTimer, SIGNAL( timeout() ), this, SLOT( updateOutputControls() ) );
109}
110
111
113{
114// INFOLOG( "DESTROY" );
115}
116
117
118
120{
122}
123
124
125
126void LadspaFXProperties::closeEvent( QCloseEvent *ev )
127{
128 ev->accept();
129}
130
131
133{
134 Fader* pFader = dynamic_cast<Fader*>( pRef );
135 pFader->setPeak_L( pFader->getValue() );
136 pFader->setPeak_R( pFader->getValue() );
137
138#ifdef H2CORE_HAVE_LADSPA
140
141 for ( uint i = 0; i < m_pInputControlFaders.size(); i++ ) {
142 if (pFader == m_pInputControlFaders[ i ] ) {
143 LadspaControlPort *pControl = pFX->inputControlPorts[ i ];
144
145 pControl->fControlValue = pFader->getValue();
146 //float fInterval = pControl->fUpperBound - pControl->fLowerBound;
147 //pControl->fControlValue = pControl->fLowerBound + fValue * fInterval;
148
149 QString sValue;
150 if (pControl->fControlValue < 1.0 ) {
151 sValue = QString("%1").arg( pControl->fControlValue, 0, 'f', 2 );
152 }
153 else if ( pControl->fControlValue < 100.0 ) {
154 sValue = QString("%1").arg( pControl->fControlValue, 0, 'f', 1 );
155 }
156 else {
157 sValue = QString("%1").arg( pControl->fControlValue, 0, 'f', 0 );
158 }
159 m_pInputControlLabel[ i ]->setText( sValue );
160 }
161 }
163#endif
164}
165
166
167
169{
170#ifdef H2CORE_HAVE_LADSPA
171 INFOLOG( "*** [updateControls] ***" );
172 m_pTimer->stop();
173
175
176 // svuoto i vettori..
177 if ( m_pInputControlNames.size() != 0 ) {
178 for (uint i = 0; i < m_pInputControlNames.size(); i++) {
179 delete m_pInputControlNames[ i ];
180 }
181 m_pInputControlNames.clear();
182 }
183 if ( m_pInputControlLabel.size() != 0 ) {
184 for (uint i = 0; i < m_pInputControlLabel.size(); i++) {
185 delete m_pInputControlLabel[ i ];
186 }
187 m_pInputControlLabel.clear();
188 }
189 if ( m_pInputControlFaders.size() != 0 ) {
190 for (uint i = 0; i < m_pInputControlFaders.size(); i++) {
191 delete m_pInputControlFaders[ i ];
192 }
193 m_pInputControlFaders.clear();
194 }
195
196 if ( m_pOutputControlFaders.size() != 0 ) {
197 for (uint i = 0; i < m_pOutputControlFaders.size(); i++) {
198 delete m_pOutputControlFaders[ i ];
199 }
201 }
202 if ( m_pOutputControlNames.size() != 0 ) {
203 for (uint i = 0; i < m_pOutputControlNames.size(); i++) {
204 delete m_pOutputControlNames[ i ];
205 }
206 m_pOutputControlNames.clear();
207 }
208
209 if (pFX) {
210 QString sPluginName = pFX->getPluginLabel();
211 setWindowTitle( tr( "[%1] LADSPA FX Properties" ).arg( sPluginName ) );
212
213 int nControlsFrameWidth = 10 + 45 * (pFX->inputControlPorts.size() + pFX->outputControlPorts.size()) + 10 + 45;
214 if ( nControlsFrameWidth < width() ) {
215 nControlsFrameWidth = width();
216 }
217 m_pFrame->resize( nControlsFrameWidth, height() );
218
219 m_pActivateBtn->setEnabled(true);
220 if (pFX->isEnabled()) {
221 m_pActivateBtn->setText( tr("Deactivate") );
222 }
223 else {
224 m_pActivateBtn->setText( tr("Activate") );
225 }
226
227 QString mixerline_text_path = Skin::getImagePath() + "/mixerPanel/mixer_background.png";
228 QPixmap textBackground;
229 if( textBackground.load( mixerline_text_path ) == false ){
230 ERRORLOG( "Error loading pixmap" );
231 }
232
233 // input controls
234 uint nInputControl_X = 0;
235 for (uint i = 0; i < pFX->inputControlPorts.size(); i++) {
236 LadspaControlPort *pControlPort = pFX->inputControlPorts[ i ];
237
238 nInputControl_X = 10 + 45 * i;
239
240 if (pControlPort->isToggle){ // toggle button
241 WARNINGLOG( "[updateControls] LADSPA toggle controls not implemented yet");
242 }
243
244 // peak volume label
245 QString sValue;
246 if (pControlPort->fControlValue < 1.0 ) {
247 sValue = QString("%1").arg( pControlPort->fControlValue, 0, 'f', 2);
248 }
249 else if ( pControlPort->fControlValue < 100.0 ) {
250 sValue = QString("%1").arg( pControlPort->fControlValue, 0, 'f', 1);
251 }
252 else {
253 sValue = QString("%1").arg( pControlPort->fControlValue, 0, 'f', 0);
254 }
255
256 LCDDisplay *pLCD = new LCDDisplay( m_pFrame, QSize( 38, 18 ), false, false );
257 pLCD->move( nInputControl_X, 40 );
258 pLCD->setText( sValue );
259 pLCD->show();
260 QPalette lcdPalette;
261 lcdPalette.setColor( QPalette::Window, QColor( 58, 62, 72 ) );
262 pLCD->setPalette( lcdPalette );
263
264 m_pInputControlLabel.push_back( pLCD );
265
267 pName->move( nInputControl_X, 60 );
268 pName->show();
269 pName->setText( pControlPort->sName );
270 m_pInputControlNames.push_back( pName );
271 pName->setToolTip( pName->text() );
272
273
274 // fader
275 Fader *pFader = new Fader( m_pFrame, Fader::Type::Normal, tr( "Input control param. value" ), pControlPort->m_bIsInteger, false, pControlPort->fLowerBound, pControlPort->fUpperBound );
276 connect( pFader, SIGNAL( valueChanged( WidgetWithInput* ) ), this, SLOT( faderChanged( WidgetWithInput* ) ) );
277 m_pInputControlFaders.push_back( pFader );
278 pFader->move( nInputControl_X + 20, 60 );
279 pFader->show();
280 pFader->setMaxPeak( pControlPort->fUpperBound );
281 pFader->setMinPeak( pControlPort->fLowerBound );
282 pFader->setValue( pControlPort->fControlValue );
283 pFader->setPeak_L( pControlPort->fControlValue );
284 pFader->setPeak_R( pControlPort->fControlValue );
285 pFader->setDefaultValue( pControlPort->fDefaultValue );
286
287 faderChanged( pFader );
288
289 m_pNameLbl->setText( pFX->getPluginName() );
290 }
291
292 nInputControl_X += 45;
293 for (uint i = 0; i < pFX->outputControlPorts.size(); i++) {
294 LadspaControlPort *pControl = pFX->outputControlPorts[ i ];
295
296 uint xPos = nInputControl_X + 10 + 45 * i;
297
299 pName->move( xPos, 60 );
300 pName->show();
301 pName->setText( pControl->sName );
302 m_pInputControlNames.push_back( pName );
303 pName->setToolTip( pName->text() );
304
305 // fader
306 Fader *pFader = new Fader( m_pFrame, Fader::Type::Normal, tr( "Output control param. value" ), true, true, pControl->fLowerBound, pControl->fUpperBound );
307 pFader->move( xPos + 20, 60 );
308 //float fInterval = pControl->fUpperBound - pControl->fLowerBound;
309 //float fValue = pControl->fControlValue / fInterval;
310 pFader->show();
311 pFader->setMaxPeak( pControl->fUpperBound );
312 pFader->setMinPeak( pControl->fLowerBound );
313 pFader->setValue( pControl->fControlValue );
314 pFader->setPeak_L( pControl->fControlValue );
315 pFader->setPeak_R( pControl->fControlValue );
316 pFader->setDefaultValue( pControl->fDefaultValue );
317
318 m_pOutputControlFaders.push_back( pFader );
319 }
320 }
321 else {
322 INFOLOG( "NULL PLUGIN" );
323 setWindowTitle( tr( "LADSPA FX %1 Properties" ).arg( m_nLadspaFX) );
324 m_pNameLbl->setText( tr("No plugin") );
325 m_pActivateBtn->setEnabled(false);
326 }
327
328 m_pTimer->start(100);
329#endif
330}
331
332
333
335{
336#ifdef H2CORE_HAVE_LADSPA
337 auto pHydrogen = Hydrogen::get_instance();
338 auto pAudioDriver = pHydrogen->getAudioOutput();
339 if ( pAudioDriver == nullptr ) {
340 ERRORLOG( "AudioDriver is not ready!" );
341 return;
342 }
343
344 LadspaFXSelector fxSelector(m_nLadspaFX);
345 if (fxSelector.exec() == QDialog::Accepted) {
346 QString sSelectedFX = fxSelector.getSelectedFX();
347 if ( !sSelectedFX.isEmpty() ) {
348 LadspaFX *pFX = nullptr;
349
350 std::vector<H2Core::LadspaFXInfo*> pluginList = Effects::get_instance()->getPluginList();
351 for (uint i = 0; i < pluginList.size(); i++) {
352 H2Core::LadspaFXInfo *pFXInfo = pluginList[i];
353 if (pFXInfo->m_sName == sSelectedFX ) {
354 int nSampleRate = pAudioDriver->getSampleRate();
355 pFX = LadspaFX::load( pFXInfo->m_sFilename, pFXInfo->m_sLabel, nSampleRate );
356 pFX->setEnabled( true );
357 break;
358 }
359 }
361
362 pHydrogen->restartLadspaFX();
364 }
365 else { // no plugin selected
366 INFOLOG( "no plugin selected" );
367 }
368 }
369#endif
370}
371
372
374{
375#ifdef H2CORE_HAVE_LADSPA
380#endif
381}
382
383
385{
386#ifdef H2CORE_HAVE_LADSPA
387
389
390 if (pFX) {
391 m_pActivateBtn->setEnabled(true);
392 if (pFX->isEnabled()) {
393 m_pActivateBtn->setText( tr("Deactivate") );
394 }
395 else {
396 m_pActivateBtn->setText( tr("Activate") );
397 }
398
399 for (uint i = 0; i < pFX->outputControlPorts.size(); i++) {
400 LadspaControlPort *pControl = pFX->outputControlPorts[i];
401
402 std::vector<Fader*>::iterator it = m_pOutputControlFaders.begin() + i;
403 if (it != m_pOutputControlFaders.end() ) {
404 Fader *pFader = *it;
405 if (pFader == nullptr) {
406 ERRORLOG( "[updateOutputControls] pFader = NULL" );
407 continue;
408 }
409
410 float fInterval = pControl->fUpperBound - pControl->fLowerBound;
411 float fValue = pControl->fControlValue / fInterval;
412
413 if (fValue < 0) fValue = -fValue;
414
415 pFader->setPeak_L( fValue );
416 pFader->setPeak_R( fValue );
417 }
418 }
419 }
420 else {
421 m_pActivateBtn->setEnabled(false);
422 }
423#endif
424}
425
426
427
428
430{
431#ifdef H2CORE_HAVE_LADSPA
433 if (pFX) {
435 pFX->setEnabled( !pFX->isEnabled() );
437 }
438#endif
439}
#define RIGHT_HERE
Macro intended to be used for the logging of the locking of the H2Core::AudioEngine.
Definition AudioEngine.h:61
#define INFOLOG(x)
Definition Object.h:240
#define WARNINGLOG(x)
Definition Object.h:241
#define ERRORLOG(x)
Definition Object.h:242
Custom fader widget.
Definition Fader.h:44
void setPeak_R(float peak)
Definition Fader.cpp:346
void setMaxPeak(float fMax)
Definition Fader.cpp:371
void setMinPeak(float fMin)
Definition Fader.cpp:403
void setPeak_L(float peak)
Definition Fader.cpp:321
void unlock()
Mutex unlocking of the AudioEngine.
void lock(const char *file, unsigned int line, const char *function)
Mutex locking of the AudioEngine.
static Effects * get_instance()
Returns a pointer to the current Effects singleton stored in __instance.
Definition Effects.h:54
std::vector< LadspaFXInfo * > getPluginList()
Loads only usable plugins.
Definition Effects.cpp:131
void setLadspaFX(LadspaFX *pFX, int nFX)
Definition Effects.cpp:99
LadspaFX * getLadspaFX(int nFX) const
Definition Effects.cpp:91
void restartLadspaFX()
Definition Hydrogen.cpp:890
static Hydrogen * get_instance()
Returns the current Hydrogen instance __instance.
Definition Hydrogen.h:84
AudioEngine * getAudioEngine() const
Definition Hydrogen.h:663
void setIsModified(bool bIsModified)
Wrapper around Song::setIsModified() that checks whether a song is set.
LADSPA_Data fDefaultValue
Definition LadspaFX.h:105
LADSPA_Data fControlValue
Definition LadspaFX.h:106
QString m_sFilename
plugin filename
Definition LadspaFX.h:46
std::vector< LadspaControlPort * > inputControlPorts
Definition LadspaFX.h:131
void setEnabled(bool bEnabled)
Definition LadspaFx.cpp:201
const QString & getPluginName() const
Definition LadspaFX.h:146
const QString & getPluginLabel() const
Definition LadspaFX.h:142
std::vector< LadspaControlPort * > outputControlPorts
Definition LadspaFX.h:132
bool isEnabled() const
Definition LadspaFX.h:155
static LadspaFX * load(const QString &sLibraryPath, const QString &sPluginLabel, long nSampleRate)
Definition LadspaFx.cpp:211
void setText(QString text)
Non-interactive display used for both numerical values and the status display.
Definition LCDDisplay.h:40
LadspaFXProperties(QWidget *parent, uint nLadspaFX)
std::vector< Fader * > m_pOutputControlFaders
std::vector< Fader * > m_pInputControlFaders
QPushButton * m_pActivateBtn
QScrollArea * m_pScrollArea
void faderChanged(WidgetWithInput *ref)
virtual void closeEvent(QCloseEvent *ev) override
std::vector< InstrumentNameWidget * > m_pInputControlNames
QPushButton * m_pRemoveFXBtn
virtual void showEvent(QShowEvent *ev) override
std::vector< InstrumentNameWidget * > m_pOutputControlNames
QPushButton * m_pSelectFXBtn
std::vector< LCDDisplay * > m_pInputControlLabel
static QString getImagePath()
Definition Skin.h:36
Base class for active user input widget, which are not based on a high-level Qt widget.
virtual void setValue(float fValue, bool bTriggeredByUserInteraction=false)
void setDefaultValue(float fDefaultValue)
float getValue() const