root/trunk/libs/hydrogen/src/action.cpp @ 580

Revision 580, 12.5 KB (checked in by smoors, 5 years ago)

added the remaining midi actions

Line 
1/*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 *
5 * http://www.hydrogen-music.org
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY, without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 *
21 */
22#include <QObject>
23
24#include <hydrogen/audio_engine.h>
25#include <hydrogen/event_queue.h>
26#include <hydrogen/hydrogen.h>
27#include <gui/src/HydrogenApp.h>
28
29#include <hydrogen/instrument.h>
30#include <hydrogen/Song.h>
31
32
33#include <hydrogen/Preferences.h>
34#include <hydrogen/action.h>
35#include <map>
36
37ActionManager* ActionManager::instance = NULL;
38
39using namespace H2Core;
40
41/* Class Action */
42
43QString Action::getType(){
44        return type;
45}
46
47
48
49void Action::setParameter1( QString text ){
50        parameter1 = text;
51}
52
53void Action::setParameter2( QString text ){
54        parameter2 = text;
55}
56
57QString Action::getParameter1(){
58        return parameter1;
59}
60
61QString Action::getParameter2(){
62        return parameter2;
63}
64
65Action::Action( QString s ) : Object( "Action" ) {
66        type = s;
67        QString parameter1 = "0";
68        QString parameter2 = "0" ;
69}
70
71
72/* Class ActionManager */
73
74
75ActionManager::ActionManager() : Object( "ActionManager" ) {
76        INFOLOG( "ActionManager Init" );
77       
78        actionList <<""
79        << "PLAY"
80        << "PLAY_TOGGLE"
81        << "STOP"
82        << "PAUSE"
83        << "MUTE"
84        << "UNMUTE"
85        << "MUTE_TOGGLE"
86        << ">>_NEXT_BAR"
87        << "<<_PREVIOUS_BAR"
88        << "BPM_INCR"
89        << "BPM_DECR"
90        << "BPM_CC_RELATIVE"
91        << "MASTER_VOLUME_RELATIVE"
92        << "MASTER_VOLUME_ABSOLUTE"
93        << "STRIP_VOLUME_RELATIVE"
94        << "STRIP_VOLUME_ABSOLUTE"
95        << "EFFECT1_LEVEL_RELATIVE"
96        << "EFFECT2_LEVEL_RELATIVE"
97        << "EFFECT3_LEVEL_RELATIVE"
98        << "EFFECT4_LEVEL_RELATIVE"
99        << "EFFECT1_LEVEL_ABSOLUTE"
100        << "EFFECT2_LEVEL_ABSOLUTE"
101        << "EFFECT3_LEVEL_ABSOLUTE"
102        << "EFFECT4_LEVEL_ABSOLUTE"
103        << "PAN_RELATIVE"
104        << "PAN_ABSOULTE"
105        << "BEATCOUNTER"
106        << "TAP_TEMPO";
107
108        eventList << ""
109        << "MMC_PLAY"
110        << "MMC_DEFERRED_PLAY"
111        << "MMC_STOP"
112        << "MMC_FAST_FORWARD"
113        << "MMC_REWIND"
114        << "MMC_RECORD_STROBE"
115        << "MMC_RECORD_EXIT"
116        << "MMC_PAUSE"
117        << "NOTE"
118        << "CC";
119}
120
121
122ActionManager::~ActionManager(){
123        INFOLOG( "ActionManager delete" );
124        instance = NULL;
125}
126
127
128/// Return an instance of ActionManager
129ActionManager* ActionManager::getInstance()
130{
131        if ( instance == NULL ) {
132                instance = new ActionManager();
133        }
134       
135        return instance;
136}
137
138QStringList ActionManager::getActionList(){
139        return actionList;
140}
141
142QStringList ActionManager::getEventList(){
143        return eventList;
144}
145
146
147
148bool setAbsoluteFXLevel( int nLine, int fx_channel , int fx_param)
149{
150        //helper function to set fx levels
151                       
152        Hydrogen::get_instance()->setSelectedInstrumentNumber( nLine );
153
154        Hydrogen *engine = Hydrogen::get_instance();
155        Song *song = engine->getSong();
156        InstrumentList *instrList = song->get_instrument_list();
157        Instrument *instr = instrList->get( nLine );
158        if ( instr == NULL) return false;
159
160        if( fx_param != 0 ){
161                        instr->set_fx_level(  ( (float) (fx_param / 127.0 ) ), fx_channel );
162        } else {
163                        instr->set_fx_level( 0 , fx_channel );
164        }
165               
166        Hydrogen::get_instance()->setSelectedInstrumentNumber(nLine);
167       
168        return true;
169
170}
171
172bool ActionManager::handleAction( Action * pAction ){
173
174        Hydrogen *pEngine = Hydrogen::get_instance();
175
176        /*
177                return false if action is null
178                (for example if no Action exists for an event)
179        */
180        if( pAction == NULL )   return false;
181
182        QString sActionString = pAction->getType();
183
184       
185        if( sActionString == "PLAY" )
186        {
187                int nState = pEngine->getState();
188                if ( nState == STATE_READY ){
189                        pEngine->sequencer_play();
190                }
191                return true;
192        }
193
194        if( sActionString == "PLAY_TOGGLE" )
195        {
196                int nState = pEngine->getState();
197                switch ( nState )
198                {
199                        case STATE_READY:
200                                pEngine->sequencer_play();
201                                break;
202
203                        case STATE_PLAYING:
204                                pEngine->sequencer_stop();
205                                break;
206
207                        default:
208                                ERRORLOG( "[Hydrogen::ActionManager(PLAY): Unhandled case" );
209                }
210
211                return true;
212        }
213
214        if( sActionString == "PAUSE" )
215        {       
216                pEngine->sequencer_stop();
217                return true;
218        }
219
220        if( sActionString == "STOP" )
221        {       
222                pEngine->sequencer_stop();
223                pEngine->setPatternPos( 0 );
224                return true;
225        }
226
227        if( sActionString == "MUTE" ){
228                //mutes the master, not a single strip
229                pEngine->getSong()->__is_muted = true;
230                return true;
231        }
232
233        if( sActionString == "UNMUTE" ){
234                pEngine->getSong()->__is_muted = false;
235                return true;
236        }
237
238        if( sActionString == "MUTE_TOGGLE" ){
239                pEngine->getSong()->__is_muted = !Hydrogen::get_instance()->getSong()->__is_muted;
240                return true;
241        }
242
243        if( sActionString == "BEATCOUNTER" ){
244                pEngine->handleBeatCounter();
245                return true;
246        }
247
248        if( sActionString == "TAP_TEMPO" ){
249                pEngine->onTapTempoAccelEvent();
250                return true;
251        }
252
253
254
255       
256        if( sActionString == "EFFECT1_LEVEL_ABSOLUTE" ){
257                bool ok;
258                int nLine = pAction->getParameter1().toInt(&ok,10);
259                int fx_param = pAction->getParameter2().toInt(&ok,10);
260                setAbsoluteFXLevel( nLine, 0 , fx_param );
261        }
262
263        if( sActionString == "EFFECT2_LEVEL_ABSOLUTE" ){
264                bool ok;
265                int nLine = pAction->getParameter1().toInt(&ok,10);
266                int fx_param = pAction->getParameter2().toInt(&ok,10);
267                setAbsoluteFXLevel( nLine, 1 , fx_param );
268        }
269
270        if( sActionString == "EFFECT3_LEVEL_ABSOLUTE" ){
271                bool ok;
272                int nLine = pAction->getParameter1().toInt(&ok,10);
273                int fx_param = pAction->getParameter2().toInt(&ok,10);
274                setAbsoluteFXLevel( nLine, 2 , fx_param );
275        }
276
277        if( sActionString == "EFFECT4_LEVEL_ABSOLUTE" ){
278                bool ok;
279                int nLine = pAction->getParameter1().toInt(&ok,10);
280                int fx_param = pAction->getParameter2().toInt(&ok,10);
281                setAbsoluteFXLevel( nLine, 3 , fx_param );
282        }
283       
284
285       
286       
287
288        if( sActionString == "MASTER_VOLUME_RELATIVE" ){
289                //increments/decrements the volume of the whole song   
290               
291                bool ok;
292                int vol_param = pAction->getParameter2().toInt(&ok,10);
293                       
294                Hydrogen *engine = Hydrogen::get_instance();
295                Song *song = engine->getSong();
296
297
298
299                if( vol_param != 0 ){
300                                if ( vol_param == 1 && song->get_volume() < 1.5 ){
301                                        song->set_volume( song->get_volume() + 0.05 ); 
302                                }  else  {
303                                        if( song->get_volume() >= 0.0 ){
304                                                song->set_volume( song->get_volume() - 0.05 );
305                                        }
306                                }
307                } else {
308                        song->set_volume( 0 );
309                }
310
311        }
312
313       
314
315        if( sActionString == "MASTER_VOLUME_ABSOLUTE" ){
316                //sets the volume of a mixer strip to a given level (percentage)
317
318                bool ok;
319                int nLine = pAction->getParameter1().toInt(&ok,10);
320                int vol_param = pAction->getParameter2().toInt(&ok,10);
321                       
322
323                Hydrogen *engine = Hydrogen::get_instance();
324                Song *song = engine->getSong();
325
326
327                if( vol_param != 0 ){
328                                song->set_volume( 1.5* ( (float) (vol_param / 127.0 ) ));
329                } else {
330                                song->set_volume( 0 );
331                }
332
333        }
334
335       
336
337        if( sActionString == "STRIP_VOLUME_RELATIVE" ){
338                //increments/decrements the volume of one mixer strip   
339               
340                bool ok;
341                int nLine = pAction->getParameter1().toInt(&ok,10);
342                int vol_param = pAction->getParameter2().toInt(&ok,10);
343                       
344                Hydrogen::get_instance()->setSelectedInstrumentNumber( nLine );
345
346                Hydrogen *engine = Hydrogen::get_instance();
347                Song *song = engine->getSong();
348                InstrumentList *instrList = song->get_instrument_list();
349
350                Instrument *instr = instrList->get( nLine );
351
352                if ( instr == NULL) return 0;
353
354                if( vol_param != 0 ){
355                                if ( vol_param == 1 && instr->get_volume() < 1.5 ){
356                                        instr->set_volume( instr->get_volume() + 0.1 ); 
357                                }  else  {
358                                        if( instr->get_volume() >= 0.0 ){
359                                                instr->set_volume( instr->get_volume() - 0.1 );
360                                        }
361                                }
362                } else {
363                        instr->set_volume( 0 );
364                }
365
366                Hydrogen::get_instance()->setSelectedInstrumentNumber(nLine);
367        }
368
369        if( sActionString == "STRIP_VOLUME_ABSOLUTE" ){
370                //sets the volume of a mixer strip to a given level (percentage)
371
372                bool ok;
373                int nLine = pAction->getParameter1().toInt(&ok,10);
374                int vol_param = pAction->getParameter2().toInt(&ok,10);
375                       
376                Hydrogen::get_instance()->setSelectedInstrumentNumber( nLine );
377
378                Hydrogen *engine = Hydrogen::get_instance();
379                Song *song = engine->getSong();
380                InstrumentList *instrList = song->get_instrument_list();
381
382                Instrument *instr = instrList->get( nLine );
383
384                if ( instr == NULL) return 0;
385
386                if( vol_param != 0 ){
387                                instr->set_volume( 1.5* ( (float) (vol_param / 127.0 ) ));
388                } else {
389                                instr->set_volume( 0 );
390                }
391
392                Hydrogen::get_instance()->setSelectedInstrumentNumber(nLine);
393        }
394
395       
396        if( sActionString == "PAN_ABSOULTE" ){
397               
398                 // sets the absolute panning of a given mixer channel
399               
400               
401                bool ok;
402                int nLine = pAction->getParameter1().toInt(&ok,10);
403                int pan_param = pAction->getParameter2().toInt(&ok,10);
404
405               
406                float pan_L;
407                float pan_R;
408
409                Hydrogen *engine = Hydrogen::get_instance();
410                engine->setSelectedInstrumentNumber( nLine );
411                Song *song = engine->getSong();
412                InstrumentList *instrList = song->get_instrument_list();
413
414                Instrument *instr = instrList->get( nLine );
415               
416                if( instr == NULL )
417                        return false;
418               
419                pan_L = instr->get_pan_l();
420                pan_R = instr->get_pan_r();
421
422                // pan
423                float fPanValue = 0.0;
424                if (pan_R == 1.0) {
425                        fPanValue = 1.0 - (pan_L / 2.0);
426                }
427                else {
428                        fPanValue = pan_R / 2.0;
429                }
430
431               
432                fPanValue = 1 * ( ((float) pan_param) / 127.0 );
433
434
435                if (fPanValue >= 0.5) {
436                        pan_L = (1.0 - fPanValue) * 2;
437                        pan_R = 1.0;
438                }
439                else {
440                        pan_L = 1.0;
441                        pan_R = fPanValue * 2;
442                }
443
444
445                instr->set_pan_l( pan_L );
446                instr->set_pan_r( pan_R );
447
448                Hydrogen::get_instance()->setSelectedInstrumentNumber(nLine);
449
450                return true;
451        }
452
453        if( sActionString == "PAN_RELATIVE" ){
454               
455                 // changes the panning of a given mixer channel
456                // this is useful if the panning is set by a rotary control knob
457               
458               
459                bool ok;
460                int nLine = pAction->getParameter1().toInt(&ok,10);
461                int pan_param = pAction->getParameter2().toInt(&ok,10);
462
463               
464                float pan_L;
465                float pan_R;
466
467                Hydrogen *engine = Hydrogen::get_instance();
468                engine->setSelectedInstrumentNumber( nLine );
469                Song *song = engine->getSong();
470                InstrumentList *instrList = song->get_instrument_list();
471
472                Instrument *instr = instrList->get( nLine );
473               
474                if( instr == NULL )
475                        return false;
476               
477                pan_L = instr->get_pan_l();
478                pan_R = instr->get_pan_r();
479
480                // pan
481                float fPanValue = 0.0;
482                if (pan_R == 1.0) {
483                        fPanValue = 1.0 - (pan_L / 2.0);
484                }
485                else {
486                        fPanValue = pan_R / 2.0;
487                }
488
489                if( pan_param == 1 && fPanValue < 1 ){
490                        fPanValue += 0.05;
491                }
492
493                if( pan_param != 1 && fPanValue > 0 ){
494                        fPanValue -= 0.05;
495                }
496
497                if (fPanValue >= 0.5) {
498                        pan_L = (1.0 - fPanValue) * 2;
499                        pan_R = 1.0;
500                }
501                else {
502                        pan_L = 1.0;
503                        pan_R = fPanValue * 2;
504                }
505
506
507                instr->set_pan_l( pan_L );
508                instr->set_pan_r( pan_R );
509
510                Hydrogen::get_instance()->setSelectedInstrumentNumber(nLine);
511
512                return true;
513        }
514       
515
516        if( sActionString == "BPM_CC_RELATIVE" ){
517                /*
518                 * increments/decrements the BPM
519                 * this is useful if the bpm is set by a rotary control knob
520                */
521
522                AudioEngine::get_instance()->lock( "Action::BPM_CC_RELATIVE" );
523
524                int mult = 1;   
525
526                //second parameter of cc command
527                //this value should be 1 to decrement and something other then 1 to increment the bpm
528                int cc_param = 1;
529
530                //this Action should be triggered only by CC commands
531
532                bool ok;
533                mult = pAction->getParameter1().toInt(&ok,10);
534                cc_param = pAction->getParameter2().toInt(&ok,10);
535                       
536
537
538                Song* pSong = pEngine->getSong();
539
540
541               
542                if ( cc_param == 1 && pSong->__bpm  < 300) {
543                        pEngine->setBPM( pSong->__bpm + 1*mult );
544                }
545
546
547                if ( cc_param != 1 && pSong->__bpm  > 40 ) {
548                        pEngine->setBPM( pSong->__bpm - 1*mult );
549                }
550
551
552                AudioEngine::get_instance()->unlock();
553
554                return true;
555        }
556
557
558        if( sActionString == "BPM_INCR" ){
559                AudioEngine::get_instance()->lock( "Action::BPM_INCR" );
560
561                int mult = 1;   
562
563                bool ok;
564                mult = pAction->getParameter1().toInt(&ok,10);
565
566
567                Song* pSong = pEngine->getSong();
568                if (pSong->__bpm  < 300) {
569                        pEngine->setBPM( pSong->__bpm + 1*mult );
570                }
571                AudioEngine::get_instance()->unlock();
572
573                return true;
574        }
575
576
577
578        if( sActionString == "BPM_DECR" ){
579                AudioEngine::get_instance()->lock( "Action::BPM_DECR" );
580
581                int mult = 1;   
582
583                bool ok;
584                mult = pAction->getParameter1().toInt(&ok,10);
585
586                Song* pSong = pEngine->getSong();
587                if (pSong->__bpm  > 40 ) {
588                        pEngine->setBPM( pSong->__bpm - 1*mult );
589                }
590                AudioEngine::get_instance()->unlock();
591               
592                return true;
593        }
594
595        if( sActionString == ">>_NEXT_BAR"){
596                pEngine->setPatternPos(pEngine->getPatternPos() +1 );
597                return true;
598        }
599
600        if( sActionString == "<<_PREVIOUS_BAR"){
601                pEngine->setPatternPos(pEngine->getPatternPos() -1 );
602                return true;
603        }
604       
605        return false;
606}
Note: See TracBrowser for help on using the browser.