hydrogen 1.2.3
PlayerControl.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-2024 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
20https://www.gnu.org/licenses
21 *
22 */
23
24
25#include "Skin.h"
26#include "CommonStrings.h"
27#include "PlayerControl.h"
28#include "InstrumentRack.h"
29#include "HydrogenApp.h"
30
32#include "Widgets/LCDDisplay.h"
33#include "Widgets/LCDSpinBox.h"
34#include "Widgets/LED.h"
35#include "Widgets/Button.h"
39
40#include "Mixer/Mixer.h"
44
45#include <core/Hydrogen.h>
46#include <core/Basics/Song.h>
50#include <core/EventQueue.h>
51using namespace H2Core;
52
53
54//beatconter global
56// ~ beatcounter
57
59 : QLabel(parent)
62{
63
65
66 setObjectName( "PlayerControl" );
68
70 auto pSong = m_pHydrogen->getSong();
71 auto pCommonStrings = HydrogenApp::get_instance()->getCommonStrings();
72
73 // Background image
74 setPixmap( QPixmap( Skin::getImagePath() + "/playerControlPanel/background.png" ) );
75 setScaledContents( true );
76
77 QHBoxLayout *hbox = new QHBoxLayout();
78 hbox->setSpacing( 0 );
79 hbox->setMargin( 0 );
80 setLayout( hbox );
81
82// CONTROLS
83 PixmapWidget *pControlsPanel = new PixmapWidget( nullptr );
84 pControlsPanel->setFixedSize( 344, 43 );
85 pControlsPanel->setPixmap( "/playerControlPanel/background_Control.png" );
86 pControlsPanel->setObjectName( "ControlsPanel" );
87 hbox->addWidget( pControlsPanel );
88
89 m_pTimeDisplay = new LCDDisplay( pControlsPanel, QSize( 146, 22 ), true, false );
90 m_pTimeDisplay->move( 13, 7 );
91 m_pTimeDisplay->setAlignment( Qt::AlignRight );
92 m_pTimeDisplay->setText( "00:00:00:000" );
93 m_pTimeDisplay->setStyleSheet( m_pTimeDisplay->styleSheet().
94 append(" QLineEdit { font-size: 19px; }" ) );
95
96 m_pTimeHoursLbl = new ClickableLabel( pControlsPanel, QSize( 33, 9 ),
97 pCommonStrings->getTimeHoursLabel() );
98 m_pTimeHoursLbl->move( 22, 30 );
99 m_pTimeMinutesLbl = new ClickableLabel( pControlsPanel, QSize( 33, 9 ),
100 pCommonStrings->getTimeMinutesLabel() );
101 m_pTimeMinutesLbl->move( 53, 30 );
102 m_pTimeSecondsLbl = new ClickableLabel( pControlsPanel, QSize( 33, 9 ),
103 pCommonStrings->getTimeSecondsLabel() );
104 m_pTimeSecondsLbl->move( 83, 30 );
105 m_pTimeMilliSecondsLbl = new ClickableLabel( pControlsPanel, QSize( 34, 9 ),
106 pCommonStrings->getTimeMilliSecondsLabel() );
107 m_pTimeMilliSecondsLbl->move( 119, 30 );
108
109 // Rewind button
110 m_pRwdBtn = new Button( pControlsPanel, QSize( 25, 19 ), Button::Type::Push,
111 "rewind.svg", "", false, QSize( 13, 13 ), tr("Rewind") );
112 m_pRwdBtn->setObjectName( "PlayerControlRewindButton" );
113 m_pRwdBtn->move( 166, 15 );
114 connect(m_pRwdBtn, SIGNAL( clicked() ), this, SLOT( rewindBtnClicked() ));
115 std::shared_ptr<Action> pAction = std::make_shared<Action>("<<_PREVIOUS_BAR");
116 m_pRwdBtn->setAction( pAction );
117
118 // Record button
119 m_pRecBtn = new Button( pControlsPanel, QSize( 25, 19 ), Button::Type::Toggle,
120 "record.svg", "", false, QSize( 11, 11 ), tr("Record"), true );
121 m_pRecBtn->setObjectName( "PlayerControlRecordButton" );
122 m_pRecBtn->move( 193, 15 );
123 m_pRecBtn->setChecked(false);
124 m_pRecBtn->setHidden(false);
125 connect(m_pRecBtn, SIGNAL( clicked() ), this, SLOT( recBtnClicked() ));
126 pAction = std::make_shared<Action>("RECORD_READY");
127 m_pRecBtn->setAction( pAction );
128
129 // Play button
130 m_pPlayBtn = new Button( pControlsPanel, QSize( 30, 21 ), Button::Type::Toggle,
131 "play_pause.svg", "", false, QSize( 30, 21 ), tr("Play/ Pause") );
132 m_pPlayBtn->setObjectName( "PlayerControlPlayButton" );
133 m_pPlayBtn->move( 220, 15 );
134 m_pPlayBtn->setChecked(false);
135 connect(m_pPlayBtn, SIGNAL( clicked() ), this, SLOT( playBtnClicked() ));
136 pAction = std::make_shared<Action>("PLAY/PAUSE_TOGGLE");
137 m_pPlayBtn->setAction( pAction );
138
139 // Stop button
140 m_pStopBtn = new Button( pControlsPanel, QSize( 25, 19 ), Button::Type::Push,
141 "stop.svg", "", false, QSize( 11, 11 ), tr("Stop") );
142 m_pStopBtn->setObjectName( "PlayerControlStopButton" );
143 m_pStopBtn->move( 252, 15 );
144 connect(m_pStopBtn, SIGNAL( clicked() ), this, SLOT( stopBtnClicked() ));
145 pAction = std::make_shared<Action>("STOP");
146 m_pStopBtn->setAction( pAction );
147
148 // Fast forward button
149 m_pFfwdBtn = new Button( pControlsPanel, QSize( 25, 19 ), Button::Type::Push,
150 "fast_forward.svg", "", false, QSize( 13, 13 ), tr("Fast Forward") );
151 m_pFfwdBtn->setObjectName( "PlayerControlForwardButton" );
152 m_pFfwdBtn->move( 279, 15 );
153 connect(m_pFfwdBtn, SIGNAL( clicked() ), this, SLOT( fastForwardBtnClicked() ));
154 pAction = std::make_shared<Action>(">>_NEXT_BAR");
155 m_pFfwdBtn->setAction( pAction );
156
157 // Loop song button button
158 m_pSongLoopBtn = new Button( pControlsPanel, QSize( 25, 19 ),
159 Button::Type::Toggle, "loop.svg", "", false,
160 QSize( 17, 13 ), tr("Loop song"),
161 false, true );
162 m_pSongLoopBtn->setObjectName( "PlayerControlLoopButton" );
163 m_pSongLoopBtn->move( 308, 15);
164 connect( m_pSongLoopBtn, &QPushButton::clicked,
165 [=]( bool bChecked ) { Hydrogen::get_instance()->getCoreActionController()->
166 activateLoopMode( bChecked );
167 });
168 if ( pSong->getLoopMode() == Song::LoopMode::Enabled ) {
169 m_pSongLoopBtn->setChecked( true );
170 }
171
172 // Live mode button
173 m_pPatternModeLED = new LED( pControlsPanel, QSize( 11, 9 ) );
174 m_pPatternModeLED->move( 179, 4 );
175 m_pPatternModeLED->setActivated( true );
176 m_pPatternModeBtn = new Button( pControlsPanel, QSize( 59, 11 ),
178 pCommonStrings->getPatternModeButton(),
179 false, QSize(), tr("Pattern Mode"),
180 false, true );
181 m_pPatternModeBtn->setObjectName( "PlayerControlPatternModeButton" );
182 m_pPatternModeBtn->move( 190, 3 );
183 m_pPatternModeBtn->setChecked(true);
184 connect( m_pPatternModeBtn, &QPushButton::clicked,
185 [=]() { activateSongMode( false ); } );
186
187 // Song mode button
188 m_pSongModeLED = new LED( pControlsPanel, QSize( 11, 9 ) );
189 m_pSongModeLED->move( 252, 4 );
190 m_pSongModeBtn = new Button( pControlsPanel, QSize( 59, 11 ),
192 pCommonStrings->getSongModeButton(),
193 false, QSize(), tr("Song Mode"),
194 false, true );
195 m_pSongModeBtn->setObjectName( "PlayerControlSongModeButton" );
196 m_pSongModeBtn->move( 263, 3 );
197 connect( m_pSongModeBtn, &QPushButton::clicked,
198 [=]() { activateSongMode( true ); } );
199
200 if ( m_pHydrogen->getMode() == Song::Mode::Song ) {
201 m_pSongModeBtn->setChecked( true );
202 m_pPatternModeBtn->setChecked( false );
203 m_pSongModeLED->setActivated( true );
204 m_pPatternModeLED->setActivated( false );
205 } else {
206 m_pSongModeBtn->setChecked( false );
207 m_pPatternModeBtn->setChecked( true );
208 m_pSongModeLED->setActivated( false );
209 m_pPatternModeLED->setActivated( true );
210
211 m_pSongLoopBtn->setIsActive( false );
212 }
213
214
215
216// ~ CONTROLS
217
218// BC on off
219 QWidget *pControlsBBTBConoffPanel = new QWidget( nullptr );
220 pControlsBBTBConoffPanel->setFixedSize( 15, 43 );
221 pControlsBBTBConoffPanel->setObjectName( "BeatCounterOnOff" );
222 hbox->addWidget( pControlsBBTBConoffPanel );
223
224 m_sBCOnOffBtnToolTip = tr("Toggle the BeatCounter Panel");
225 m_sBCOnOffBtnTimelineToolTip = tr( "Please deactivate the Timeline first in order to use the BeatCounter" );
226 m_sBCOnOffBtnJackTimebaseToolTip = tr( "In the presence of an external JACK Timebase master the BeatCounter can not be used" );
227 m_pBCOnOffBtn = new Button( pControlsBBTBConoffPanel, QSize( 13, 42 ),
229 pCommonStrings->getBeatCounterButton(), false,
230 QSize(), m_sBCOnOffBtnToolTip,
231 false, true );
232 m_pBCOnOffBtn->move(0, 0);
233 if ( pPref->m_bbc == Preferences::BC_ON ) {
235 } else {
237 }
238 if ( m_pHydrogen->getTempoSource() != H2Core::Hydrogen::Tempo::Song ) {
239 m_pBCOnOffBtn->setChecked( false );
240 m_pBCOnOffBtn->setIsActive( false );
241 } else {
243 }
245
246 connect(m_pBCOnOffBtn, SIGNAL( clicked(bool) ), this, SLOT( activateBeatCounter(bool) ));
247 pAction = std::make_shared<Action>("BEATCOUNTER");
248 m_pBCOnOffBtn->setAction( pAction );
249// ~ BC on off
250
251//beatcounter
252 m_pControlsBCPanel = new PixmapWidget( nullptr );
253 m_pControlsBCPanel->setFixedSize( 86, 43 );
254 m_pControlsBCPanel->setPixmap( "/playerControlPanel/beatConter_BG.png" );
255 m_pControlsBCPanel->setObjectName( "BeatCounter" );
256 hbox->addWidget( m_pControlsBCPanel );
257
258
259 m_pBCDisplayZ = new QLabel( m_pControlsBCPanel );
260 m_pBCDisplayZ->resize( QSize( 23, 13 ) );
261 m_pBCDisplayZ->move( 45, 8 );
262 m_pBCDisplayZ->setText( "--" );
263
264 QLabel* pLabelBC1 = new QLabel( m_pControlsBCPanel );
265 pLabelBC1->resize( QSize( 9, 11 ) );
266 pLabelBC1->move( 25, 9 );
267 pLabelBC1->setText( "1" );
268 QLabel* pLabelBC2 = new QLabel( m_pControlsBCPanel );
269 pLabelBC2->resize( QSize( 9, 3 ) );
270 pLabelBC2->move( 25, 20 );
271 pLabelBC2->setText( "—" );
272
273 m_pBCDisplayT = new QLabel( m_pControlsBCPanel );
274 m_pBCDisplayT->resize( QSize( 9, 11 ) );
275 m_pBCDisplayT->move( 25, 25 );
276 m_pBCDisplayT->setText( "4" );
277
278 m_pBCDisplayB = new QLabel( m_pControlsBCPanel );
279 m_pBCDisplayB->resize( QSize( 23, 11 ) );
280 m_pBCDisplayB->move( 45, 25 );
281 m_pBCDisplayB->setText( "04" );
282
283 m_pBCTUpBtn = new Button( m_pControlsBCPanel, QSize( 19, 12 ),
284 Button::Type::Push, "plus.svg", "", false,
285 QSize( 8, 8 ), "", false, true );
286 m_pBCTUpBtn->move( 2, 3 );
287 connect( m_pBCTUpBtn, SIGNAL( clicked() ), this, SLOT( bctUpButtonClicked() ) );
288
289 m_pBCTDownBtn = new Button( m_pControlsBCPanel, QSize( 19, 12 ),
290 Button::Type::Push, "minus.svg", "", false,
291 QSize( 8, 8 ), "", false, true );
292 m_pBCTDownBtn->move( 2, 14 );
293 connect( m_pBCTDownBtn, SIGNAL( clicked() ), this, SLOT( bctDownButtonClicked() ) );
294
295 m_pBCBUpBtn = new Button( m_pControlsBCPanel, QSize( 19, 12 ),
296 Button::Type::Push, "plus.svg", "", false,
297 QSize( 8, 8 ), "", false, true );
298 m_pBCBUpBtn->move( 64, 3 );
299 connect( m_pBCBUpBtn, SIGNAL( clicked() ), this, SLOT( bcbUpButtonClicked() ) );
300
301 m_pBCBDownBtn = new Button( m_pControlsBCPanel, QSize( 19, 12 ),
302 Button::Type::Push, "minus.svg", "", false,
303 QSize( 8, 8 ), "", false, true );
304 m_pBCBDownBtn->move( 64, 14 );
305 connect( m_pBCBDownBtn, SIGNAL( clicked() ), this, SLOT( bcbDownButtonClicked() ) );
306
307 m_pBCSetPlayBtn = new Button( m_pControlsBCPanel, QSize( 19, 15 ),
309 pCommonStrings->getBeatCounterSetPlayButtonOff(),
310 false, QSize(),
311 tr("Set BPM / Set BPM and play"),
312 false, true );
313 m_pBCSetPlayBtn->setObjectName( "BeatCounterSetPlayButton" );
314 m_pBCSetPlayBtn->move( 64, 25 );
315 connect(m_pBCSetPlayBtn, SIGNAL( clicked() ), this, SLOT( bcSetPlayBtnClicked() ));
316// ~ beatcounter
317
318
319// BPM
320 m_sLCDBPMSpinboxToolTip = tr("Alter the Playback Speed");
321 m_sLCDBPMSpinboxTimelineToolTip = tr( "While the Timeline is active this widget is in read-only mode and just displays the tempo set using the current Timeline position" );
322 m_sLCDBPMSpinboxJackTimebaseToolTip = tr( "In the presence of an external JACK Timebase master this widget just displays the tempo broadcasted by JACK" );
323
324 PixmapWidget *pBPMPanel = new PixmapWidget( nullptr );
325 pBPMPanel->setFixedSize( 145, 43 );
326 pBPMPanel->setPixmap( "/playerControlPanel/background_BPM.png" );
327 pBPMPanel->setObjectName( "BPM" );
328 hbox->addWidget( pBPMPanel );
329 m_pBPMLbl = new ClickableLabel( pBPMPanel, QSize( 26, 10 ),
330 pCommonStrings->getBPMLabel(), ClickableLabel::Color::Dark );
331 m_pBPMLbl->move( 36, 31 );
332
333 // LCD BPM SpinBox
334 m_pLCDBPMSpinbox = new LCDSpinBox( pBPMPanel, QSize( 95, 30), LCDSpinBox::Type::Double,
335 static_cast<double>( MIN_BPM ),
336 static_cast<double>( MAX_BPM ), true );
337 m_pLCDBPMSpinbox->move( 36, 1 );
338 m_pLCDBPMSpinbox->setStyleSheet( m_pLCDBPMSpinbox->styleSheet().
339 append( " QAbstractSpinBox {font-size: 16px;}" ) );
340 connect( m_pLCDBPMSpinbox, SIGNAL( valueChanged( double ) ),
341 this, SLOT( bpmChanged( double ) ) );
342 // initialize BPM widget
343 m_pLCDBPMSpinbox->setIsActive( m_pHydrogen->getTempoSource() ==
345 m_pLCDBPMSpinbox->setValue( m_pHydrogen->getAudioEngine()->getTransportPosition()->getBpm() );
347
348 m_pRubberBPMChange = new Button( pBPMPanel, QSize( 13, 42 ),
350 pCommonStrings->getRubberbandButton(),
351 false, QSize(),
352 tr("Recalculate Rubberband modified samples if bpm will change"),
353 false, true );
354 m_pRubberBPMChange->setObjectName( "PlayerControlRubberbandButton" );
355 m_pRubberBPMChange->move( 131, 0 );
356 m_pRubberBPMChange->setChecked( pPref->getRubberBandBatchMode());
357 connect( m_pRubberBPMChange, SIGNAL( clicked() ), this, SLOT( rubberbandButtonToggle() ) );
358 QString program = pPref->m_rubberBandCLIexecutable;
359 //test the path. if test fails, no button
360 if ( QFile( program ).exists() == false) {
361 m_pRubberBPMChange->hide();
362 }
363
364 m_pMetronomeLED = new MetronomeLED( pBPMPanel, QSize( 22, 7 ) );
365 m_pMetronomeLED->move( 7, 32 );
366
367 m_pMetronomeBtn = new Button( pBPMPanel, QSize( 24, 28 ),
368 Button::Type::Toggle, "metronome.svg", "",
369 false, QSize( 20, 20 ),
370 tr("Switch metronome on/off"),
371 false, true );
372 m_pMetronomeBtn->setObjectName( "MetronomeButton" );
373 m_pMetronomeBtn->move( 6, 2 );
374 connect( m_pMetronomeBtn, SIGNAL( clicked() ), this, SLOT( metronomeButtonClicked() ) );
375 pAction = std::make_shared<Action>("TOGGLE_METRONOME");
376 m_pMetronomeBtn->setAction( pAction );
377 m_pMetronomeBtn->setChecked( pPref->m_bUseMetronome );
378
379// ~ BPM
380
381
382// JACK
383 PixmapWidget *pJackPanel = new PixmapWidget( nullptr );
384 pJackPanel->setFixedSize( 113, 43 );
385 pJackPanel->setPixmap( "/playerControlPanel/background_Jack.png" );
386 pJackPanel->setObjectName( "JackPanel" );
387 hbox->addWidget( pJackPanel );
388
389 // Jack transport mode button
390
391 /*: Using the JACK the audio/midi input and output ports of any
392 number of application can be connected.*/
393 m_pJackTransportBtn = new Button( pJackPanel, QSize( 53, 16 ),
395 pCommonStrings->getJackTransportButton(),
396 false, QSize(),
397 tr("JACK transport on/off"),
398 false, true );
399 m_pJackTransportBtn->setObjectName( "PlayerControlJackTransportButton" );
400 if ( ! m_pHydrogen->hasJackAudioDriver() ) {
401 m_pJackTransportBtn->hide();
402 }
403 if ( m_pHydrogen->hasJackTransport() ) {
404 m_pJackTransportBtn->setChecked( true );
405 } else {
406 m_pJackTransportBtn->setChecked( false );
407 }
408 connect(m_pJackTransportBtn, SIGNAL( clicked() ), this, SLOT( jackTransportBtnClicked() ));
409 m_pJackTransportBtn->move( 3, 24 );
410
411 //jack time master
412 /*: Using the JACK Timebase Master functionality one of the
413 connected programs can broadcast both speed and measure information to
414 all other connected applications in order to have a more fine-grained
415 transport control.*/
416 m_pJackMasterBtn = new Button( pJackPanel, QSize( 53, 16 ),
418 pCommonStrings->getJackMasterButton(), false,
419 QSize(), pCommonStrings->getJackTBMMasterTooltip(),
420 false, true );
421 m_pJackMasterBtn->setObjectName( "PlayerControlJackMasterButton" );
422 if ( ! m_pHydrogen->hasJackAudioDriver() ) {
423 m_pJackMasterBtn->hide();
424 }
425
426 if ( pPref->m_bJackTimebaseEnabled ) {
427 if ( m_pHydrogen->hasJackTransport() ) {
428 if ( m_pHydrogen->getJackTimebaseState() ==
430 m_pJackMasterBtn->setChecked( true );
431 }
432 else if ( m_pHydrogen->getJackTimebaseState() ==
434 m_pJackMasterBtn->setChecked( true );
435 m_pJackMasterBtn->setUseRedBackground( true );
436 m_pJackMasterBtn->setToolTip( pCommonStrings->getJackTBMSlaveTooltip() );
437 }
438 else {
439 m_pJackMasterBtn->setChecked( false );
440 }
441 }
442 else {
443 m_pJackMasterBtn->setIsActive( false );
444 }
445 }
446 else {
447 m_pJackMasterBtn->setIsActive( false );
448 m_pJackMasterBtn->setBaseToolTip( pCommonStrings->getJackMasterDisabledTooltip() );
449 }
450
451 connect(m_pJackMasterBtn, SIGNAL( clicked() ), this, SLOT( jackMasterBtnClicked() ));
452 m_pJackMasterBtn->move( 56, 24 );
453 // ~ jack time master
454
455 // CPU load widget
456 m_pCpuLoadWidget = new CpuLoadWidget( pJackPanel );
457 m_pCpuLoadWidget->setObjectName( "CpuLoadWidget" );
458
459 // Midi Activity widget
460 m_pMidiActivityLED = new LED( pJackPanel, QSize( 11, 9 ) );
461 m_pMidiActivityLED->setObjectName( "MidiActivityLED" );
462 m_pMidiActivityTimer = new QTimer( this );
463 connect( m_pMidiActivityTimer, SIGNAL( timeout() ),
464 this, SLOT( deactivateMidiActivityLED() ) );
465 m_pMidiInLbl = new ClickableLabel( pJackPanel, QSize( 45, 9 ),
466 pCommonStrings->getMidiInLabel() );
467 m_pMidiInLbl->move( 22, 14 );
468 m_pCpuLbl = new ClickableLabel( pJackPanel, QSize( 30, 9 ),
469 pCommonStrings->getCpuLabel() );
470 m_pCpuLbl->move( 71, 14 );
471
472 m_pMidiActivityLED->move( 11, 14 );
473 m_pCpuLoadWidget->move( 10, 3 );
474// ~ JACK
475
476
477 QWidget *pLcdBackGround = new QWidget( nullptr );
478 pLcdBackGround->setFixedSize( 256, 43 );
479 pLcdBackGround->setObjectName( "LcdBackground" );
480 hbox->addWidget( pLcdBackGround );
481
482 m_pShowMixerBtn = new Button( pLcdBackGround, QSize( 88, 23 ), Button::Type::Toggle,
483 "", pCommonStrings->getMixerButton(), false, QSize(),
484 tr( "Show mixer" ) );
485 m_pShowMixerBtn->move( 0, 0 );
486 connect(m_pShowMixerBtn, SIGNAL( clicked() ), this, SLOT( showMixerButtonClicked() ));
487
488 m_pShowInstrumentRackBtn = new Button( pLcdBackGround, QSize( 168, 23 ), Button::Type::Toggle,
489 "", pCommonStrings->getInstrumentRackButton(), false, QSize(),
490 tr( "Show Instrument Rack" ) );
491 m_pShowInstrumentRackBtn->move( 88, 0 );
492 connect( m_pShowInstrumentRackBtn, SIGNAL( clicked() ),
493 this, SLOT( showInstrumentRackButtonClicked() ) );
494
495 m_pStatusLabel = new StatusMessageDisplay( pLcdBackGround, QSize( 255, 18 ) );
496 m_pStatusLabel->move( 0, 24 );
497
498 hbox->addStretch( 1000 ); // this must be the last widget in the HBOX!!
499
500 QTimer *timer = new QTimer( this );
501 connect(timer, SIGNAL(timeout()), this, SLOT(updatePlayerControl()));
502 timer->start(100); // update player control at 10 fps
503
506}
507
508
509
510
513
514
515
516
517
519{
522
523 if ( ! m_pShowMixerBtn->isDown() ) {
524 m_pShowMixerBtn->setChecked( pH2App->getMixer()->isVisible() );
525 }
526 if ( ! m_pShowInstrumentRackBtn->isDown() ) {
527 m_pShowInstrumentRackBtn->setChecked( pH2App->getInstrumentRack()->isVisible() );
528 }
529
530 auto state = m_pHydrogen->getAudioEngine()->getState();
531 if ( ! m_pPlayBtn->isDown() && ! m_pStopBtn->isDown() &&
532 ! m_pFfwdBtn->isDown() && ! m_pRwdBtn->isDown() ) {
534 m_pPlayBtn->setChecked(true);
535 } else {
536 m_pPlayBtn->setChecked(false);
537 }
538 }
539
540 if ( ! m_pRecBtn->isDown() ) {
541 if (pPref->getRecordEvents()) {
542 m_pRecBtn->setChecked(true);
543 } else {
544 m_pRecBtn->setChecked(false);
545 }
546 }
547
548 std::shared_ptr<Song> song = m_pHydrogen->getSong();
549
550 if ( ! m_pLCDBPMSpinbox->hasFocus() &&
551 ! m_pLCDBPMSpinbox->getIsHovered() ) {
553 m_pLCDBPMSpinbox->setValue( m_pHydrogen->getAudioEngine()->getTransportPosition()->getBpm() );
555 }
556
557 //beatcounter
558 if ( pPref->m_bbc == Preferences::BC_OFF ) {
559 m_pControlsBCPanel->hide();
560 if ( ! m_pBCOnOffBtn->isDown() ) {
561 m_pBCOnOffBtn->setChecked(false);
562 }
563 } else {
564 m_pControlsBCPanel->show();
565 if ( ! m_pBCOnOffBtn->isDown() ) {
566 m_pBCOnOffBtn->setChecked(true);
567 }
568 }
569
570 if ( ! m_pBCSetPlayBtn->isDown() ) {
572 m_pBCSetPlayBtn->setChecked(false);
573 } else {
574 m_pBCSetPlayBtn->setChecked(true);
575 }
576 }
577 // ~ beatcounter
578
579 // time
580 float fSeconds = m_pHydrogen->getAudioEngine()->getElapsedTime();
581
582 int nMSec = (int)( (fSeconds - (int)fSeconds) * 1000.0 );
583 int nSeconds = ( (int)fSeconds ) % 60;
584 int nMins = (int)( fSeconds / 60.0 ) % 60;
585 int nHours = (int)( fSeconds / 3600.0 );
586
587 QString sTime = QString( "%1:%2:%3.%4" )
588 .arg( nHours, 2, 10, QLatin1Char( '0' ) )
589 .arg( nMins, 2, 10, QLatin1Char( '0' ) )
590 .arg( nSeconds, 2, 10, QLatin1Char( '0' ) )
591 .arg( nMSec, 3, 10, QLatin1Char( '0' ) );
592
593 if ( m_pTimeDisplay->text() != sTime ) {
594 m_pTimeDisplay->setText( sTime );
595 }
596
597 if ( ! m_pMetronomeBtn->isDown() ) {
598 m_pMetronomeBtn->setChecked(pPref->m_bUseMetronome);
599 }
600
601
602 //beatcounter get BC message
603 char bcstatus[4];
604 int beatstocountondisplay = 1;
605 beatstocountondisplay = m_pHydrogen->getBcStatus();
606
607 switch (beatstocountondisplay){
608 case 1 :
609 if (bcDisplaystatus == 1){
611 bcDisplaystatus = 0;
612 }
613 sprintf(bcstatus, "R");
614 if ( m_pBCDisplayZ->text() != bcstatus ) {
615 m_pBCDisplayZ->setText( QString (bcstatus) );
616 }
617
618 break;
619 default:
622 bcDisplaystatus = 1;
623 }
624 sprintf(bcstatus, "%02d ", beatstocountondisplay -1);
625 if ( m_pBCDisplayZ->text() != bcstatus ) {
626 m_pBCDisplayZ->setText( QString (bcstatus) );
627 }
628
629 }
630
631 // Rubberband
632 if ( m_pRubberBPMChange->isChecked() != pPref->getRubberBandBatchMode() ) {
633 m_pRubberBPMChange->setChecked( pPref->getRubberBandBatchMode());
634 }
635}
636
637
638
641 if ( m_pHydrogen->getAudioEngine()->getState() != H2Core::AudioEngine::State::Playing ) {
642 if ( m_pRecBtn->isChecked() ) {
644 (HydrogenApp::get_instance())->showStatusBarMessage( tr("Record midi events = On" ) );
645 }
646 else {
648 (HydrogenApp::get_instance())->showStatusBarMessage( tr("Record midi events = Off" ) );
649 }
650 }
651}
652
655 auto pCommonStrings = HydrogenApp::get_instance()->getCommonStrings();
656
657 // Hint that something is wrong in case there is no proper audio
658 // driver set.
659 if ( m_pHydrogen->getAudioOutput() == nullptr ||
660 dynamic_cast<NullDriver*>(m_pHydrogen->getAudioOutput()) != nullptr ) {
661 QMessageBox::warning( this, "Hydrogen",
662 QString( "%1\n%2" )
663 .arg( pCommonStrings->getAudioDriverNotPresent() )
664 .arg( pCommonStrings->getAudioDriverErrorHint() ) );
665 return;
666 }
667
668 if ( m_pPlayBtn->isChecked() ) {
669 m_pHydrogen->sequencer_play();
670 (HydrogenApp::get_instance())->showStatusBarMessage( tr("Playing.") );
671 }
672 else {
673 m_pHydrogen->sequencer_stop();
675 }
676}
677
680{
681 auto pCommonStrings = HydrogenApp::get_instance()->getCommonStrings();
682
683 // Hint that something is wrong in case there is no proper audio
684 // driver set.
685 if ( m_pHydrogen->getAudioOutput() == nullptr ||
686 dynamic_cast<NullDriver*>(m_pHydrogen->getAudioOutput()) != nullptr ) {
687 QMessageBox::warning( this, "Hydrogen",
688 QString( "%1\n%2" )
689 .arg( pCommonStrings->getAudioDriverNotPresent() )
690 .arg( pCommonStrings->getAudioDriverErrorHint() ) );
691 return;
692 }
693
694 if ( ! m_pPlayBtn->isDown() ) {
695 m_pPlayBtn->setChecked(false);
696 }
697 m_pHydrogen->sequencer_stop();
698 m_pHydrogen->getCoreActionController()->locateToColumn( 0 );
699 (HydrogenApp::get_instance())->showStatusBarMessage( tr("Stopped.") );
700}
701
703 m_pMidiActivityTimer->stop();
704 m_pMidiActivityLED->setActivated( true );
705 m_pMidiActivityTimer->start( std::chrono::duration_cast<std::chrono::milliseconds>( m_midiActivityTimeout )
706 .count() );
707}
708
710 m_pMidiActivityTimer->stop();
711 m_pMidiActivityLED->setActivated( false );
712}
713
715 // A new song got loaded
716 if ( nValue == 0 ) {
723 }
724}
725
727{
728 auto pHydrogen = Hydrogen::get_instance();
729 auto pHydrogenApp = HydrogenApp::get_instance();
730
731 if ( pHydrogen->getMode() == Song::Mode::Song ) {
732 // Song mode
733 m_pPatternModeLED->setActivated( false );
734 m_pSongModeLED->setActivated( true );
735 m_pSongModeBtn->setChecked( true );
736 m_pPatternModeBtn->setChecked( false );
737
738 m_pSongLoopBtn->setIsActive( true );
739
740 pHydrogenApp->showStatusBarMessage( tr("Song mode selected.") );
741 } else {
742 // Pattern mode
743 m_pPatternModeLED->setActivated( true );
744 m_pSongModeLED->setActivated( false );
745 m_pSongModeBtn->setChecked( false );
746 m_pPatternModeBtn->setChecked( true );
747
748 m_pSongLoopBtn->setIsActive( false );
749
750 pHydrogenApp->showStatusBarMessage( tr("Pattern mode selected.") );
751 }
752
755}
756
757void PlayerControl::activateSongMode( bool bActivate ) {
758 auto pCoreActionController = Hydrogen::get_instance()->getCoreActionController();
759 if ( bActivate ) {
760 pCoreActionController->activateSongMode( true );
761 m_pSongModeBtn->setChecked( true );
762 m_pPatternModeBtn->setChecked( false );
763 }
764 else {
765 pCoreActionController->activateSongMode( false );
766 m_pSongModeBtn->setChecked( false );
767 m_pPatternModeBtn->setChecked( true );
768 }
769}
770
771void PlayerControl::bpmChanged( double fNewBpmValue ) {
772 auto pAudioEngine = m_pHydrogen->getAudioEngine();
773 if ( m_pLCDBPMSpinbox->getIsActive() &&
775 // Store it's value in the .h2song file.
776 m_pHydrogen->getSong()->setBpm( static_cast<float>( fNewBpmValue ) );
777 // Use tempo in the next process cycle of the audio engine.
778 pAudioEngine->lock( RIGHT_HERE );
779 pAudioEngine->setNextBpm( static_cast<float>( fNewBpmValue ) );
780 pAudioEngine->unlock();
781 }
782}
783
784
785
786//beatcounter
788{
790 if ( bActivate ) {
791 pPref->m_bbc = Preferences::BC_ON;
792 (HydrogenApp::get_instance())->showStatusBarMessage( tr(" BC Panel on") );
793 m_pControlsBCPanel->show();
794 m_pBCOnOffBtn->setChecked( true );
795 }
796 else {
797 pPref->m_bbc = Preferences::BC_OFF;
798 (HydrogenApp::get_instance())->showStatusBarMessage( tr(" BC Panel off") );
799 m_pControlsBCPanel->hide();
800 m_pBCOnOffBtn->setChecked( false );
801 }
802}
803
805{
807 if ( m_pBCSetPlayBtn->text() == HydrogenApp::get_instance()->getCommonStrings()->getBeatCounterSetPlayButtonOff() ) {
809 m_pBCSetPlayBtn->setText( HydrogenApp::get_instance()->getCommonStrings()->getBeatCounterSetPlayButtonOn() );
810 (HydrogenApp::get_instance())->showStatusBarMessage( tr(" Count BPM and start PLAY") );
811 }
812 else {
814 m_pBCSetPlayBtn->setText( HydrogenApp::get_instance()->getCommonStrings()->getBeatCounterSetPlayButtonOff() );
815 (HydrogenApp::get_instance())->showStatusBarMessage( tr(" Count and set BPM") );
816 }
817}
818
820{
822 auto pHydrogen = H2Core::Hydrogen::get_instance();
823 if ( m_pRubberBPMChange->isChecked() ) {
824 // Recalculate all samples ones just to be safe since the
825 // recalculation is just triggered if there is a tempo change
826 // in the audio engine.
827 pHydrogen->getAudioEngine()->lock( RIGHT_HERE );
828 pHydrogen->recalculateRubberband( pHydrogen->getAudioEngine()->getTransportPosition()->getBpm() );
829 pHydrogen->getAudioEngine()->unlock();
830 pPref->setRubberBandBatchMode(true);
831 (HydrogenApp::get_instance())->showStatusBarMessage( tr("Recalculate all samples using Rubberband ON") );
832 }
833 else {
834 pPref->setRubberBandBatchMode(false);
835 (HydrogenApp::get_instance())->showStatusBarMessage( tr("Recalculate all samples using Rubberband OFF") );
836 }
837}
838
839
841{
842 int tmp = m_pHydrogen->getbeatsToCount();
843 char tmpb[3];
844
845 tmp ++;
846 if (tmp > 16) {
847 tmp = 2;
848 }
849
850 sprintf(tmpb, "%02d", tmp );
851 m_pBCDisplayB->setText( QString( tmpb ) );
852 m_pHydrogen->setbeatsToCount( tmp );
853}
854
856{
857 int tmp = m_pHydrogen->getbeatsToCount();
858 char tmpb[3];
859 tmp --;
860 if (tmp < 2 ) {
861 tmp = 16;
862 }
863 sprintf(tmpb, "%02d", tmp );
864 m_pBCDisplayB->setText( QString( tmpb ) );
865 m_pHydrogen->setbeatsToCount( tmp );
866}
867
869{
870 float tmp = m_pHydrogen->getNoteLength() * 4;
871
872 tmp = tmp / 2 ;
873 if (tmp < 1) {
874 tmp = 8;
875 }
876
877 m_pBCDisplayT->setText( QString::number( tmp ) );
878 m_pHydrogen->setNoteLength( (tmp) / 4 );
879}
880
882{
883 float tmp = m_pHydrogen->getNoteLength() * 4;
884
885 tmp = tmp * 2;
886 if (tmp > 8 ) {
887 tmp = 1;
888 }
889 m_pBCDisplayT->setText( QString::number(tmp) );
890 m_pHydrogen->setNoteLength( (tmp) / 4 );
891}
892// ~ beatcounter
893
894
895
897{
898 if ( !m_pHydrogen->hasJackAudioDriver() ) {
899 QMessageBox::warning( this, "Hydrogen", tr( "JACK-transport will work only with JACK driver." ) );
900 return;
901 }
902
903 auto pPref = Preferences::get_instance();
904 auto pCoreActionController = Hydrogen::get_instance()->getCoreActionController();
905
906 if ( pPref->m_bJackTransportMode == Preferences::USE_JACK_TRANSPORT ) {
907 pCoreActionController->activateJackTransport( false );
908 }
909 else {
910 pCoreActionController->activateJackTransport( true );
911 }
912}
913
914
915//jack time master
917{
918#ifdef H2CORE_HAVE_JACK
919 if ( !m_pHydrogen->hasJackTransport() ) {
920 QMessageBox::warning( this, "Hydrogen", tr( "JACK transport will work only with JACK driver." ) );
921 return;
922 }
923
924 auto pPref = Preferences::get_instance();
925 auto pCoreActionController = Hydrogen::get_instance()->getCoreActionController();
926
927 if ( pPref->m_bJackMasterMode == Preferences::USE_JACK_TIME_MASTER ) {
928 pCoreActionController->activateJackTimebaseMaster( false );
929 }
930 else {
931 pCoreActionController->activateJackTimebaseMaster( true );
932 }
933#endif
934}
935// ~ jack time master
936
938{
939 auto pHydrogen = Hydrogen::get_instance();
940 pHydrogen->getCoreActionController()->locateToColumn( pHydrogen->getAudioEngine()->getTransportPosition()->getColumn() + 1 );
941}
942
943
944
946{
947 auto pHydrogen = Hydrogen::get_instance();
948 pHydrogen->getCoreActionController()->locateToColumn( pHydrogen->getAudioEngine()->getTransportPosition()->getColumn() - 1 );
949}
950
952
953 auto pSong = Hydrogen::get_instance()->getSong();
954 if ( pSong == nullptr ) {
955 return;
956 }
957
958 if ( pSong->getLoopMode() == Song::LoopMode::Enabled ) {
959
960 m_pSongLoopBtn->setChecked( true );
961 HydrogenApp::get_instance()->showStatusBarMessage( tr("Loop song = On") );
962 }
963 else {
964 m_pSongLoopBtn->setChecked( false );
965 HydrogenApp::get_instance()->showStatusBarMessage( tr("Loop song = Off") );
966 }
967}
968
970{
971 Hydrogen* pHydrogen = Hydrogen::get_instance();
972 CoreActionController* pController = pHydrogen->getCoreActionController();
973
974 pController->setMetronomeIsActive( m_pMetronomeBtn->isChecked() );
975}
976
978{
980 bool isVisible = pH2App->getMixer()->isVisible();
981 pH2App->showMixer( !isVisible );
982}
983
985{
987 bool isVisible = pH2App->getInstrumentRack()->isVisible();
988 pH2App->showInstrumentPanel( isVisible );
989}
990
991
996
998 auto pHydrogen = Hydrogen::get_instance();
999
1000 m_pLCDBPMSpinbox->setIsActive( pHydrogen->getTempoSource() ==
1003}
1004
1005void PlayerControl::showStatusBarMessage( const QString& sMessage, const QString& sCaller ) {
1006 m_pStatusLabel->showMessage( sMessage, sCaller );
1007}
1008
1010 auto pHydrogen = Hydrogen::get_instance();
1011 switch ( pHydrogen->getTempoSource() ) {
1014 break;
1017 break;
1018 default:
1020 }
1021}
1022
1024 auto pPref = Preferences::get_instance();
1025 auto pHydrogen = Hydrogen::get_instance();
1026
1027 if ( pHydrogen->getTempoSource() == H2Core::Hydrogen::Tempo::Song &&
1028 ! m_pBCOnOffBtn->getIsActive() ) {
1029 m_pBCOnOffBtn->setIsActive( true );
1030 if ( m_bLastBCOnOffBtnState ) {
1031 m_pBCOnOffBtn->setChecked( true );
1032 pPref->m_bbc = Preferences::BC_ON;
1033 m_pControlsBCPanel->show();
1034 }
1035
1036 } else if ( pHydrogen->getTempoSource() !=
1038 m_pBCOnOffBtn->getIsActive() ) {
1039 pPref->m_bbc = Preferences::BC_OFF;
1040 m_pControlsBCPanel->hide();
1042 m_pBCOnOffBtn->setChecked( false );
1043 m_pBCOnOffBtn->setIsActive( false );
1044 }
1045
1047}
1048
1050 auto pHydrogen = Hydrogen::get_instance();
1051 switch ( pHydrogen->getTempoSource() ) {
1054 break;
1057 break;
1058 default:
1059 m_pBCOnOffBtn->setToolTip( m_sBCOnOffBtnToolTip );
1060 }
1061}
1062
1064{
1065 // When updating the tempo of the BPM spin box it is crucial to
1066 // indicated that this was done due to a batch event and not due
1067 // to user input.
1069
1070 // Also update value if the BPM widget is disabled
1071 bool bIsReadOnly = m_pLCDBPMSpinbox->isReadOnly();
1072
1073 if ( ! bIsReadOnly ) {
1074 m_pLCDBPMSpinbox->setReadOnly( true );
1075 }
1076 /*
1077 * This is an external tempo change, triggered
1078 * via a midi or osc message.
1079 *
1080 * Just update the GUI using the current tempo
1081 * of the song.
1082 */
1083 m_pLCDBPMSpinbox->setValue( m_pHydrogen->getAudioEngine()->getTransportPosition()->getBpm() );
1084
1085 if ( ! bIsReadOnly ) {
1086 m_pLCDBPMSpinbox->setReadOnly( false );
1087 }
1088
1089 // Re-enabling core Bpm alteration using BPM spinbox
1091
1092 if ( nValue == -1 ) {
1093 // Value was changed via API commands and not by the
1094 // AudioEngine.
1095 auto pHydrogen = H2Core::Hydrogen::get_instance();
1096 if ( pHydrogen->getTempoSource() == H2Core::Hydrogen::Tempo::Timeline ) {
1097 QMessageBox::warning( this, "Hydrogen", tr("A tempo change via MIDI, OSC, BeatCounter, or TapTempo was detected. It will only be used after deactivating the Timeline and left of the first Tempo Marker when activating it again.") );
1098 } else if ( pHydrogen->getTempoSource() ==
1100 QMessageBox::warning( this, "Hydrogen", tr("A tempo change via MIDI, OSC, BeatCounter, or TapTempo was detected. It will only take effect when deactivating JACK BBT transport or making Hydrogen the Timebase master.") );
1101 }
1102 }
1103}
1104
1106 if ( m_pHydrogen->hasJackAudioDriver() ) {
1107 m_pJackTransportBtn->show();
1108 m_pJackMasterBtn->show();
1109
1112 }
1113 else {
1114 m_pJackTransportBtn->hide();
1115 m_pJackMasterBtn->hide();
1116 }
1117}
1118
1120{
1121 auto pPref = Preferences::get_instance();
1122
1123 if ( pPref->m_bJackTransportMode == Preferences::USE_JACK_TRANSPORT ) {
1124
1125 if ( ! m_pJackTransportBtn->isDown() ) {
1126 m_pJackTransportBtn->setChecked( true );
1127 }
1128
1129 HydrogenApp::get_instance()->showStatusBarMessage( tr("JACK transport mode = On") );
1130
1131 if ( pPref->m_bJackTimebaseEnabled ) {
1132 m_pJackMasterBtn->setIsActive( true );
1134 }
1135 }
1136 else {
1137
1138 if ( ! m_pJackTransportBtn->isDown() ) {
1139 m_pJackTransportBtn->setChecked( false );
1140 }
1141 m_pJackMasterBtn->setChecked( false );
1142 m_pJackMasterBtn->setIsActive( false );
1143 HydrogenApp::get_instance()->showStatusBarMessage( tr("JACK transport mode = Off") );
1144 }
1145}
1146
1148{
1149 auto pPref = Preferences::get_instance();
1150 if ( ! pPref->m_bJackTimebaseEnabled ) {
1151 return;
1152 }
1153
1154 auto pCommonStrings = HydrogenApp::get_instance()->getCommonStrings();
1155 auto pHydrogen = Hydrogen::get_instance();
1156
1157 QString sMessage = tr("JACK Timebase mode" ) + QString( " = " );
1158
1159 switch( pHydrogen->getJackTimebaseState() ) {
1161
1162 if ( ! m_pJackMasterBtn->isDown() ) {
1163 m_pJackMasterBtn->setChecked( true );
1164 }
1165 m_pJackMasterBtn->setUseRedBackground( false );
1166 m_pJackMasterBtn->setToolTip( pCommonStrings->getJackTBMMasterTooltip() );
1167
1168 sMessage.append( "master" );
1169 break;
1170
1172
1173 if ( ! m_pJackMasterBtn->isDown() ) {
1174 m_pJackMasterBtn->setChecked( true );
1175 }
1176 m_pJackMasterBtn->setUseRedBackground( true );
1177 m_pJackMasterBtn->setToolTip( pCommonStrings->getJackTBMSlaveTooltip() );
1178
1179 sMessage.append( "slave" );
1180 break;
1181
1182 default:
1183
1184 if ( ! m_pJackMasterBtn->isDown() ) {
1185 m_pJackMasterBtn->setChecked( false );
1186 }
1187 m_pJackMasterBtn->setUseRedBackground( false );
1188 m_pJackMasterBtn->setToolTip( pCommonStrings->getJackTBMMasterTooltip() );
1189
1190 sMessage.append( pCommonStrings->getStatusOff() );
1191 }
1192
1196}
1197
1199{
1201 auto pPref = Preferences::get_instance();
1202 auto pCommonStrings = HydrogenApp::get_instance()->getCommonStrings();
1203
1204 if ( pPref->m_bJackTimebaseEnabled ) {
1205 if ( Hydrogen::get_instance()->hasJackTransport() ) {
1206 m_pJackMasterBtn->setIsActive( true );
1208 }
1209 else {
1210 m_pJackMasterBtn->setToolTip( pCommonStrings->getJackTBMMasterTooltip() );
1211 }
1212 }
1213 else {
1214 m_pJackMasterBtn->setChecked( false );
1215 m_pJackMasterBtn->setIsActive( false );
1216 m_pJackMasterBtn->setBaseToolTip( pCommonStrings->getJackMasterDisabledTooltip() );
1217 }
1218 }
1219}
#define RIGHT_HERE
Macro intended to be used for the logging of the locking of the H2Core::AudioEngine.
Definition AudioEngine.h:59
int bcDisplaystatus
Generic Button with SVG icons or text.
Definition Button.h:60
@ Push
Button is not set checkable.
Definition Button.h:68
@ Toggle
Button is set checkable.
Definition Button.h:70
Custom QLabel that emits a signal when clicked.
Shows the current CPU load using a meter similar to the one used in Fader.
@ Playing
Transport is rolling.
Hydrogen Audio Engine.
Definition Hydrogen.h:54
@ Timeline
Only tempo markers on the Timeline are considered.
Definition Hydrogen.h:66
@ Jack
Hydrogen will disregard all internal tempo settings and uses the ones provided by the JACK server ins...
Definition Hydrogen.h:73
@ Song
BeatCounter, TapTempo, OSC and MIDI commands as well as the BPM widget in the PlayerControl are used ...
Definition Hydrogen.h:64
std::shared_ptr< Song > getSong() const
Get the current song.
Definition Hydrogen.h:122
static Hydrogen * get_instance()
Returns the current Hydrogen instance __instance.
Definition Hydrogen.h:83
CoreActionController * getCoreActionController() const
Definition Hydrogen.h:639
@ Master
Hydrogen itself is timebase master.
@ Slave
An external program is timebase master and Hydrogen will disregard all tempo markers on the Timeline ...
Manager for User Preferences File (singleton)
Definition Preferences.h:78
static Preferences * get_instance()
Returns a pointer to the current Preferences singleton stored in __instance.
@ USE_JACK_TIME_MASTER
Specifies that Hydrogen is using in the time master mode and will thus control specific aspects of th...
Definition Preferences.h:96
@ USE_JACK_TRANSPORT
Specifies whether or not to use JACK transport capabilities.
Definition Preferences.h:89
void setRubberBandBatchMode(int val)
Changes
Bitwise or-able options showing which part of the Preferences were altered using the PreferencesDialo...
@ AudioTab
Any option in the Audio tab appeared.
bool m_bUseMetronome
If set to true, samples of the metronome will be added to H2Core::AudioEngine::m_songNoteQueue and th...
void setRecordEvents(bool value)
void addEventListener(EventListener *pListener)
static HydrogenApp * get_instance()
Returns the instance of HydrogenApp class.
std::shared_ptr< CommonStrings > getCommonStrings()
InstrumentRack * getInstrumentRack()
void showStatusBarMessage(const QString &sMessage, const QString &sCaller="")
void showMixer(bool bShow)
void preferencesChanged(H2Core::Preferences::Changes changes)
Propagates a change in the Preferences through the GUI.
void showInstrumentPanel(bool)
Mixer * getMixer()
Non-interactive display used for both numerical values and the status display.
Definition LCDDisplay.h:40
Custom spin box.
Definition LCDSpinBox.h:50
LED identicating a user selection.
Definition LED.h:43
Custom LED that comes with its own timer.
Definition LED.h:72
void setPixmap(QString sPixmapPath, bool expand_horiz=false)
void updateBeatCounterToolTip()
Button * m_pBCBDownBtn
Button * m_pRecBtn
void midiActivityEvent() override
void bcbDownButtonClicked()
LCDDisplay * m_pTimeDisplay
void showInstrumentRackButtonClicked()
virtual void timelineActivationEvent() override
Button * m_pBCTUpBtn
PixmapWidget * m_pControlsBCPanel
virtual void driverChangedEvent() override
Button * m_pMetronomeBtn
void updateBPMSpinbox()
Store the tool tip of the beat counter since it gets overwritten during deactivation.
void activateBeatCounter(bool bActivate)
ClickableLabel * m_pTimeMinutesLbl
MetronomeLED * m_pMetronomeLED
Button * m_pSongLoopBtn
void bcbUpButtonClicked()
Button * m_pBCOnOffBtn
void updatePlayerControl()
void recBtnClicked()
Toggle record mode.
void bctDownButtonClicked()
Button * m_pRubberBPMChange
void metronomeButtonClicked()
ClickableLabel * m_pBPMLbl
LED * m_pPatternModeLED
void jackMasterBtnClicked()
Button * m_pShowInstrumentRackBtn
void playBtnClicked()
Start audio engine.
QLabel * m_pBCDisplayB
void bpmChanged(double)
void onPreferencesChanged(H2Core::Preferences::Changes changes)
ClickableLabel * m_pMidiInLbl
QTimer * m_pMidiActivityTimer
Used to turn off the LED m_pMidiActivityLED indicating an incoming MIDI event after m_midiActivityTim...
virtual void updateSongEvent(int nValue) override
virtual void songModeActivationEvent() override
Shared GUI update when activating Song or Pattern mode via button click or via OSC command.
void rubberbandButtonToggle()
QString m_sBCOnOffBtnToolTip
StatusMessageDisplay * m_pStatusLabel
Button * m_pPlayBtn
Button * m_pBCSetPlayBtn
virtual void jackTransportActivationEvent() override
Button * m_pJackMasterBtn
ClickableLabel * m_pTimeHoursLbl
Button * m_pStopBtn
PlayerControl(QWidget *parent)
void jackTransportBtnClicked()
void showMixerButtonClicked()
QLabel * m_pBCDisplayT
void bcSetPlayBtnClicked()
virtual void tempoChangedEvent(int nValue) override
ClickableLabel * m_pCpuLbl
std::chrono::milliseconds m_midiActivityTimeout
ClickableLabel * m_pTimeSecondsLbl
QLabel * m_pBCDisplayZ
void fastForwardBtnClicked()
virtual void loopModeActivationEvent() override
void updateBPMSpinboxToolTip()
LED * m_pMidiActivityLED
CpuLoadWidget * m_pCpuLoadWidget
Button * m_pJackTransportBtn
Button * m_pBCBUpBtn
Button * m_pShowMixerBtn
void bctUpButtonClicked()
QString m_sBCOnOffBtnTimelineToolTip
bool m_bLastBCOnOffBtnState
void activateSongMode(bool bActivate)
QString m_sBCOnOffBtnJackTimebaseToolTip
Button * m_pBCTDownBtn
void showStatusBarMessage(const QString &msg, const QString &sCaller="")
Button * m_pRwdBtn
ClickableLabel * m_pTimeMilliSecondsLbl
QString m_sLCDBPMSpinboxToolTip
Button * m_pSongModeBtn
QString m_sLCDBPMSpinboxJackTimebaseToolTip
Button * m_pPatternModeBtn
void deactivateMidiActivityLED()
void stopBtnClicked()
Stop audio engine.
bool m_bLCDBPMSpinboxIsArmed
When updating the tempo of the BPM spin box it is crucial to indicated that this was done due to a ba...
virtual void jackTimebaseStateChangedEvent() override
LCDSpinBox * m_pLCDBPMSpinbox
H2Core::Hydrogen * m_pHydrogen
QString m_sLCDBPMSpinboxTimelineToolTip
Button * m_pFfwdBtn
static QString getImagePath()
Definition Skin.h:36
Non-interactive display for status messages in the PlayerControl.
#define MAX_BPM
Definition Globals.h:36
#define MIN_BPM
Definition Globals.h:35