hydrogen 1.2.3
MidiAction.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 https://www.gnu.org/licenses
20 *
21 */
22#include <QObject>
23
26#include <core/EventQueue.h>
28#include <core/Hydrogen.h>
29
35#include <core/Basics/Song.h>
37
39#include <core/MidiAction.h>
40
41#include <core/Basics/Drumkit.h>
42
43// #include <QFileInfo>
44
45#include <sstream>
46
47using namespace H2Core;
48
71Action::Action( QString sType ) {
72 m_sType = sType;
73 m_sParameter1 = "0";
74 m_sParameter2 = "0";
75 m_sParameter3 = "0";
76 m_sValue = "0";
77}
78
79Action::Action( std::shared_ptr<Action> pOther ) {
80 m_sType = pOther->m_sType;
81 m_sParameter1 = pOther->m_sParameter1;
82 m_sParameter2 = pOther->m_sParameter2;
83 m_sParameter3 = pOther->m_sParameter3;
84 m_sValue = pOther->m_sValue;
85}
86
87bool Action::isNull() const {
89}
90
91bool Action::isEquivalentTo( std::shared_ptr<Action> pOther ) {
92 if ( pOther == nullptr ) {
93 return false;
94 }
95
96 return ( m_sType == pOther->m_sType &&
97 m_sParameter1 == pOther->m_sParameter1 &&
98 m_sParameter2 == pOther->m_sParameter2 &&
99 m_sParameter3 == pOther->m_sParameter3 );
100}
101
102QString Action::toQString( const QString& sPrefix, bool bShort ) const {
103 QString s = Base::sPrintIndention;
104 QString sOutput;
105 if ( ! bShort ) {
106 sOutput = QString( "%1[Action]\n" ).arg( sPrefix )
107 .append( QString( "%1%2m_sType: %3\n" ).arg( sPrefix ).arg( s ).arg( m_sType ) )
108 .append( QString( "%1%2m_sValue: %3\n" ).arg( sPrefix ).arg( s ).arg( m_sValue ) )
109 .append( QString( "%1%2m_sParameter1: %3\n" ).arg( sPrefix ).arg( s ).arg( m_sParameter1 ) )
110 .append( QString( "%1%2m_sParameter2: %3\n" ).arg( sPrefix ).arg( s ).arg( m_sParameter2 ) )
111 .append( QString( "%1%2m_sParameter3: %3\n" ).arg( sPrefix ).arg( s ).arg( m_sParameter3 ) );
112 } else {
113 sOutput = QString( "[Action]" )
114 .append( QString( " m_sType: %1" ).arg( m_sType ) )
115 .append( QString( ", m_sValue: %1" ).arg( m_sValue ) )
116 .append( QString( ", m_sParameter1: %1" ).arg( m_sParameter1 ) )
117 .append( QString( ", m_sParameter2: %1" ).arg( m_sParameter2 ) )
118 .append( QString( ", m_sParameter3: %1" ).arg( m_sParameter3 ) );
119 }
120
121 return sOutput;
122}
123
138
140 __instance = this;
141
143 /*
144 the m_actionMap holds all Action identifiers which hydrogen is able to interpret.
145 it holds pointer to member function
146 */
147 m_actionMap.insert(std::make_pair("PLAY", std::make_pair( &MidiActionManager::play, 0 ) ));
148 m_actionMap.insert(std::make_pair("PLAY/STOP_TOGGLE", std::make_pair( &MidiActionManager::play_stop_pause_toggle, 0 ) ));
149 m_actionMap.insert(std::make_pair("PLAY/PAUSE_TOGGLE", std::make_pair( &MidiActionManager::play_stop_pause_toggle, 0 ) ));
150 m_actionMap.insert(std::make_pair("STOP", std::make_pair( &MidiActionManager::stop, 0 ) ));
151 m_actionMap.insert(std::make_pair("PAUSE", std::make_pair( &MidiActionManager::pause, 0 ) ));
152 m_actionMap.insert(std::make_pair("RECORD_READY", std::make_pair( &MidiActionManager::record_ready, 0 ) ));
153 m_actionMap.insert(std::make_pair("RECORD/STROBE_TOGGLE", std::make_pair( &MidiActionManager::record_strobe_toggle, 0 ) ));
154 m_actionMap.insert(std::make_pair("RECORD_STROBE", std::make_pair( &MidiActionManager::record_strobe, 0 ) ));
155 m_actionMap.insert(std::make_pair("RECORD_EXIT", std::make_pair( &MidiActionManager::record_exit, 0 ) ));
156 m_actionMap.insert(std::make_pair("MUTE", std::make_pair( &MidiActionManager::mute, 0 ) ));
157 m_actionMap.insert(std::make_pair("UNMUTE", std::make_pair( &MidiActionManager::unmute, 0 ) ));
158 m_actionMap.insert(std::make_pair("MUTE_TOGGLE", std::make_pair( &MidiActionManager::mute_toggle, 0 ) ));
159 m_actionMap.insert(std::make_pair("STRIP_MUTE_TOGGLE", std::make_pair( &MidiActionManager::strip_mute_toggle, 1 ) ));
160 m_actionMap.insert(std::make_pair("STRIP_SOLO_TOGGLE", std::make_pair( &MidiActionManager::strip_solo_toggle, 1 ) ));
161 m_actionMap.insert(std::make_pair(">>_NEXT_BAR", std::make_pair( &MidiActionManager::next_bar, 0 ) ));
162 m_actionMap.insert(std::make_pair("<<_PREVIOUS_BAR", std::make_pair( &MidiActionManager::previous_bar, 0 ) ));
163 m_actionMap.insert(std::make_pair("BPM_INCR", std::make_pair( &MidiActionManager::bpm_increase, 1 ) ));
164 m_actionMap.insert(std::make_pair("BPM_DECR", std::make_pair( &MidiActionManager::bpm_decrease, 1 ) ));
165 m_actionMap.insert(std::make_pair("BPM_CC_RELATIVE", std::make_pair( &MidiActionManager::bpm_cc_relative, 1 ) ));
166 m_actionMap.insert(std::make_pair("BPM_FINE_CC_RELATIVE", std::make_pair( &MidiActionManager::bpm_fine_cc_relative, 1 ) ));
167 m_actionMap.insert(std::make_pair("MASTER_VOLUME_RELATIVE", std::make_pair( &MidiActionManager::master_volume_relative, 0 ) ));
168 m_actionMap.insert(std::make_pair("MASTER_VOLUME_ABSOLUTE", std::make_pair( &MidiActionManager::master_volume_absolute, 0 ) ));
169 m_actionMap.insert(std::make_pair("STRIP_VOLUME_RELATIVE", std::make_pair( &MidiActionManager::strip_volume_relative, 1 ) ));
170 m_actionMap.insert(std::make_pair("STRIP_VOLUME_ABSOLUTE", std::make_pair( &MidiActionManager::strip_volume_absolute, 1 ) ));
171 m_actionMap.insert(std::make_pair("EFFECT_LEVEL_ABSOLUTE", std::make_pair( &MidiActionManager::effect_level_absolute, 2 ) ));
172 m_actionMap.insert(std::make_pair("EFFECT_LEVEL_RELATIVE", std::make_pair( &MidiActionManager::effect_level_relative, 2 ) ));
173 m_actionMap.insert(std::make_pair("GAIN_LEVEL_ABSOLUTE", std::make_pair( &MidiActionManager::gain_level_absolute, 3 ) ));
174 m_actionMap.insert(std::make_pair("PITCH_LEVEL_ABSOLUTE", std::make_pair( &MidiActionManager::pitch_level_absolute, 3 ) ));
175 m_actionMap.insert(std::make_pair("SELECT_NEXT_PATTERN", std::make_pair( &MidiActionManager::select_next_pattern, 1 ) ));
176 m_actionMap.insert(std::make_pair("SELECT_ONLY_NEXT_PATTERN", std::make_pair( &MidiActionManager::select_only_next_pattern, 1 ) ));
177 m_actionMap.insert(std::make_pair("SELECT_NEXT_PATTERN_CC_ABSOLUTE", std::make_pair( &MidiActionManager::select_next_pattern_cc_absolute, 0 ) ));
178 m_actionMap.insert(std::make_pair("SELECT_ONLY_NEXT_PATTERN_CC_ABSOLUTE", std::make_pair( &MidiActionManager::select_only_next_pattern_cc_absolute, 0 ) ));
179 m_actionMap.insert(std::make_pair("SELECT_NEXT_PATTERN_RELATIVE", std::make_pair( &MidiActionManager::select_next_pattern_relative, 1 ) ));
180 m_actionMap.insert(std::make_pair("SELECT_AND_PLAY_PATTERN", std::make_pair( &MidiActionManager::select_and_play_pattern, 1 ) ));
181 m_actionMap.insert(std::make_pair("PAN_RELATIVE", std::make_pair( &MidiActionManager::pan_relative, 1 ) ));
182 m_actionMap.insert(std::make_pair("PAN_ABSOLUTE", std::make_pair( &MidiActionManager::pan_absolute, 1 ) ));
183 m_actionMap.insert(std::make_pair("PAN_ABSOLUTE_SYM", std::make_pair( &MidiActionManager::pan_absolute_sym, 1 ) ));
184 m_actionMap.insert(std::make_pair("FILTER_CUTOFF_LEVEL_ABSOLUTE", std::make_pair( &MidiActionManager::filter_cutoff_level_absolute, 1 ) ));
185 m_actionMap.insert(std::make_pair("BEATCOUNTER", std::make_pair( &MidiActionManager::beatcounter, 0 ) ));
186 m_actionMap.insert(std::make_pair("TAP_TEMPO", std::make_pair( &MidiActionManager::tap_tempo, 0 ) ));
187 m_actionMap.insert(std::make_pair("PLAYLIST_SONG", std::make_pair( &MidiActionManager::playlist_song, 1 ) ));
188 m_actionMap.insert(std::make_pair("PLAYLIST_NEXT_SONG", std::make_pair( &MidiActionManager::playlist_next_song, 0 ) ));
189 m_actionMap.insert(std::make_pair("PLAYLIST_PREV_SONG", std::make_pair( &MidiActionManager::playlist_previous_song, 0 ) ));
190 m_actionMap.insert(std::make_pair("TOGGLE_METRONOME", std::make_pair( &MidiActionManager::toggle_metronome, 0 ) ));
191 m_actionMap.insert(std::make_pair("SELECT_INSTRUMENT", std::make_pair( &MidiActionManager::select_instrument, 0 ) ));
192 m_actionMap.insert(std::make_pair("UNDO_ACTION", std::make_pair( &MidiActionManager::undo_action, 0 ) ));
193 m_actionMap.insert(std::make_pair("REDO_ACTION", std::make_pair( &MidiActionManager::redo_action, 0 ) ));
194 /*
195 the m_actionList holds all Action identifiers which hydrogen is able to interpret.
196 */
197 m_actionList <<"";
198 for ( const auto& ppAction : m_actionMap ) {
199 m_actionList << ppAction.first;
200 }
201}
202
203
205 //INFOLOG( "ActionManager delete" );
206 __instance = nullptr;
207}
208
210 if ( __instance == nullptr ) {
212 }
213}
214
215bool MidiActionManager::play( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
216 // Preventive measure to avoid bad things.
217 if ( pHydrogen->getSong() == nullptr ) {
218 ERRORLOG( "No song set yet" );
219 return false;
220 }
221
222 if ( pHydrogen->getAudioEngine()->getState() == AudioEngine::State::Ready ) {
223 pHydrogen->sequencer_play();
224 }
225 return true;
226}
227
228bool MidiActionManager::pause( std::shared_ptr<Action> , Hydrogen* pHydrogen ) {
229 // Preventive measure to avoid bad things.
230 if ( pHydrogen->getSong() == nullptr ) {
231 ERRORLOG( "No song set yet" );
232 return false;
233 }
234
235 pHydrogen->sequencer_stop();
236 return true;
237}
238
239bool MidiActionManager::stop( std::shared_ptr<Action> , Hydrogen* pHydrogen ) {
240 // Preventive measure to avoid bad things.
241 if ( pHydrogen->getSong() == nullptr ) {
242 ERRORLOG( "No song set yet" );
243 return false;
244 }
245
246 pHydrogen->sequencer_stop();
247 return pHydrogen->getCoreActionController()->locateToColumn( 0 );
248}
249
250bool MidiActionManager::play_stop_pause_toggle( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
251 // Preventive measure to avoid bad things.
252 if ( pHydrogen->getSong() == nullptr ) {
253 ERRORLOG( "No song set yet" );
254 return false;
255 }
256
257 QString sActionString = pAction->getType();
258 switch ( pHydrogen->getAudioEngine()->getState() )
259 {
260 case AudioEngine::State::Ready:
261 pHydrogen->sequencer_play();
262 break;
263
264 case AudioEngine::State::Playing:
265 if( sActionString == "PLAY/STOP_TOGGLE" ) {
266 pHydrogen->getCoreActionController()->locateToColumn( 0 );
267 }
268 pHydrogen->sequencer_stop();
269 break;
270
271 default:
272 ERRORLOG( "[Hydrogen::ActionManager(PLAY): Unhandled case" );
273 break;
274 }
275
276 return true;
277}
278
279//mutes the master, not a single strip
280bool MidiActionManager::mute( std::shared_ptr<Action> , Hydrogen* pHydrogen ) {
281 // Preventive measure to avoid bad things.
282 if ( pHydrogen->getSong() == nullptr ) {
283 ERRORLOG( "No song set yet" );
284 return false;
285 }
286
287 return pHydrogen->getCoreActionController()->setMasterIsMuted( true );
288}
289
290bool MidiActionManager::unmute( std::shared_ptr<Action> , Hydrogen* pHydrogen ) {
291 // Preventive measure to avoid bad things.
292 if ( pHydrogen->getSong() == nullptr ) {
293 ERRORLOG( "No song set yet" );
294 return false;
295 }
296
297 return pHydrogen->getCoreActionController()->setMasterIsMuted( false );
298}
299
300bool MidiActionManager::mute_toggle( std::shared_ptr<Action> , Hydrogen* pHydrogen ) {
301 // Preventive measure to avoid bad things.
302 if ( pHydrogen->getSong() == nullptr ) {
303 ERRORLOG( "No song set yet" );
304 return false;
305 }
306
307 return pHydrogen->getCoreActionController()->setMasterIsMuted( !pHydrogen->getSong()->getIsMuted() );
308}
309
310bool MidiActionManager::strip_mute_toggle( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
311 auto pSong = pHydrogen->getSong();
312
313 // Preventive measure to avoid bad things.
314 if ( pSong == nullptr ) {
315 ERRORLOG( "No song set yet" );
316 return false;
317 }
318
319 bool ok;
320 int nLine = pAction->getParameter1().toInt(&ok,10);
321
322 auto pInstrList = pSong->getInstrumentList();
323
324 auto pInstr = pInstrList->get( nLine );
325 if ( pInstr == nullptr ) {
326 ERRORLOG( QString( "Unable to retrieve instrument (Par. 1) [%1]" ).arg( nLine ) );
327 return false;
328 }
329
330 return pHydrogen->getCoreActionController()->setStripIsMuted( nLine, !pInstr->is_muted() );
331}
332
333bool MidiActionManager::strip_solo_toggle( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
334 auto pSong = pHydrogen->getSong();
335
336 // Preventive measure to avoid bad things.
337 if ( pSong == nullptr ) {
338 ERRORLOG( "No song set yet" );
339 return false;
340 }
341
342 bool ok;
343 int nLine = pAction->getParameter1().toInt(&ok,10);
344
345 auto pInstrList = pSong->getInstrumentList();
346
347 auto pInstr = pInstrList->get( nLine );
348 if ( pInstr == nullptr ) {
349 ERRORLOG( QString( "Unable to retrieve instrument (Par. 1) [%1]" ).arg( nLine ) );
350 return false;
351 }
352
353 return pHydrogen->getCoreActionController()->setStripIsSoloed( nLine, !pInstr->is_soloed() );
354}
355
356bool MidiActionManager::beatcounter( std::shared_ptr<Action> , Hydrogen* pHydrogen ) {
357 // Preventive measure to avoid bad things.
358 if ( pHydrogen->getSong() == nullptr ) {
359 ERRORLOG( "No song set yet" );
360 return false;
361 }
362
363 return pHydrogen->handleBeatCounter();
364}
365
366bool MidiActionManager::tap_tempo( std::shared_ptr<Action> , Hydrogen* pHydrogen ) {
367 // Preventive measure to avoid bad things.
368 if ( pHydrogen->getSong() == nullptr ) {
369 ERRORLOG( "No song set yet" );
370 return false;
371 }
372
373 pHydrogen->onTapTempoAccelEvent();
374 return true;
375}
376
377bool MidiActionManager::select_next_pattern( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
378 bool ok;
379 return nextPatternSelection( pAction->getParameter1().toInt(&ok,10) );
380}
381
382
383bool MidiActionManager::select_next_pattern_relative( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
384 bool ok;
386 pAction->getParameter1().toInt(&ok,10) );
387}
388
389bool MidiActionManager::select_next_pattern_cc_absolute( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
390 bool ok;
391 return nextPatternSelection( pAction->getValue().toInt(&ok,10) );
392}
393
394bool MidiActionManager::nextPatternSelection( int nPatternNumber ) {
395 auto pHydrogen = Hydrogen::get_instance();
396 auto pSong = pHydrogen->getSong();
397
398 // Preventive measure to avoid bad things.
399 if ( pSong == nullptr ) {
400 ERRORLOG( "No song set yet" );
401 return false;
402 }
403
404 if ( nPatternNumber > pSong->getPatternList()->size() - 1 ||
405 nPatternNumber < 0 ) {
406 ERRORLOG( QString( "Provided value [%1] out of bound [0,%2]" ).arg( nPatternNumber )
407 .arg( pSong->getPatternList()->size() - 1 ) );
408 return false;
409 }
410
411 if ( pHydrogen->getPatternMode() == Song::PatternMode::Selected ) {
412 pHydrogen->setSelectedPatternNumber( nPatternNumber );
413 }
414 else if ( pHydrogen->getPatternMode() == Song::PatternMode::Stacked ) {
415 pHydrogen->toggleNextPattern( nPatternNumber );
416 }
417
418 return true;
419}
420
421bool MidiActionManager::select_only_next_pattern( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
422 bool ok;
423 return onlyNextPatternSelection( pAction->getParameter1().toInt(&ok,10) );
424}
425
426bool MidiActionManager::select_only_next_pattern_cc_absolute( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
427 bool ok;
428 return onlyNextPatternSelection( pAction->getValue().toInt(&ok,10) );
429}
430
432 auto pHydrogen = Hydrogen::get_instance();
433 auto pSong = pHydrogen->getSong();
434
435 // Preventive measure to avoid bad things.
436 if ( pSong == nullptr ) {
437 ERRORLOG( "No song set yet" );
438 return false;
439 }
440
441 if ( nPatternNumber > pSong->getPatternList()->size() -1 ||
442 nPatternNumber < 0 ) {
443 if ( pHydrogen->getPatternMode() == Song::PatternMode::Selected ) {
444 ERRORLOG( QString( "Provided pattern number [%1] out of bound [0,%2]." )
445 .arg( nPatternNumber )
446 .arg( pSong->getPatternList()->size() - 1 ) );
447 return false;
448 }
449 else {
450 INFOLOG( QString( "Provided pattern number [%1] out of bound [0,%2]. All patterns will be deselected." )
451 .arg( nPatternNumber )
452 .arg( pSong->getPatternList()->size() - 1 ) );
453 }
454 }
455
456 if ( pHydrogen->getPatternMode() == Song::PatternMode::Selected ) {
457 return nextPatternSelection( nPatternNumber );
458 }
459
460 return pHydrogen->flushAndAddNextPattern( nPatternNumber );
461}
462
463bool MidiActionManager::select_and_play_pattern( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
464 // Preventive measure to avoid bad things.
465 if ( pHydrogen->getSong() == nullptr ) {
466 ERRORLOG( "No song set yet" );
467 return false;
468 }
469
470 if ( ! select_next_pattern( pAction, pHydrogen ) ) {
471 return false;
472 }
473
474 if ( pHydrogen->getAudioEngine()->getState() == AudioEngine::State::Ready ) {
475 pHydrogen->sequencer_play();
476 }
477
478 return true;
479}
480
481bool MidiActionManager::select_instrument( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
482 auto pSong = pHydrogen->getSong();
483
484 // Preventive measure to avoid bad things.
485 if ( pSong == nullptr ) {
486 ERRORLOG( "No song set yet" );
487 return false;
488 }
489
490 bool ok;
491 int nInstrumentNumber = pAction->getValue().toInt(&ok,10) ;
492
493 if ( pSong->getInstrumentList()->size() < nInstrumentNumber ) {
494 nInstrumentNumber = pSong->getInstrumentList()->size() -1;
495 } else if ( nInstrumentNumber < 0 ) {
496 nInstrumentNumber = 0;
497 }
498
499 pHydrogen->setSelectedInstrumentNumber( nInstrumentNumber );
500 return true;
501}
502
503bool MidiActionManager::effect_level_absolute( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen) {
504 auto pSong = pHydrogen->getSong();
505
506 // Preventive measure to avoid bad things.
507 if ( pSong == nullptr ) {
508 ERRORLOG( "No song set yet" );
509 return false;
510 }
511
512 bool ok;
513 int nLine = pAction->getParameter1().toInt(&ok,10);
514 int fx_param = pAction->getValue().toInt(&ok,10);
515 int fx_id = pAction->getParameter2().toInt(&ok,10);
516
517 auto pInstrList = pSong->getInstrumentList();
518
519 auto pInstr = pInstrList->get( nLine );
520 if ( pInstr == nullptr) {
521 ERRORLOG( QString( "Unable to retrieve instrument (Par. 1) [%1]" ).arg( nLine ) );
522 return false;
523 }
524
525 if( fx_param != 0 ) {
526 pInstr->set_fx_level( (float) (fx_param / 127.0 ), fx_id );
527 } else {
528 pInstr->set_fx_level( 0 , fx_id );
529 }
530
531 pHydrogen->setSelectedInstrumentNumber( nLine );
532
534
535 return true;
536}
537
538bool MidiActionManager::effect_level_relative( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
539 auto pSong = pHydrogen->getSong();
540
541 // Preventive measure to avoid bad things.
542 if ( pSong == nullptr ) {
543 ERRORLOG( "No song set yet" );
544 return false;
545 }
546
547 bool ok;
548 int nLine = pAction->getParameter1().toInt(&ok,10);
549 int fx_param = pAction->getValue().toInt(&ok,10);
550 int fx_id = pAction->getParameter2().toInt(&ok,10);
551
552 auto pInstrList = pSong->getInstrumentList();
553
554 auto pInstr = pInstrList->get( nLine );
555 if ( pInstr == nullptr) {
556 ERRORLOG( QString( "Unable to retrieve instrument (Par. 1) [%1]" ).arg( nLine ) );
557 return false;
558 }
559 if ( fx_param != 0 ) {
560 if ( fx_param == 1 && pInstr->get_fx_level( fx_id ) <= 0.95 ) {
561 pInstr->set_fx_level( pInstr->get_fx_level( fx_id ) + 0.05, fx_id );
562 }
563 else if ( pInstr->get_fx_level( fx_id ) >= 0.05 ) {
564 pInstr->set_fx_level( pInstr->get_fx_level( fx_id ) - 0.05, fx_id );
565 }
566 }
567
568 pHydrogen->setSelectedInstrumentNumber( nLine );
569
571
572 return true;
573}
574
575//sets the volume of a master output to a given level (percentage)
576bool MidiActionManager::master_volume_absolute( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
577 auto pSong = pHydrogen->getSong();
578
579 // Preventive measure to avoid bad things.
580 if ( pSong == nullptr ) {
581 ERRORLOG( "No song set yet" );
582 return false;
583 }
584
585 bool ok;
586 int nVolume = pAction->getValue().toInt(&ok,10);
587
588 if ( nVolume != 0 ) {
589 pSong->setVolume( 1.5* ( (float) (nVolume / 127.0 ) ));
590 } else {
591 pSong->setVolume( 0 );
592 }
593
594 return true;
595}
596
597//increments/decrements the volume of the whole song
598bool MidiActionManager::master_volume_relative( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
599 auto pSong = pHydrogen->getSong();
600
601 // Preventive measure to avoid bad things.
602 if ( pSong == nullptr ) {
603 ERRORLOG( "No song set yet" );
604 return false;
605 }
606
607 bool ok;
608 int nVolume = pAction->getValue().toInt(&ok,10);
609
610 if ( nVolume != 0 ) {
611 if ( nVolume == 1 && pSong->getVolume() < 1.5 ) {
612 pSong->setVolume( pSong->getVolume() + 0.05 );
613 } else if ( pSong->getVolume() >= 0.0 ) {
614 pSong->setVolume( pSong->getVolume() - 0.05 );
615 }
616 } else {
617 pSong->setVolume( 0 );
618 }
619
620 return true;
621}
622
623//sets the volume of a mixer strip to a given level (percentage)
624bool MidiActionManager::strip_volume_absolute( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
625 auto pSong = pHydrogen->getSong();
626
627 // Preventive measure to avoid bad things.
628 if ( pSong == nullptr ) {
629 ERRORLOG( "No song set yet" );
630 return false;
631 }
632
633 bool ok;
634 int nLine = pAction->getParameter1().toInt(&ok,10);
635 int nVolume = pAction->getValue().toInt(&ok,10);
636
637 auto pInstrList = pSong->getInstrumentList();
638
639 auto pInstr = pInstrList->get( nLine );
640 if ( pInstr == nullptr ) {
641 ERRORLOG( QString( "Unable to retrieve instrument (Par. 1) [%1]" ).arg( nLine ) );
642 return false;
643 }
644
645 if ( nVolume != 0 ) {
646 pInstr->set_volume( 1.5* ( (float) (nVolume / 127.0 ) ));
647 } else {
648 pInstr->set_volume( 0 );
649 }
650
651 pHydrogen->setSelectedInstrumentNumber(nLine);
653
654 return true;
655}
656
657//increments/decrements the volume of one mixer strip
658bool MidiActionManager::strip_volume_relative( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
659 auto pSong = pHydrogen->getSong();
660
661 // Preventive measure to avoid bad things.
662 if ( pSong == nullptr ) {
663 ERRORLOG( "No song set yet" );
664 return false;
665 }
666
667 bool ok;
668 int nLine = pAction->getParameter1().toInt(&ok,10);
669 int nVolume = pAction->getValue().toInt(&ok,10);
670
671 auto pInstrList = pSong->getInstrumentList();
672
673 auto pInstr = pInstrList->get( nLine );
674
675 if ( pInstr == nullptr) {
676 ERRORLOG( QString( "Unable to retrieve instrument (Par. 1) [%1]" ).arg( nLine ) );
677 return false;
678 }
679
680 if( nVolume != 0 ) {
681 if ( nVolume == 1 && pInstr->get_volume() < 1.5 ) {
682 pInstr->set_volume( pInstr->get_volume() + 0.1 );
683 }
684 else if( pInstr->get_volume() >= 0.0 ){
685 pInstr->set_volume( pInstr->get_volume() - 0.1 );
686 }
687 }
688 else {
689 pInstr->set_volume( 0 );
690 }
691
692 pHydrogen->setSelectedInstrumentNumber( nLine );
694
695 return true;
696}
697
698// sets the absolute panning of a given mixer channel
699bool MidiActionManager::pan_absolute( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
700 auto pSong = pHydrogen->getSong();
701
702 // Preventive measure to avoid bad things.
703 if ( pSong == nullptr ) {
704 ERRORLOG( "No song set yet" );
705 return false;
706 }
707
708 bool ok;
709 int nLine = pAction->getParameter1().toInt(&ok,10);
710 int pan_param = pAction->getValue().toInt(&ok,10);
711
712 auto pInstrList = pSong->getInstrumentList();
713
714 auto pInstr = pInstrList->get( nLine );
715 if( pInstr == nullptr ) {
716 ERRORLOG( QString( "Unable to retrieve instrument (Par. 1) [%1]" ).arg( nLine ) );
717 return false;
718 }
719
720 pInstr->setPanWithRangeFrom0To1( (float) pan_param / 127.f );
721
722 pHydrogen->setSelectedInstrumentNumber(nLine);
723
725
726 return true;
727}
728
729// sets the absolute panning of a given mixer channel
730bool MidiActionManager::pan_absolute_sym( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
731 auto pSong = pHydrogen->getSong();
732
733 // Preventive measure to avoid bad things.
734 if ( pSong == nullptr ) {
735 ERRORLOG( "No song set yet" );
736 return false;
737 }
738
739 bool ok;
740 int nLine = pAction->getParameter1().toInt(&ok,10);
741 int pan_param = pAction->getValue().toInt(&ok,10);
742
743 auto pInstrList = pSong->getInstrumentList();
744
745 auto pInstr = pInstrList->get( nLine );
746 if ( pInstr == nullptr ) {
747 ERRORLOG( QString( "Unable to retrieve instrument (Par. 1) [%1]" ).arg( nLine ) );
748 return false;
749 }
750
751 pInstr->setPan( (float) pan_param / 127.f );
752
753 pHydrogen->setSelectedInstrumentNumber(nLine);
755
756 return true;
757}
758
759
760// changes the panning of a given mixer channel
761// this is useful if the panning is set by a rotary control knob
762bool MidiActionManager::pan_relative( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
763 auto pSong = pHydrogen->getSong();
764
765 // Preventive measure to avoid bad things.
766 if ( pSong == nullptr ) {
767 ERRORLOG( "No song set yet" );
768 return false;
769 }
770
771 bool ok;
772 int nLine = pAction->getParameter1().toInt(&ok,10);
773 int pan_param = pAction->getValue().toInt(&ok,10);
774
775 auto pInstrList = pSong->getInstrumentList();
776
777 auto pInstr = pInstrList->get( nLine );
778 if ( pInstr == nullptr ) {
779 ERRORLOG( QString( "Unable to retrieve instrument (Par. 1) [%1]" ).arg( nLine ) );
780 return false;
781 }
782
783 float fPan = pInstr->getPan();
784
785 if ( pan_param == 1 && fPan < 1.f ) {
786 pInstr->setPan( fPan + 0.1 );
787 }
788 else if ( pan_param != 1 && fPan > -1.f ) {
789 pInstr->setPan( fPan - 0.1 );
790 }
791
792 pHydrogen->setSelectedInstrumentNumber(nLine);
794
795 return true;
796}
797
798bool MidiActionManager::gain_level_absolute( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
799 auto pSong = pHydrogen->getSong();
800
801 // Preventive measure to avoid bad things.
802 if ( pSong == nullptr ) {
803 ERRORLOG( "No song set yet" );
804 return false;
805 }
806
807 bool ok;
808 int nLine = pAction->getParameter1().toInt(&ok,10);
809 int gain_param = pAction->getValue().toInt(&ok,10);
810 int component_id = pAction->getParameter2().toInt(&ok,10);
811 int layer_id = pAction->getParameter3().toInt(&ok,10);
812
813 auto pInstrList = pSong->getInstrumentList();
814
815 auto pInstr = pInstrList->get( nLine );
816 if( pInstr == nullptr ) {
817 ERRORLOG( QString( "Unable to retrieve instrument (Par. 1) [%1]" ).arg( nLine ) );
818 return false;
819 }
820
821 auto pComponent = pInstr->get_component( component_id );
822 if( pComponent == nullptr) {
823 ERRORLOG( QString( "Unable to retrieve component (Par. 2) [%1]" ).arg( component_id ) );
824 return false;
825 }
826
827 auto pLayer = pComponent->get_layer( layer_id );
828 if( pLayer == nullptr ) {
829 ERRORLOG( QString( "Unable to retrieve layer (Par. 3) [%1]" ).arg( layer_id ) );
830 return false;
831 }
832
833 if ( gain_param != 0 ) {
834 pLayer->set_gain( 5.0* ( (float) (gain_param / 127.0 ) ) );
835 } else {
836 pLayer->set_gain( 0 );
837 }
838
839 pHydrogen->setSelectedInstrumentNumber( nLine );
841
842 return true;
843}
844
845bool MidiActionManager::pitch_level_absolute( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
846 auto pSong = pHydrogen->getSong();
847
848 // Preventive measure to avoid bad things.
849 if ( pSong == nullptr ) {
850 ERRORLOG( "No song set yet" );
851 return false;
852 }
853
854 bool ok;
855 int nLine = pAction->getParameter1().toInt(&ok,10);
856 int pitch_param = pAction->getValue().toInt(&ok,10);
857 int component_id = pAction->getParameter2().toInt(&ok,10);
858 int layer_id = pAction->getParameter3().toInt(&ok,10);
859
860 auto pInstrList = pSong->getInstrumentList();
861
862 auto pInstr = pInstrList->get( nLine );
863 if( pInstr == nullptr ) {
864 ERRORLOG( QString( "Unable to retrieve instrument (Par. 1) [%1]" ).arg( nLine ) );
865 return false;
866 }
867
868 auto pComponent = pInstr->get_component( component_id );
869 if( pComponent == nullptr) {
870 ERRORLOG( QString( "Unable to retrieve component (Par. 2) [%1]" ).arg( component_id ) );
871 return false;
872 }
873
874 auto pLayer = pComponent->get_layer( layer_id );
875 if( pLayer == nullptr ) {
876 ERRORLOG( QString( "Unable to retrieve layer (Par. 3) [%1]" ).arg( layer_id ) );
877 return false;
878 }
879
880 if( pitch_param != 0 ){
881 pLayer->set_pitch( 49* ( (float) (pitch_param / 127.0 ) ) -24.5 );
882 } else {
883 pLayer->set_pitch( -24.5 );
884 }
885
886 pHydrogen->setSelectedInstrumentNumber( nLine );
888
889 return true;
890}
891
892bool MidiActionManager::filter_cutoff_level_absolute( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
893 auto pSong = pHydrogen->getSong();
894
895 // Preventive measure to avoid bad things.
896 if ( pSong == nullptr ) {
897 ERRORLOG( "No song set yet" );
898 return false;
899 }
900
901 bool ok;
902 int nLine = pAction->getParameter1().toInt(&ok,10);
903 int filter_cutoff_param = pAction->getValue().toInt(&ok,10);
904
905 auto pInstrList = pSong->getInstrumentList();
906
907 auto pInstr = pInstrList->get( nLine );
908 if( pInstr == nullptr ) {
909 ERRORLOG( QString( "Unable to retrieve instrument (Par. 1) [%1]" ).arg( nLine ) );
910 return false;
911 }
912
913 pInstr->set_filter_active( true );
914 if( filter_cutoff_param != 0 ) {
915 pInstr->set_filter_cutoff( ( (float) (filter_cutoff_param / 127.0 ) ) );
916 } else {
917 pInstr->set_filter_cutoff( 0 );
918 }
919
920 pHydrogen->setSelectedInstrumentNumber( nLine );
922
923 return true;
924}
925
926
927/*
928 * increments/decrements the BPM
929 * this is useful if the bpm is set by a rotary control knob
930 */
931bool MidiActionManager::bpm_cc_relative( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
932 // Preventive measure to avoid bad things.
933 if ( pHydrogen->getSong() == nullptr ) {
934 ERRORLOG( "No song set yet" );
935 return false;
936 }
937
938 auto pAudioEngine = pHydrogen->getAudioEngine();
939 const float fBpm = pAudioEngine->getTransportPosition()->getBpm();
940
941 //this Action should be triggered only by CC commands
942
943 bool ok;
944 int mult = pAction->getParameter1().toInt(&ok,10);
945 //this value should be 1 to decrement and something other then 1 to increment the bpm
946 int cc_param = pAction->getValue().toInt(&ok,10);
947
948 if( m_nLastBpmChangeCCParameter == -1) {
950 }
951
952 if ( m_nLastBpmChangeCCParameter >= cc_param &&
953 fBpm - mult > MIN_BPM ) {
954 // Use tempo in the next process cycle of the audio engine.
955 pAudioEngine->lock( RIGHT_HERE );
956 pAudioEngine->setNextBpm( fBpm - 1*mult );
957 pAudioEngine->unlock();
958 // Store it's value in the .h2song file.
959 pHydrogen->getSong()->setBpm( fBpm - 1*mult );
960 }
961
962 if ( m_nLastBpmChangeCCParameter < cc_param
963 && fBpm + mult < MAX_BPM ) {
964 // Use tempo in the next process cycle of the audio engine.
965 pAudioEngine->lock( RIGHT_HERE );
966 pAudioEngine->setNextBpm( fBpm + 1*mult );
967 pAudioEngine->unlock();
968 // Store it's value in the .h2song file.
969 pHydrogen->getSong()->setBpm( fBpm + 1*mult );
970 }
971
973
975
976 return true;
977}
978
979/*
980 * increments/decrements the BPM
981 * this is useful if the bpm is set by a rotary control knob
982 */
983bool MidiActionManager::bpm_fine_cc_relative( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
984 // Preventive measure to avoid bad things.
985 if ( pHydrogen->getSong() == nullptr ) {
986 ERRORLOG( "No song set yet" );
987 return false;
988 }
989
990 auto pAudioEngine = pHydrogen->getAudioEngine();
991 const float fBpm = pAudioEngine->getTransportPosition()->getBpm();
992
993 //this Action should be triggered only by CC commands
994 bool ok;
995 int mult = pAction->getParameter1().toInt(&ok,10);
996 //this value should be 1 to decrement and something other then 1 to increment the bpm
997 int cc_param = pAction->getValue().toInt(&ok,10);
998
999 if( m_nLastBpmChangeCCParameter == -1) {
1000 m_nLastBpmChangeCCParameter = cc_param;
1001 }
1002
1003 if ( m_nLastBpmChangeCCParameter >= cc_param &&
1004 fBpm - mult > MIN_BPM ) {
1005 // Use tempo in the next process cycle of the audio engine.
1006 pAudioEngine->lock( RIGHT_HERE );
1007 pAudioEngine->setNextBpm( fBpm - 0.01*mult );
1008 pAudioEngine->unlock();
1009 // Store it's value in the .h2song file.
1010 pHydrogen->getSong()->setBpm( fBpm - 0.01*mult );
1011 }
1012 if ( m_nLastBpmChangeCCParameter < cc_param
1013 && fBpm + mult < MAX_BPM ) {
1014 // Use tempo in the next process cycle of the audio engine.
1015 pAudioEngine->lock( RIGHT_HERE );
1016 pAudioEngine->setNextBpm( fBpm + 0.01*mult );
1017 pAudioEngine->unlock();
1018 // Store it's value in the .h2song file.
1019 pHydrogen->getSong()->setBpm( fBpm + 0.01*mult );
1020 }
1021
1022 m_nLastBpmChangeCCParameter = cc_param;
1023
1025
1026 return true;
1027}
1028
1029bool MidiActionManager::bpm_increase( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
1030 // Preventive measure to avoid bad things.
1031 if ( pHydrogen->getSong() == nullptr ) {
1032 ERRORLOG( "No song set yet" );
1033 return false;
1034 }
1035
1036 auto pAudioEngine = pHydrogen->getAudioEngine();
1037 const float fBpm = pAudioEngine->getTransportPosition()->getBpm();
1038
1039 bool ok;
1040 int mult = pAction->getParameter1().toInt(&ok,10);
1041
1042 // Use tempo in the next process cycle of the audio engine.
1043 pAudioEngine->lock( RIGHT_HERE );
1044 pAudioEngine->setNextBpm( fBpm + 1*mult );
1045 pAudioEngine->unlock();
1046 // Store it's value in the .h2song file.
1047 pHydrogen->getSong()->setBpm( fBpm + 1*mult );
1048
1050
1051 return true;
1052}
1053
1054bool MidiActionManager::bpm_decrease( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
1055 // Preventive measure to avoid bad things.
1056 if ( pHydrogen->getSong() == nullptr ) {
1057 ERRORLOG( "No song set yet" );
1058 return false;
1059 }
1060
1061 auto pAudioEngine = pHydrogen->getAudioEngine();
1062 const float fBpm = pAudioEngine->getTransportPosition()->getBpm();
1063
1064 bool ok;
1065 int mult = pAction->getParameter1().toInt(&ok,10);
1066
1067 // Use tempo in the next process cycle of the audio engine.
1068 pAudioEngine->lock( RIGHT_HERE );
1069 pAudioEngine->setNextBpm( fBpm - 1*mult );
1070 pAudioEngine->unlock();
1071 // Store it's value in the .h2song file.
1072 pHydrogen->getSong()->setBpm( fBpm - 1*mult );
1073
1075
1076 return true;
1077}
1078
1079bool MidiActionManager::next_bar( std::shared_ptr<Action> , Hydrogen* pHydrogen ) {
1080 // Preventive measure to avoid bad things.
1081 if ( pHydrogen->getSong() == nullptr ) {
1082 ERRORLOG( "No song set yet" );
1083 return false;
1084 }
1085
1086 int nNewColumn = std::max( 0, pHydrogen->getAudioEngine()->
1087 getTransportPosition()->getColumn() ) + 1;
1088
1089 pHydrogen->getCoreActionController()->locateToColumn( nNewColumn );
1090 return true;
1091}
1092
1093
1094bool MidiActionManager::previous_bar( std::shared_ptr<Action> , Hydrogen* pHydrogen ) {
1095 // Preventive measure to avoid bad things.
1096 if ( pHydrogen->getSong() == nullptr ) {
1097 ERRORLOG( "No song set yet" );
1098 return false;
1099 }
1100
1102 pHydrogen->getAudioEngine()->getTransportPosition()->getColumn() -1 );
1103 return true;
1104}
1105
1106bool MidiActionManager::setSong( int nSongNumber, Hydrogen* pHydrogen ) {
1107 int nActiveSongNumber = Playlist::get_instance()->getActiveSongNumber();
1108 if( nSongNumber >= 0 && nSongNumber <= Playlist::get_instance()->size() - 1 ) {
1109 if ( nActiveSongNumber != nSongNumber ) {
1111 }
1112 } else {
1113 // Preventive measure to avoid bad things.
1114 if ( pHydrogen->getSong() == nullptr ) {
1115 ___ERRORLOG( "No song set yet" );
1116 }
1117 else if ( Playlist::get_instance()->size() == 0 ) {
1118 ___ERRORLOG( QString( "No songs added to the current playlist yet" ) );
1119 }
1120 else {
1121 ___ERRORLOG( QString( "Provided song number [%1] out of bound [0,%2]" )
1122 .arg( nSongNumber )
1123 .arg( Playlist::get_instance()->size() - 1 ) );
1124 }
1125 return false;
1126 }
1127 return true;
1128}
1129
1130bool MidiActionManager::playlist_song( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
1131 bool ok;
1132 int songnumber = pAction->getParameter1().toInt(&ok,10);
1133 return setSong( songnumber, pHydrogen );
1134}
1135
1136bool MidiActionManager::playlist_next_song( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
1137 int songnumber = Playlist::get_instance()->getActiveSongNumber();
1138 return setSong( ++songnumber, pHydrogen );
1139}
1140
1141bool MidiActionManager::playlist_previous_song( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
1142 int songnumber = Playlist::get_instance()->getActiveSongNumber();
1143 return setSong( --songnumber, pHydrogen );
1144}
1145
1146bool MidiActionManager::record_ready( std::shared_ptr<Action> pAction, Hydrogen* pHydrogen ) {
1147 // Preventive measure to avoid bad things.
1148 if ( pHydrogen->getSong() == nullptr ) {
1149 ERRORLOG( "No song set yet" );
1150 return false;
1151 }
1152
1153 if ( pHydrogen->getAudioEngine()->getState() != AudioEngine::State::Playing ) {
1154 if (!Preferences::get_instance()->getRecordEvents()) {
1156 }
1157 else {
1159 }
1160 }
1161 return true;
1162}
1163
1164bool MidiActionManager::record_strobe_toggle( std::shared_ptr<Action> , Hydrogen* pHydrogen ) {
1165 // Preventive measure to avoid bad things.
1166 if ( pHydrogen->getSong() == nullptr ) {
1167 ERRORLOG( "No song set yet" );
1168 return false;
1169 }
1170
1171 if (!Preferences::get_instance()->getRecordEvents()) {
1173 }
1174 else {
1176 }
1177 return true;
1178}
1179
1180bool MidiActionManager::record_strobe( std::shared_ptr<Action> , Hydrogen* pHydrogen ) {
1181 // Preventive measure to avoid bad things.
1182 if ( pHydrogen->getSong() == nullptr ) {
1183 ERRORLOG( "No song set yet" );
1184 return false;
1185 }
1186
1187 if (!Preferences::get_instance()->getRecordEvents()) {
1189 }
1190 return true;
1191}
1192
1193bool MidiActionManager::record_exit( std::shared_ptr<Action> , Hydrogen* pHydrogen) {
1194 // Preventive measure to avoid bad things.
1195 if ( pHydrogen->getSong() == nullptr ) {
1196 ERRORLOG( "No song set yet" );
1197 return false;
1198 }
1199
1200 if (Preferences::get_instance()->getRecordEvents()) {
1202 }
1203 return true;
1204}
1205
1206bool MidiActionManager::toggle_metronome( std::shared_ptr<Action> , Hydrogen* pHydrogen) {
1207 // Preventive measure to avoid bad things.
1208 if ( pHydrogen->getSong() == nullptr ) {
1209 ERRORLOG( "No song set yet" );
1210 return false;
1211 }
1212
1213 // Use the wrapper in CAC over a plain setting of the parameter in
1214 // order to send MIDI feedback
1216 ! Preferences::get_instance()->m_bUseMetronome );
1217
1218 return true;
1219}
1220
1221bool MidiActionManager::undo_action( std::shared_ptr<Action> , Hydrogen* ) {
1223 return true;
1224}
1225
1226bool MidiActionManager::redo_action( std::shared_ptr<Action> , Hydrogen* ) {
1228 return true;
1229}
1230
1231int MidiActionManager::getParameterNumber( const QString& sActionType ) const {
1232 auto foundActionPair = m_actionMap.find( sActionType );
1233 if ( foundActionPair != m_actionMap.end() ) {
1234 return foundActionPair->second.second;
1235 } else {
1236 ERRORLOG( QString( "MIDI Action type [%1] couldn't be found" ).arg( sActionType ) );
1237 }
1238
1239 return -1;
1240}
1241
1242bool MidiActionManager::handleActions( std::vector<std::shared_ptr<Action>> actions ) {
1243
1244 bool bResult = false;
1245
1246 for ( const auto& action : actions ) {
1247 if ( action != nullptr ) {
1248 if ( handleAction( action ) ) {
1249 bResult = true;
1250 }
1251 }
1252 }
1253
1254 return bResult;
1255}
1256
1257bool MidiActionManager::handleAction( std::shared_ptr<Action> pAction ) {
1258
1259 Hydrogen *pHydrogen = Hydrogen::get_instance();
1260 /*
1261 return false if action is null
1262 (for example if no Action exists for an event)
1263 */
1264 if( pAction == nullptr ) {
1265 return false;
1266 }
1267
1268 QString sActionString = pAction->getType();
1269
1270 auto foundActionPair = m_actionMap.find( sActionString );
1271 if( foundActionPair != m_actionMap.end() ) {
1272 action_f action = foundActionPair->second.first;
1273 return (this->*action)(pAction, pHydrogen);
1274 } else {
1275 ERRORLOG( QString( "MIDI Action type [%1] couldn't be found" ).arg( sActionString ) );
1276 }
1277
1278 return false;
1279}
#define RIGHT_HERE
Macro intended to be used for the logging of the locking of the H2Core::AudioEngine.
Definition AudioEngine.h:59
#define INFOLOG(x)
Definition Object.h:237
#define ERRORLOG(x)
Definition Object.h:239
#define ___ERRORLOG(x)
Definition Object.h:257
static QString getNullActionType()
Definition MidiAction.h:34
QString m_sValue
Definition MidiAction.h:132
QString m_sParameter1
Definition MidiAction.h:129
QString m_sParameter2
Definition MidiAction.h:130
QString m_sType
Definition MidiAction.h:128
bool isEquivalentTo(std::shared_ptr< Action > pOther)
bool isNull() const
Checks whether m_sType is of getNullActionType()
QString toQString(const QString &sPrefix="", bool bShort=true) const override
Formatted string version for debugging purposes.
Action(QString sType=getNullActionType())
QString m_sParameter3
Definition MidiAction.h:131
State getState() const
const std::shared_ptr< TransportPosition > getTransportPosition() const
static QString sPrintIndention
String used to format the debugging string output of some core classes.
Definition Object.h:127
bool locateToColumn(int nPatternGroup)
Relocates transport to the beginning of a particular column/Pattern group.
bool setStripIsMuted(int nStrip, bool isMuted)
bool setStripIsSoloed(int nStrip, bool isSoloed)
static EventQueue * get_instance()
Returns a pointer to the current EventQueue singleton stored in __instance.
Definition EventQueue.h:224
void push_event(const EventType type, const int nValue)
Queues the next event into the EventQueue.
Hydrogen Audio Engine.
Definition Hydrogen.h:54
void sequencer_stop()
Stop the internal sequencer.
Definition Hydrogen.cpp:226
std::shared_ptr< Song > getSong() const
Get the current song.
Definition Hydrogen.h:122
void onTapTempoAccelEvent()
Definition Hydrogen.cpp:779
int getSelectedPatternNumber() const
Definition Hydrogen.h:660
void setSelectedInstrumentNumber(int nInstrument, bool bTriggerEvent=true)
Definition Hydrogen.cpp:918
static Hydrogen * get_instance()
Returns the current Hydrogen instance __instance.
Definition Hydrogen.h:83
bool handleBeatCounter()
Definition Hydrogen.cpp:993
AudioEngine * getAudioEngine() const
Definition Hydrogen.h:649
CoreActionController * getCoreActionController() const
Definition Hydrogen.h:639
void sequencer_play()
Start the internal sequencer.
Definition Hydrogen.cpp:218
void setNextSongByNumber(int SongNumber)
Definition Playlist.cpp:197
int getActiveSongNumber()
Definition Playlist.h:149
static Playlist * get_instance()
Returns a pointer to the current Playlist singleton stored in __instance.
Definition Playlist.h:60
static Preferences * get_instance()
Returns a pointer to the current Preferences singleton stored in __instance.
void setRecordEvents(bool value)
The MidiActionManager cares for the execution of MidiActions.
Definition MidiAction.h:142
bool previous_bar(std::shared_ptr< Action >, H2Core::Hydrogen *)
static MidiActionManager * __instance
Object holding the current MidiActionManager singleton.
Definition MidiAction.h:151
bool bpm_decrease(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool record_strobe(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool playlist_next_song(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool setSong(int nSongNumber, H2Core::Hydrogen *pHydrogen)
bool playlist_song(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool unmute(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool strip_volume_absolute(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool play(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool playlist_previous_song(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool select_instrument(std::shared_ptr< Action >, H2Core::Hydrogen *)
int m_nLastBpmChangeCCParameter
Definition MidiAction.h:216
bool mute(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool record_exit(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool master_volume_absolute(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool pitch_level_absolute(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool tap_tempo(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool select_next_pattern_relative(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool handleAction(std::shared_ptr< Action > action)
The handleAction method is the heart of the MidiActionManager class.
bool strip_solo_toggle(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool beatcounter(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool pan_absolute(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool onlyNextPatternSelection(int nPatternNumber)
static void create_instance()
If __instance equals 0, a new MidiActionManager singleton will be created and stored in it.
bool pan_relative(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool pan_absolute_sym(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool select_next_pattern(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool bpm_fine_cc_relative(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool select_and_play_pattern(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool effect_level_absolute(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool redo_action(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool handleActions(std::vector< std::shared_ptr< Action > > actions)
Handles multiple actions at once and calls handleAction() on them.
bool filter_cutoff_level_absolute(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool strip_volume_relative(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool pause(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool next_bar(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool toggle_metronome(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool play_stop_pause_toggle(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool record_strobe_toggle(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool select_only_next_pattern_cc_absolute(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool bpm_cc_relative(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool stop(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool record_ready(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool undo_action(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool select_only_next_pattern(std::shared_ptr< Action >, H2Core::Hydrogen *)
QStringList m_actionList
Holds the names of all Action identifiers which Hydrogen is able to interpret.
Definition MidiAction.h:157
bool mute_toggle(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool nextPatternSelection(int nPatternNumber)
bool master_volume_relative(std::shared_ptr< Action >, H2Core::Hydrogen *)
int getParameterNumber(const QString &sActionType) const
bool select_next_pattern_cc_absolute(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool(MidiActionManager::* action_f)(std::shared_ptr< Action >, H2Core::Hydrogen *)
Definition MidiAction.h:159
std::map< QString, std::pair< action_f, int > > m_actionMap
Holds all Action identifiers which Hydrogen is able to interpret.
Definition MidiAction.h:168
bool bpm_increase(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool strip_mute_toggle(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool effect_level_relative(std::shared_ptr< Action >, H2Core::Hydrogen *)
bool gain_level_absolute(std::shared_ptr< Action >, H2Core::Hydrogen *)
#define MAX_BPM
Definition Globals.h:36
#define MIN_BPM
Definition Globals.h:35
@ EVENT_INSTRUMENT_PARAMETERS_CHANGED
Some parameters of an instrument have been changed.
Definition EventQueue.h:83
@ EVENT_UNDO_REDO
Definition EventQueue.h:101
@ EVENT_TEMPO_CHANGED
Definition EventQueue.h:103