root/trunk/libs/hydrogen/src/hydrogen.cpp @ 332

Revision 332, 73.7 KB (checked in by wolke, 5 years ago)

do a renamejackports only if jack track outputs are true

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
23#ifdef WIN32
24#include "timeHelper.h"
25#include "timersub.h"
26#else
27#include <unistd.h>
28#include <sys/time.h>
29#endif
30
31#include <pthread.h>
32#include <cassert>
33#include <cstdio>
34#include <deque>
35#include <queue>
36#include <iostream>
37#include <ctime>
38#include <cmath>
39
40#include <hydrogen/LocalFileMng.h>
41#include <hydrogen/event_queue.h>
42#include <hydrogen/adsr.h>
43#include <hydrogen/SoundLibrary.h>
44#include <hydrogen/h2_exception.h>
45#include <hydrogen/audio_engine.h>
46#include <hydrogen/instrument.h>
47#include <hydrogen/sample.h>
48#include <hydrogen/hydrogen.h>
49#include <hydrogen/Pattern.h>
50#include <hydrogen/note.h>
51#include <hydrogen/fx/LadspaFX.h>
52#include <hydrogen/fx/Effects.h>
53#include <hydrogen/IO/AudioOutput.h>
54#include <hydrogen/IO/JackOutput.h>
55#include <hydrogen/IO/NullDriver.h>
56#include <hydrogen/IO/MidiInput.h>
57#include <hydrogen/IO/CoreMidiDriver.h>
58#include <hydrogen/IO/TransportInfo.h>
59#include <hydrogen/Preferences.h>
60#include <hydrogen/data_path.h>
61#include <hydrogen/sampler/Sampler.h>
62
63#include "IO/OssDriver.h"
64#include "IO/FakeDriver.h"
65#include "IO/AlsaAudioDriver.h"
66#include "IO/PortAudioDriver.h"
67#include "IO/DiskWriterDriver.h"
68#include "IO/AlsaMidiDriver.h"
69#include "IO/PortMidiDriver.h"
70#include "IO/CoreAudioDriver.h"
71
72
73namespace H2Core
74{
75
76// GLOBALS
77
78// info
79float m_fMasterPeak_L = 0.0f;           ///< Master peak (left channel)
80float m_fMasterPeak_R = 0.0f;           ///< Master peak (right channel)
81float m_fProcessTime = 0.0f;            ///< time used in process function
82float m_fMaxProcessTime = 0.0f;         ///< max ms usable in process with no xrun
83//~ info
84
85
86// beatcounter
87
88//100,000 ms in 1 second.
89#define MS_DIVIDER .000001
90
91float m_ntaktoMeterCompute = 1;         ///< beatcounter note lenght
92int m_nbeatsToCount = 4;                ///< beatcounter beats to count
93int eventCount = 1;                     ///< beatcounter event
94int tempochangecounter = 0;             ///< count tempochanges for timeArray
95int beatCount = 1;                      ///< beatcounter beat to count
96double beatDiffs[16];                   ///< beat diff
97timeval currentTime, lastTime;          ///< timeval
98double lastBeatTime, currentBeatTime, beatDiff;         ///< timediff
99float beatCountBpm;                     ///< bpm
100//~ beatcounter
101//jack time master
102float m_nNewBpmJTM = 120;
103unsigned long m_nHumantimeFrames = 0;
104//~ jack time master
105
106AudioOutput *m_pAudioDriver = NULL;     ///< Audio output
107MidiInput *m_pMidiDriver = NULL;        ///< MIDI input
108
109// overload the the > operator of Note objects for priority_queue
110bool operator> (const Note& pNote1, const Note &pNote2) {
111        return (pNote1.m_nHumanizeDelay + pNote1.get_position() * m_pAudioDriver->m_transport.m_nTickSize) > \
112                (pNote2.m_nHumanizeDelay + pNote2.get_position() * m_pAudioDriver->m_transport.m_nTickSize);
113}
114
115std::priority_queue<Note*, std::deque<Note*>, std::greater<Note> > m_songNoteQueue;     /// Song Note FIFO
116std::deque<Note*> m_midiNoteQueue;      ///< Midi Note FIFO
117
118
119Song *m_pSong;                          ///< Current song
120PatternList* m_pNextPatterns;           ///< Next pattern (used only in Pattern mode)
121bool m_bAppendNextPattern;              ///< Add the next pattern to the list instead of replace.
122bool m_bDeleteNextPattern;              ///< Delete the next pattern from the list.
123
124
125PatternList* m_pPlayingPatterns;
126int m_nSongPos;                         ///< Is the position inside the song
127
128int m_nSelectedPatternNumber;
129int m_nSelectedInstrumentNumber;
130
131Instrument *m_pMetronomeInstrument = NULL;      ///< Metronome instrument
132
133
134// Buffers used in the process function
135unsigned m_nBufferSize = 0;
136float *m_pMainBuffer_L = NULL;
137float *m_pMainBuffer_R = NULL;
138bool m_bUseDefaultOuts = false;
139
140
141Hydrogen* hydrogenInstance = NULL;              ///< Hydrogen class instance (used for log)
142
143
144int  m_audioEngineState = STATE_UNINITIALIZED;  ///< Audio engine state
145
146
147
148#ifdef LADSPA_SUPPORT
149float m_fFXPeak_L[MAX_FX];
150float m_fFXPeak_R[MAX_FX];
151#endif
152
153
154int m_nPatternStartTick = -1;
155int m_nPatternTickPosition = 0;
156
157// used in findPatternInTick
158int m_nSongSizeInTicks = 0;
159
160struct timeval m_currentTickTime;
161
162unsigned long m_nRealtimeFrames = 0;
163
164
165
166
167// PROTOTYPES
168void    audioEngine_init();
169void    audioEngine_destroy();
170int     audioEngine_start( bool bLockEngine = false, unsigned nTotalFrames = 0 );
171void    audioEngine_stop( bool bLockEngine = false );
172void    audioEngine_setSong( Song *newSong );
173void    audioEngine_removeSong();
174void    audioEngine_noteOn( Note *note );
175void    audioEngine_noteOff( Note *note );
176int     audioEngine_process( uint32_t nframes, void *arg );
177inline void audioEngine_clearNoteQueue();
178inline void audioEngine_process_checkBPMChanged();
179inline void audioEngine_process_playNotes( unsigned long nframes );
180inline void audioEngine_process_transport();
181
182inline unsigned audioEngine_renderNote( Note* pNote, const unsigned& nBufferSize );
183inline int audioEngine_updateNoteQueue( unsigned nFrames );
184inline void audioEngine_prepNoteQueue();
185
186inline int findPatternInTick( int tick, bool loopMode, int *patternStartTick );
187
188void audioEngine_seek( long long nFrames, bool bLoopMode = false );
189
190void audioEngine_restartAudioDrivers();
191void audioEngine_startAudioDrivers();
192void audioEngine_stopAudioDrivers();
193
194/*
195inline unsigned long currentTime() {
196        struct timeval now;
197        gettimeofday(&now, NULL);
198        return now.tv_sec * 1000 + now.tv_usec / 1000;
199}
200*/
201
202
203inline timeval currentTime2()
204{
205        struct timeval now;
206        gettimeofday( &now, NULL );
207        return now;
208}
209
210
211
212inline int randomValue( int max )
213{
214        return rand() % max;
215}
216
217
218inline float getGaussian( float z )
219{
220        // gaussian distribution -- dimss
221        float x1, x2, w;
222        do {
223                x1 = 2.0 * ( ( ( float ) rand() ) / RAND_MAX ) - 1.0;
224                x2 = 2.0 * ( ( ( float ) rand() ) / RAND_MAX ) - 1.0;
225                w = x1 * x1 + x2 * x2;
226        } while ( w >= 1.0 );
227
228        w = sqrtf( ( -2.0 * logf( w ) ) / w );
229        return x1 * w * z + 0.0; // tunable
230}
231
232
233
234void audioEngine_raiseError( unsigned nErrorCode )
235{
236        EventQueue::get_instance()->push_event( EVENT_ERROR, nErrorCode );
237}
238
239
240
241void updateTickSize()
242{
243//      hydrogenInstance->infoLog("UpdateTickSize");
244        float sampleRate = ( float )m_pAudioDriver->getSampleRate();
245        m_pAudioDriver->m_transport.m_nTickSize = ( sampleRate * 60.0 /  m_pSong->__bpm / m_pSong->__resolution );
246}
247
248
249
250void audioEngine_init()
251{
252        _INFOLOG( "*** Hydrogen audio engine init ***" );
253
254        // check current state
255        if ( m_audioEngineState != STATE_UNINITIALIZED ) {
256                _ERRORLOG( "Error the audio engine is not in UNINITIALIZED state" );
257                AudioEngine::get_instance()->unlock();
258                return;
259        }
260
261        m_pSong = NULL;
262        m_pPlayingPatterns = new PatternList();
263        m_pNextPatterns = new PatternList();
264        m_nSongPos = -1;
265        m_nSelectedPatternNumber = 0;
266        m_nSelectedInstrumentNumber = 0;
267        m_nPatternTickPosition = 0;
268        m_pMetronomeInstrument = NULL;
269        m_pAudioDriver = NULL;
270
271        m_pMainBuffer_L = NULL;
272        m_pMainBuffer_R = NULL;
273
274//      for (unsigned i=0; i < MAX_INSTRUMENTS; ++i) {
275//              m_pTrackBuffers_L[i] = NULL;
276//              m_pTrackBuffers_R[i] = NULL;
277//      }
278
279        Preferences *preferences = Preferences::getInstance();
280        m_bUseDefaultOuts = preferences->m_bJackConnectDefaults;
281
282
283        srand( time( NULL ) );
284
285        // Create metronome instrument
286        QString sMetronomeFilename = QString( "%1/click.wav" ).arg( DataPath::get_data_path() );
287        m_pMetronomeInstrument = new Instrument( sMetronomeFilename, "metronome", new ADSR() );
288        m_pMetronomeInstrument->set_layer( new InstrumentLayer( Sample::load( sMetronomeFilename ) ), 0 );
289
290        // Change the current audio engine state
291        m_audioEngineState = STATE_INITIALIZED;
292
293        EventQueue::get_instance()->push_event( EVENT_STATE, STATE_INITIALIZED );
294}
295
296
297
298void audioEngine_destroy()
299{
300        AudioEngine::get_instance()->lock( "audioEngine_destroy" );
301        _INFOLOG( "*** Hydrogen audio engine shutdown ***" );
302
303        // check current state
304        if ( m_audioEngineState != STATE_INITIALIZED ) {
305                _ERRORLOG( "Error the audio engine is not in INITIALIZED state" );
306                return;
307        }
308        AudioEngine::get_instance()->get_sampler()->stop_playing_notes();
309
310        // delete all copied notes in the song notes queue
311        while(!m_songNoteQueue.empty()){
312                delete m_songNoteQueue.top();
313                m_songNoteQueue.pop();
314        }
315        // delete all copied notes in the midi notes queue
316        for ( unsigned i = 0; i < m_midiNoteQueue.size(); ++i ) {
317                Note *note = m_midiNoteQueue[i];
318                delete note;
319                note = NULL;
320        }
321        m_midiNoteQueue.clear();
322
323        // change the current audio engine state
324        m_audioEngineState = STATE_UNINITIALIZED;
325
326        EventQueue::get_instance()->push_event( EVENT_STATE, STATE_UNINITIALIZED );
327
328        delete m_pPlayingPatterns;
329        m_pPlayingPatterns = NULL;
330
331        delete m_pNextPatterns;
332        m_pNextPatterns = NULL;
333
334        delete m_pMetronomeInstrument;
335        m_pMetronomeInstrument = NULL;
336
337        AudioEngine::get_instance()->unlock();
338}
339
340
341
342
343
344/// Start playing
345/// return 0 = OK
346/// return -1 = NULL Audio Driver
347/// return -2 = Driver connect() error
348int audioEngine_start( bool bLockEngine, unsigned nTotalFrames )
349{
350        if ( bLockEngine ) {
351                AudioEngine::get_instance()->lock( "audioEngine_start" );
352        }
353
354        _INFOLOG( "[audioEngine_start]" );
355
356        // check current state
357        if ( m_audioEngineState != STATE_READY ) {
358                _ERRORLOG( "Error the audio engine is not in READY state" );
359                if ( bLockEngine ) {
360                        AudioEngine::get_instance()->unlock();
361                }
362                return 0;       // FIXME!!
363        }
364
365        //Preferences *preferencesMng = Preferences::getInstance();
366        m_fMasterPeak_L = 0.0f;
367        m_fMasterPeak_R = 0.0f;
368        m_pAudioDriver->m_transport.m_nFrames = nTotalFrames;   // reset total frames
369        m_nSongPos = -1;
370        m_nPatternStartTick = -1;
371        m_nPatternTickPosition = 0;
372
373        // prepare the tickSize for this song
374        updateTickSize();
375
376        // change the current audio engine state
377        m_audioEngineState = STATE_PLAYING;
378        EventQueue::get_instance()->push_event( EVENT_STATE, STATE_PLAYING );
379
380        if ( bLockEngine ) {
381                AudioEngine::get_instance()->unlock();
382        }
383        return 0; // per ora restituisco sempre OK
384}
385
386
387
388/// Stop the audio engine
389void audioEngine_stop( bool bLockEngine )
390{
391        if ( bLockEngine ) {
392                AudioEngine::get_instance()->lock( "audioEngine_stop" );
393        }
394        _INFOLOG( "[audioEngine_stop]" );
395
396        // check current state
397        if ( m_audioEngineState != STATE_PLAYING ) {
398                _ERRORLOG( "Error the audio engine is not in PLAYING state" );
399                if ( bLockEngine ) {
400                        AudioEngine::get_instance()->unlock();
401                }
402                return;
403        }
404
405        // change the current audio engine state
406        m_audioEngineState = STATE_READY;
407        EventQueue::get_instance()->push_event( EVENT_STATE, STATE_READY );
408
409        m_fMasterPeak_L = 0.0f;
410        m_fMasterPeak_R = 0.0f;
411//      m_nPatternTickPosition = 0;
412        m_nPatternStartTick = -1;
413
414        // delete all copied notes in the song notes queue
415        while(!m_songNoteQueue.empty()){
416                delete m_songNoteQueue.top();
417                m_songNoteQueue.pop();
418        }
419
420        /*      // delete all copied notes in the playing notes queue
421                for (unsigned i = 0; i < m_playingNotesQueue.size(); ++i) {
422                        Note *note = m_playingNotesQueue[i];
423                        delete note;
424                }
425                m_playingNotesQueue.clear();
426        */
427
428        // delete all copied notes in the midi notes queue
429        for ( unsigned i = 0; i < m_midiNoteQueue.size(); ++i ) {
430                Note *note = m_midiNoteQueue[i];
431                delete note;
432        }
433        m_midiNoteQueue.clear();
434
435
436        if ( bLockEngine ) {
437                AudioEngine::get_instance()->unlock();
438        }
439}
440
441//
442///  Update Tick size and frame position in the audio driver from Song->__bpm
443//
444inline void audioEngine_process_checkBPMChanged()
445{
446
447        if ( ( m_audioEngineState == STATE_READY ) || ( m_audioEngineState == STATE_PLAYING ) ) {
448
449                float fNewTickSize = m_pAudioDriver->getSampleRate() * 60.0 /  m_pSong->__bpm / m_pSong->__resolution;
450
451                if ( fNewTickSize != m_pAudioDriver->m_transport.m_nTickSize ) {
452                        // cerco di convertire ...
453                        float fTickNumber = ( float )m_pAudioDriver->m_transport.m_nFrames / ( float )m_pAudioDriver->m_transport.m_nTickSize;
454
455                        m_pAudioDriver->m_transport.m_nTickSize = fNewTickSize;
456
457                        if ( m_pAudioDriver->m_transport.m_nTickSize == 0 ) {
458                                return;
459                        }
460
461                        _WARNINGLOG( "Tempo change: Recomputing ticksize and frame position" );
462                        long long nNewFrames = ( long long )( fTickNumber * fNewTickSize );
463                        // update frame position
464                        m_pAudioDriver->m_transport.m_nFrames = nNewFrames;
465#ifdef JACK_SUPPORT
466                        if ( "JackOutput" == m_pAudioDriver->get_class_name() && m_audioEngineState == STATE_PLAYING ) {
467                                static_cast< JackOutput* >( m_pAudioDriver )->calculateFrameOffset();
468                        }
469#endif
470
471                        /*
472
473                                                // delete all copied notes in the song notes queue
474                                                while(!m_songNoteQueue.empty()){
475                                                        delete m_songNoteQueue.top();
476                                                        m_songNoteQueue.pop();
477                                                }
478
479                                                // send a note-off event to all notes present in the playing note queue
480                                                for ( int i = 0; i < m_playingNotesQueue.size(); ++i ) {
481                                                        Note *pNote = m_playingNotesQueue[ i ];
482                                                        pNote->m_pADSR->release();
483                                                }
484
485                                                // delete all copied notes in the midi notes queue
486                                                for (unsigned i = 0; i < m_midiNoteQueue.size(); ++i) {
487                                                        delete m_midiNoteQueue[i];
488                                                }
489                                                m_midiNoteQueue.clear();
490                        */
491                }
492        }
493}
494
495
496
497inline void audioEngine_process_playNotes( unsigned long nframes )
498{
499        unsigned int framepos;
500
501        if (  m_audioEngineState == STATE_PLAYING ) {
502                framepos = m_pAudioDriver->m_transport.m_nFrames;
503        } else {
504                // use this to support realtime events when not playing
505                framepos = m_nRealtimeFrames;
506        }
507
508        // leggo da m_songNoteQueue
509        while (!m_songNoteQueue.empty()) {
510                Note *pNote = m_songNoteQueue.top();
511
512                // verifico se la nota rientra in questo ciclo
513                unsigned int noteStartInFrames = (int)( pNote->get_position() * m_pAudioDriver->m_transport.m_nTickSize );
514
515
516                // if there is a negative Humanize delay, take into account so we don't miss the time slice.
517                // ignore positive delay, or we might end the queue processing prematurely based on NoteQueue placement.
518                // the sampler handles positive delay.
519                if (pNote->m_nHumanizeDelay < 0) {
520                        noteStartInFrames += pNote->m_nHumanizeDelay;
521                }
522
523                // m_nTotalFrames <= NotePos < m_nTotalFrames + bufferSize
524                bool isNoteStart = ( ( noteStartInFrames >= framepos ) && ( noteStartInFrames < ( framepos + nframes ) ) );
525                bool isOldNote = noteStartInFrames < framepos;
526                if ( isNoteStart || isOldNote ) {
527
528                        // Humanize - Velocity parameter
529                        if ( m_pSong->get_humanize_velocity_value() != 0 ) {
530                                float random = m_pSong->get_humanize_velocity_value() * getGaussian( 0.2 );
531                                pNote->set_velocity( pNote->get_velocity() + ( random - ( m_pSong->get_humanize_velocity_value() / 2.0 ) ) );
532                                if ( pNote->get_velocity() > 1.0 ) {
533                                        pNote->set_velocity( 1.0 );
534                                } else if ( pNote->get_velocity() < 0.0 ) {
535                                        pNote->set_velocity( 0.0 );
536                                }
537                        }
538
539                        // Random Pitch ;)
540                        const float fMaxPitchDeviation = 2.0;
541                        pNote->set_pitch( pNote->get_pitch() + ( fMaxPitchDeviation * getGaussian( 0.2 ) - fMaxPitchDeviation / 2.0 ) * pNote->get_instrument()->get_random_pitch_factor() );
542
543                        AudioEngine::get_instance()->get_sampler()->note_on( pNote );   // aggiungo la nota alla lista di note da eseguire
544                        m_songNoteQueue.pop();                  // rimuovo la nota dalla lista di note
545
546                        // raise noteOn event
547                        int nInstrument = m_pSong->get_instrument_list()->get_pos( pNote->get_instrument() );
548                        EventQueue::get_instance()->push_event( EVENT_NOTEON, nInstrument );
549                        continue;
550                } else {
551                        // la nota non andra' in esecuzione
552                        break;
553                }
554        }
555
556}
557
558
559void audioEngine_seek( long long nFrames, bool bLoopMode )
560{
561        if ( m_pAudioDriver->m_transport.m_nFrames == nFrames ) {
562                return;
563        }
564
565        if ( nFrames < 0 ) {
566                _ERRORLOG( "nFrames < 0" );
567        }
568
569        char tmp[200];
570        sprintf( tmp, "seek in %lld (old pos = %d)", nFrames, ( int )m_pAudioDriver->m_transport.m_nFrames );
571        _INFOLOG( tmp );
572
573        m_pAudioDriver->m_transport.m_nFrames = nFrames;
574
575        int tickNumber_start = ( unsigned )( m_pAudioDriver->m_transport.m_nFrames / m_pAudioDriver->m_transport.m_nTickSize );
576//      sprintf(tmp, "[audioEngine_seek()] tickNumber_start = %d", tickNumber_start);
577//      hydrogenInstance->infoLog(tmp);
578
579        bool loop = m_pSong->is_loop_enabled();
580
581        if ( bLoopMode ) {
582                loop = true;
583        }
584       
585        m_nSongPos = findPatternInTick( tickNumber_start, loop, &m_nPatternStartTick );
586//      sprintf(tmp, "[audioEngine_seek()] m_nSongPos = %d", m_nSongPos);
587//      hydrogenInstance->infoLog(tmp);
588
589        audioEngine_clearNoteQueue();
590}
591
592
593
594inline void audioEngine_process_transport()
595{
596        if ( ( m_audioEngineState == STATE_READY ) || ( m_audioEngineState == STATE_PLAYING ) ) {
597                m_pAudioDriver->updateTransportInfo();
598                unsigned long nNewFrames = m_pAudioDriver->m_transport.m_nFrames;
599
600                // ??? audioEngine_seek returns IMMEDIATELY when nNewFrames == m_pAudioDriver->m_transport.m_nFrames ???
601//              audioEngine_seek( nNewFrames, true );
602
603                switch ( m_pAudioDriver->m_transport.m_status ) {
604                case TransportInfo::ROLLING:
605
606//                              hydrogenInstance->infoLog( "[audioEngine_process_transport] ROLLING - frames: " + to_string(m_pAudioDriver->m_transport.m_nFrames) );
607                        if ( m_audioEngineState == STATE_READY ) {
608                                //hydrogenInstance->infoLog( "[audioEngine_process_transport] first start frames is " + to_string(m_pAudioDriver->m_transport.m_nFrames) );
609                                audioEngine_start( false, nNewFrames ); // no engine lock
610                        }
611
612                        if ( m_pSong->__bpm != m_pAudioDriver->m_transport.m_nBPM ) {
613                                _INFOLOG( QString( "song bpm: (%1) gets transport bpm: (%2)" ).arg( m_pSong->__bpm ).arg( m_pAudioDriver->m_transport.m_nBPM ) );
614
615                                m_pSong->__bpm = m_pAudioDriver->m_transport.m_nBPM;
616                        }
617
618                        m_nRealtimeFrames = m_pAudioDriver->m_transport.m_nFrames;
619                        break;
620
621
622                case TransportInfo::STOPPED:
623
624//                              hydrogenInstance->infoLog( "[audioEngine_process_transport] STOPPED - frames: " + to_string(m_pAudioDriver->m_transport.m_nFrames) );
625                        if ( m_audioEngineState == STATE_PLAYING ) {
626                                audioEngine_stop( false );      // no engine lock
627                        }
628
629                        if ( m_pSong->__bpm != m_pAudioDriver->m_transport.m_nBPM ) {
630                                m_pSong->__bpm = m_pAudioDriver->m_transport.m_nBPM;
631                        }
632
633                        // go ahead and increment the realtimeframes by buffersize
634                        // to support our realtime keyboard and midi event timing
635                        m_nRealtimeFrames += m_nBufferSize;
636                        break;
637                }
638        }
639}
640
641
642
643void audioEngine_clearNoteQueue()
644{
645        //_INFOLOG( "clear notes...");
646
647        while (!m_songNoteQueue.empty()) {       // delete all copied notes in the song notes queue
648                delete m_songNoteQueue.top();
649                m_songNoteQueue.pop();
650        }
651
652        /*      for (unsigned i = 0; i < m_playingNotesQueue.size(); ++i) {     // delete all copied notes in the playing notes queue
653                        delete m_playingNotesQueue[i];
654                }
655                m_playingNotesQueue.clear();
656        */
657        AudioEngine::get_instance()->get_sampler()->stop_playing_notes();
658
659        for ( unsigned i = 0; i < m_midiNoteQueue.size(); ++i ) {       // delete all copied notes in the midi notes queue
660                delete m_midiNoteQueue[i];
661        }
662        m_midiNoteQueue.clear();
663
664}
665
666
667
668/// Clear all audio buffers
669inline void audioEngine_process_clearAudioBuffers( uint32_t nFrames )
670{
671        if ( m_pMainBuffer_L ) {
672                memset( m_pMainBuffer_L, 0, nFrames * sizeof( float ) );        // clear main out Left
673        }
674        if ( m_pMainBuffer_R ) {
675                memset( m_pMainBuffer_R, 0, nFrames * sizeof( float ) );        // clear main out Right
676        }
677
678        if ( ( m_audioEngineState == STATE_READY ) || ( m_audioEngineState == STATE_PLAYING ) ) {
679#ifdef LADSPA_SUPPORT
680                Effects* pEffects = Effects::getInstance();
681                for ( unsigned i = 0; i < MAX_FX; ++i ) {       // clear FX buffers
682                        LadspaFX* pFX = pEffects->getLadspaFX( i );
683                        if ( pFX ) {
684                                assert( pFX->m_pBuffer_L );
685                                assert( pFX->m_pBuffer_R );
686                                memset( pFX->m_pBuffer_L, 0, nFrames * sizeof( float ) );
687                                memset( pFX->m_pBuffer_R, 0, nFrames * sizeof( float ) );
688                        }
689                }
690#endif
691        }
692}
693
694/// Main audio processing function. Called by audio drivers.
695int audioEngine_process( uint32_t nframes, void *arg )
696{
697        UNUSED( arg );
698
699        if ( AudioEngine::get_instance()->try_lock( "audioEngine_process" ) == false ) {
700                return 0;
701        }
702
703        timeval startTimeval = currentTime2();
704
705        if ( m_nBufferSize != nframes ) {
706                _INFOLOG( QString( "Buffer size changed. Old size = %1, new size = %2" ).arg( m_nBufferSize ).arg( nframes ) );
707                m_nBufferSize = nframes;
708        }
709
710        audioEngine_process_transport();                // m_pAudioDriver->bpm updates Song->__bpm. (!!(Calls audioEngine_seek))
711        audioEngine_process_clearAudioBuffers( nframes );
712        audioEngine_process_checkBPMChanged();          // m_pSong->__bpm decides tick size
713
714        bool sendPatternChange = false;
715        // always update note queue.. could come from pattern or realtime input (midi, keyboard)
716        int res2 = audioEngine_updateNoteQueue( nframes );      // update the notes queue
717        if ( res2 == -1 ) {     // end of song
718                _INFOLOG( "End of song received, calling engine_stop()" );
719                AudioEngine::get_instance()->unlock();
720                m_pAudioDriver->stop();
721                m_pAudioDriver->locate( 0 );    // locate 0, reposition from start of the song
722
723                if ( ( m_pAudioDriver->get_class_name() == "DiskWriterDriver" ) || ( m_pAudioDriver->get_class_name() == "FakeDriver" ) ) {
724                        _INFOLOG( "End of song." );
725                        return 1;       // kill the audio AudioDriver thread
726                }
727#ifdef JACK_SUPPORT
728                else if ( m_pAudioDriver->get_class_name() == "JackOutput" ) {
729                        // Do something clever :-s ... Jakob Lund
730                        // Mainly to keep sync with Ardour.
731                        static_cast<JackOutput*>(m_pAudioDriver)->locateInNCycles( 0 );
732                }
733#endif
734
735
736                return 0;
737        } else if ( res2 == 2 ) {       // send pattern change
738                sendPatternChange = true;
739        }
740
741
742        // play all notes
743        audioEngine_process_playNotes( nframes );
744
745
746        timeval renderTime_start = currentTime2();
747
748        // SAMPLER
749        AudioEngine::get_instance()->get_sampler()->process( nframes, m_pSong );
750        float* out_L = AudioEngine::get_instance()->get_sampler()->__main_out_L;
751        float* out_R = AudioEngine::get_instance()->get_sampler()->__main_out_R;
752        for ( unsigned i = 0; i < nframes; ++i ) {
753                m_pMainBuffer_L[ i ] += out_L[ i ];
754                m_pMainBuffer_R[ i ] += out_R[ i ];
755        }
756
757        // SYNTH
758        AudioEngine::get_instance()->get_synth()->process( nframes );
759        out_L = AudioEngine::get_instance()->get_synth()->m_pOut_L;
760        out_R = AudioEngine::get_instance()->get_synth()->m_pOut_R;
761        for ( unsigned i = 0; i < nframes; ++i ) {
762                m_pMainBuffer_L[ i ] += out_L[ i ];
763                m_pMainBuffer_R[ i ] += out_R[ i ];
764        }
765
766
767        timeval renderTime_end = currentTime2();
768
769
770
771        timeval ladspaTime_start = renderTime_end;
772#ifdef LADSPA_SUPPORT
773        // Process LADSPA FX
774        if ( ( m_audioEngineState == STATE_READY ) || ( m_audioEngineState == STATE_PLAYING ) ) {
775                for ( unsigned nFX = 0; nFX < MAX_FX; ++nFX ) {
776                        LadspaFX *pFX = Effects::getInstance()->getLadspaFX( nFX );
777                        if ( ( pFX ) && ( pFX->isEnabled() ) ) {
778                                pFX->processFX( nframes );
779                                float *buf_L = NULL;
780                                float *buf_R = NULL;
781                                if ( pFX->getPluginType() == LadspaFX::STEREO_FX ) {    // STEREO FX
782                                        buf_L = pFX->m_pBuffer_L;
783                                        buf_R = pFX->m_pBuffer_R;
784                                } else { // MONO FX
785                                        buf_L = pFX->m_pBuffer_L;
786                                        buf_R = buf_L;
787                                }
788                                for ( unsigned i = 0; i < nframes; ++i ) {
789                                        m_pMainBuffer_L[ i ] += buf_L[ i ];
790                                        m_pMainBuffer_R[ i ] += buf_R[ i ];
791                                        if ( buf_L[ i ] > m_fFXPeak_L[nFX] )    m_fFXPeak_L[nFX] = buf_L[ i ];
792                                        if ( buf_R[ i ] > m_fFXPeak_R[nFX] )    m_fFXPeak_R[nFX] = buf_R[ i ];
793                                }
794                        }
795                }
796        }
797#endif
798        timeval ladspaTime_end = currentTime2();
799
800        // update master peaks
801        float val_L;
802        float val_R;
803        if ( m_audioEngineState == STATE_PLAYING || m_audioEngineState == STATE_READY ) {
804                for ( unsigned i = 0; i < nframes; ++i ) {
805                        val_L = m_pMainBuffer_L[i];
806                        val_R = m_pMainBuffer_R[i];
807                        if ( val_L > m_fMasterPeak_L ) {
808                                m_fMasterPeak_L = val_L;
809                        }
810                        if ( val_R > m_fMasterPeak_R ) {
811                                m_fMasterPeak_R = val_R;
812                        }
813                }
814        }
815
816        // update total frames number
817        if ( m_audioEngineState == STATE_PLAYING ) {
818                m_pAudioDriver->m_transport.m_nFrames += nframes;
819        }
820
821//      float fRenderTime = (renderTime_end.tv_sec - renderTime_start.tv_sec) * 1000.0 + (renderTime_end.tv_usec - renderTime_start.tv_usec) / 1000.0;
822        float fLadspaTime = ( ladspaTime_end.tv_sec - ladspaTime_start.tv_sec ) * 1000.0 + ( ladspaTime_end.tv_usec - ladspaTime_start.tv_usec ) / 1000.0;
823
824
825        timeval finishTimeval = currentTime2();
826        m_fProcessTime = ( finishTimeval.tv_sec - startTimeval.tv_sec ) * 1000.0 + ( finishTimeval.tv_usec - startTimeval.tv_usec ) / 1000.0;
827
828        float sampleRate = ( float )m_pAudioDriver->getSampleRate();
829        m_fMaxProcessTime = 1000.0 / ( sampleRate / nframes );
830
831
832        //DEBUG
833        if ( m_fProcessTime > m_fMaxProcessTime ) {
834                _WARNINGLOG( "" );
835                _WARNINGLOG( "----XRUN----" );
836                _WARNINGLOG( QString( "XRUN of %1 msec (%2 > %3)" ).arg( ( m_fProcessTime - m_fMaxProcessTime ) ).arg( m_fProcessTime ).arg( m_fMaxProcessTime ) );
837                _WARNINGLOG( QString( "Ladspa process time = %1" ).arg( fLadspaTime ) );
838                _WARNINGLOG( "------------" );
839                _WARNINGLOG( "" );
840                // raise xRun event
841                EventQueue::get_instance()->push_event( EVENT_XRUN, -1 );
842        }
843
844        AudioEngine::get_instance()->unlock();
845
846        if ( sendPatternChange ) {
847                EventQueue::get_instance()->push_event( EVENT_PATTERN_CHANGED, -1 );
848        }
849
850        return 0;
851}
852
853
854
855
856
857void audioEngine_setupLadspaFX( unsigned nBufferSize )
858{
859        //_INFOLOG( "buffersize=" + to_string(nBufferSize) );
860
861        if ( m_pSong == NULL ) {
862                //_INFOLOG( "m_pSong=NULL" );
863                return;
864        }
865        if ( nBufferSize == 0 ) {
866                _ERRORLOG( "nBufferSize=0" );
867                return;
868        }
869
870#ifdef LADSPA_SUPPORT
871        for ( unsigned nFX = 0; nFX < MAX_FX; ++nFX ) {
872                LadspaFX *pFX = Effects::getInstance()->getLadspaFX( nFX );
873                if ( pFX == NULL ) {
874                        return;
875                }
876
877                pFX->deactivate();
878
879//              delete[] pFX->m_pBuffer_L;
880//              pFX->m_pBuffer_L = NULL;
881//              delete[] pFX->m_pBuffer_R;
882//              pFX->m_pBuffer_R = NULL;
883//              if ( nBufferSize != 0 ) {
884                //pFX->m_nBufferSize = nBufferSize;
885                //pFX->m_pBuffer_L = new float[ nBufferSize ];
886                //pFX->m_pBuffer_R = new float[ nBufferSize ];
887//              }
888
889                Effects::getInstance()->getLadspaFX( nFX )->connectAudioPorts(
890                    pFX->m_pBuffer_L,
891                    pFX->m_pBuffer_R,
892                    pFX->m_pBuffer_L,
893                    pFX->m_pBuffer_R
894                );
895                pFX->activate();
896        }
897#endif
898}
899
900
901
902void audioEngine_renameJackPorts()
903{
904#ifdef JACK_SUPPORT
905        // renames jack ports
906        if ( m_pSong == NULL ) {
907                return;
908        }
909        if ( m_pAudioDriver->get_class_name() == "JackOutput" ) {
910                static_cast< JackOutput* >( m_pAudioDriver )->makeTrackOutputs( m_pSong );
911        }
912
913        AudioEngine::get_instance()->get_sampler()->makeTrackOutputQueues();
914
915#endif
916}
917
918
919
920void audioEngine_setSong( Song *newSong )
921{
922        _WARNINGLOG( QString( "Set song: %1" ).arg( newSong->__name ) );
923
924        AudioEngine::get_instance()->lock( "audioEngine_setSong" );
925
926        if ( m_audioEngineState == STATE_PLAYING ) {
927                m_pAudioDriver->stop();
928                audioEngine_stop( false );
929        }
930
931        // check current state
932        if ( m_audioEngineState != STATE_PREPARED ) {
933                _ERRORLOG( "Error the audio engine is not in PREPARED state" );
934        }
935
936        m_pPlayingPatterns->clear();
937        m_pNextPatterns->clear();
938
939        EventQueue::get_instance()->push_event( EVENT_SELECTED_PATTERN_CHANGED, -1 );
940        EventQueue::get_instance()->push_event( EVENT_PATTERN_CHANGED, -1 );
941        EventQueue::get_instance()->push_event( EVENT_SELECTED_INSTRUMENT_CHANGED, -1 );
942
943        //sleep( 1 );
944
945        audioEngine_clearNoteQueue();
946
947        assert( m_pSong == NULL );
948        m_pSong = newSong;
949
950        // setup LADSPA FX
951        audioEngine_setupLadspaFX( m_pAudioDriver->getBufferSize() );
952
953        // update ticksize
954        audioEngine_process_checkBPMChanged();
955
956        // find the first pattern and set as current
957        if ( m_pSong->get_pattern_list()->get_size() > 0 ) {
958                m_pPlayingPatterns->add( m_pSong->get_pattern_list()->get( 0 ) );
959        }
960
961
962        audioEngine_renameJackPorts();
963
964        m_pAudioDriver->setBpm( m_pSong->__bpm );
965
966        // change the current audio engine state
967        m_audioEngineState = STATE_READY;
968
969        m_pAudioDriver->locate( 0 );
970
971        AudioEngine::get_instance()->unlock();
972
973        EventQueue::get_instance()->push_event( EVENT_STATE, STATE_READY );
974}
975
976
977
978void audioEngine_removeSong()
979{
980        AudioEngine::get_instance()->lock( "audioEngine_removeSong" );
981
982        if ( m_audioEngineState == STATE_PLAYING ) {
983                m_pAudioDriver->stop();
984                audioEngine_stop( false );
985        }
986
987        // check current state
988        if ( m_audioEngineState != STATE_READY ) {
989                _ERRORLOG( "Error the audio engine is not in READY state" );
990                AudioEngine::get_instance()->unlock();
991                return;
992        }
993
994        m_pSong = NULL;
995        m_pPlayingPatterns->clear();
996        m_pNextPatterns->clear();
997
998        audioEngine_clearNoteQueue();
999
1000        // change the current audio engine state
1001        m_audioEngineState = STATE_PREPARED;
1002        AudioEngine::get_instance()->unlock();
1003
1004        EventQueue::get_instance()->push_event( EVENT_STATE, STATE_PREPARED );
1005}
1006
1007
1008
1009// return -1 = end of song
1010// return 2 = send pattern changed event!!
1011inline int audioEngine_updateNoteQueue( unsigned nFrames )
1012{
1013        static int nLastTick = -1;
1014        bool bSendPatternChange = false;
1015        int nMaxTimeHumanize = 2000;
1016        int nLeadLagFactor = m_pAudioDriver->m_transport.m_nTickSize * 5;  // 5 ticks
1017
1018        unsigned int framepos;
1019        if (  m_audioEngineState == STATE_PLAYING ) {
1020                framepos = m_pAudioDriver->m_transport.m_nFrames;
1021        } else {
1022                // use this to support realtime events when not playing
1023                framepos = m_nRealtimeFrames;
1024        }
1025
1026        int tickNumber_start = 0;
1027
1028        // We need to look ahead in the song for notes with negative offsets from LeadLag or Humanize.
1029        // When starting from the beginning, we prime the note queue with notes between 0 and nFrames
1030        // plus lookahead. lookahead should be equal or greater than the nLeadLagFactor + nMaxTimeHumanize.
1031        int lookahead = nLeadLagFactor + nMaxTimeHumanize + 1;
1032        if ( framepos == 0 || ( m_audioEngineState == STATE_PLAYING && m_pSong->get_mode() == Song::SONG_MODE && m_nSongPos == -1 ) ) {
1033                tickNumber_start = (int)( framepos / m_pAudioDriver->m_transport.m_nTickSize );
1034        }
1035        else {
1036                tickNumber_start = (int)( (framepos + lookahead) / m_pAudioDriver->m_transport.m_nTickSize );
1037        }
1038        int tickNumber_end = (int)( (framepos + nFrames + lookahead) / m_pAudioDriver->m_transport.m_nTickSize );
1039
1040        int tick = tickNumber_start;
1041
1042//      _WARNINGLOG( "Lookahead: " + to_string( lookahead /  m_pAudioDriver->m_transport.m_nTickSize ) );
1043        // get initial timestamp for first tick
1044        gettimeofday( &m_currentTickTime, NULL );
1045       
1046
1047        while ( tick <= tickNumber_end ) {
1048                if ( tick == nLastTick ) {
1049                        ++tick;
1050                        continue;
1051                } else {
1052                        nLastTick = tick;
1053                }
1054
1055
1056                // midi events now get put into the m_songNoteQueue as well, based on their timestamp
1057                while ( m_midiNoteQueue.size() > 0 ) {
1058                        Note *note = m_midiNoteQueue[0];
1059
1060                        if ( ( int )note->get_position() <= tick ) {
1061                                // printf ("tick=%d  pos=%d\n", tick, note->getPosition());
1062                                m_midiNoteQueue.pop_front();
1063                                m_songNoteQueue.push( note );
1064                        } else {
1065                                break;
1066                        }
1067                }
1068
1069                if (  m_audioEngineState != STATE_PLAYING ) {
1070                        // only keep going if we're playing
1071                        continue;
1072                }
1073
1074//              if ( m_nPatternStartTick == -1 ) { // for debugging pattern mode :s
1075//                      _WARNINGLOG( "m_nPatternStartTick == -1; tick = " + to_string( tick ) );
1076//              }
1077
1078
1079                // SONG MODE
1080                if ( m_pSong->get_mode() == Song::SONG_MODE ) {
1081                        if ( m_pSong->get_pattern_group_vector()->size() == 0 ) {
1082                                // there's no song!!
1083                                _ERRORLOG( "no patterns in song." );
1084                                m_pAudioDriver->stop();
1085                                return -1;
1086                        }
1087
1088                        m_nSongPos = findPatternInTick( tick, m_pSong->is_loop_enabled(), &m_nPatternStartTick );
1089                        if ( m_nSongSizeInTicks != 0 ) {
1090                                m_nPatternTickPosition = ( tick - m_nPatternStartTick ) % m_nSongSizeInTicks;
1091                        } else {
1092                                m_nPatternTickPosition = tick - m_nPatternStartTick;
1093                        }
1094
1095                        if ( m_nPatternTickPosition == 0 ) {
1096                                bSendPatternChange = true;
1097                        }
1098
1099                        //PatternList *pPatternList = (*(m_pSong->getPatternGroupVector()))[m_nSongPos];
1100                        if ( m_nSongPos == -1 ) {
1101                                _INFOLOG( "song pos = -1" );
1102                                if ( m_pSong->is_loop_enabled() == true ) {     // check if the song loop is enabled
1103                                        m_nSongPos = findPatternInTick( 0, true, &m_nPatternStartTick );
1104                                } else {
1105                                        _INFOLOG( "End of Song" );
1106                                        return -1;
1107                                }
1108                        }
1109                        PatternList *pPatternList = ( *( m_pSong->get_pattern_group_vector() ) )[m_nSongPos];
1110                        // copio tutti i pattern
1111                        m_pPlayingPatterns->clear();
1112                        if ( pPatternList ) {
1113                                for ( unsigned i = 0; i < pPatternList->get_size(); ++i ) {
1114                                        m_pPlayingPatterns->add( pPatternList->get( i ) );
1115                                }
1116                        }
1117                }
1118               
1119                // PATTERN MODE
1120                else if ( m_pSong->get_mode() == Song::PATTERN_MODE )   {
1121                        //hydrogenInstance->warningLog( "pattern mode not implemented yet" );
1122
1123                        // per ora considero solo il primo pattern, se ce ne saranno piu' di uno
1124                        // bisognera' prendere quello piu' piccolo
1125
1126                        //m_nPatternTickPosition = tick % m_pCurrentPattern->getSize();
1127                        int nPatternSize = MAX_NOTES;
1128
1129                       
1130                        if ( Preferences::getInstance()->patternModePlaysSelected() )
1131                        {
1132                                m_pPlayingPatterns->clear();
1133                                Pattern * pSelectedPattern = m_pSong->get_pattern_list()->get(m_nSelectedPatternNumber);
1134                                m_pPlayingPatterns->add( pSelectedPattern );
1135                        }
1136
1137
1138                        if ( m_pPlayingPatterns->get_size() != 0 ) {
1139                                Pattern *pFirstPattern = m_pPlayingPatterns->get( 0 );
1140                                nPatternSize = pFirstPattern->get_lenght();
1141                        }
1142
1143                        if ( nPatternSize == 0 ) {
1144                                _ERRORLOG( "nPatternSize == 0" );
1145                        }
1146
1147                        if ( ( tick == m_nPatternStartTick + nPatternSize ) || ( m_nPatternStartTick == -1 ) ) {
1148                                if ( m_pNextPatterns->get_size() > 0 ) {
1149                                        //hydrogenInstance->errorLog( "[audioEngine_updateNoteQueue] Aggiorno con nextpattern: " + to_string( (int)m_pNextPattern ) );
1150                                        /*                                      if ( m_bDeleteNextPattern ) {
1151                                                                                        m_pPlayingPatterns->del( m_pNextPattern );
1152                                                                                }
1153                                                                                else {
1154                                                                                        if ( m_bAppendNextPattern == false ) {
1155                                                                                                m_pPlayingPatterns->clear();
1156                                                                                        }
1157                                                                                        m_pPlayingPatterns->add( m_pNextPattern );
1158                                                                                }*/
1159//                                      _WARNINGLOG( "uh-oh, next patterns..." );
1160                                        Pattern * p;
1161                                        for ( uint i = 0; i < m_pNextPatterns->get_size(); i++ ) {
1162                                                p = m_pNextPatterns->get( i );
1163//                                              _WARNINGLOG( QString( "Got pattern # %1" ).arg( i + 1 ) );
1164                                                // if the pattern isn't playing already, start it now.
1165                                                if ( ( m_pPlayingPatterns->del( p ) ) == NULL ) {
1166                                                        m_pPlayingPatterns->add( p );
1167                                                }
1168                                        }
1169                                        m_pNextPatterns->clear();
1170                                        bSendPatternChange = true;
1171                                }
1172                                if ( m_nPatternStartTick == -1 ) {
1173                                        m_nPatternStartTick = tick - (tick % nPatternSize);
1174//                                      _WARNINGLOG( "set Pattern Start Tick to " + to_string( m_nPatternStartTick ) );
1175                                } else {
1176                                        m_nPatternStartTick = tick;
1177                                }
1178                        }
1179                        m_nPatternTickPosition = tick - m_nPatternStartTick;
1180                        if ( m_nPatternTickPosition > nPatternSize ) {
1181                                m_nPatternTickPosition = tick % nPatternSize;
1182                        }
1183                }
1184
1185                // metronome
1186//              if (  ( m_nPatternStartTick == tick ) || ( ( tick - m_nPatternStartTick ) % 48 == 0 ) ) {
1187                if ( m_nPatternTickPosition % 48 == 0 ) {
1188                        float fPitch;
1189                        float fVelocity;
1190//                      _INFOLOG( "Beat: " + to_string(m_nPatternTickPosition / 48 + 1) + "@ " + to_string( tick ) );
1191                        if ( m_nPatternTickPosition == 0 ) {
1192                                fPitch = 3;
1193                                fVelocity = 1.0;
1194                                EventQueue::get_instance()->push_event( EVENT_METRONOME, 1 );
1195                        } else {
1196                                fPitch = 0;
1197                                fVelocity = 0.8;
1198                                EventQueue::get_instance()->push_event( EVENT_METRONOME, 0 );
1199                        }
1200                        if ( Preferences::getInstance()->m_bUseMetronome ) {
1201                                m_pMetronomeInstrument->set_volume( Preferences::getInstance()->m_fMetronomeVolume );
1202
1203                                Note *pMetronomeNote = new Note( m_pMetronomeInstrument, tick, fVelocity, 0.5, 0.5, -1, fPitch );
1204                                m_songNoteQueue.push( pMetronomeNote );
1205                        }
1206                }
1207
1208
1209
1210                // update the notes queue
1211                if ( m_pPlayingPatterns->get_size() != 0 ) {
1212                        for ( unsigned nPat = 0; nPat < m_pPlayingPatterns->get_size(); ++nPat ) {
1213                                Pattern *pPattern = m_pPlayingPatterns->get( nPat );
1214                                assert( pPattern != NULL );
1215
1216                                std::multimap <int, Note*>::iterator pos;
1217                                for ( pos = pPattern->note_map.lower_bound( m_nPatternTickPosition ); pos != pPattern->note_map.upper_bound( m_nPatternTickPosition ); ++pos ) {
1218                                        Note *pNote = pos->second;
1219                                        if ( pNote ) {
1220                                                int nOffset = 0;
1221
1222                                                // Swing
1223                                                float fSwingFactor = m_pSong->get_swing_factor();
1224                                                if ( ( ( m_nPatternTickPosition % 12 ) == 0 ) && ( ( m_nPatternTickPosition % 24 ) != 0 ) ) {   // da l'accento al tick 4, 12, 20, 36...
1225                                                        nOffset += ( int )( ( 6.0 * m_pAudioDriver->m_transport.m_nTickSize ) * fSwingFactor );
1226                                                }
1227
1228                                                // Humanize - Time parameter
1229                                                if ( m_pSong->get_humanize_time_value() != 0 ) {
1230                                                        nOffset += ( int )( (getGaussian( 0.3 ) * m_pSong->get_humanize_time_value()  * nMaxTimeHumanize ) );
1231                                                }
1232                                                //~
1233                                                // Lead or Lag - timing parameter
1234                                                nOffset += (int) (pNote->get_leadlag() * nLeadLagFactor);
1235                                                //~
1236
1237                                                // cannot play note before 0 frame
1238                                                if (tick + nOffset / m_pAudioDriver->m_transport.m_nTickSize < tickNumber_start ) {
1239                                                        _INFOLOG(" offset before 0 frame ");
1240                                                        nOffset = tickNumber_start - (int) (tick * m_pAudioDriver->m_transport.m_nTickSize);
1241                                                }
1242                                                Note *pCopiedNote = new Note( pNote );
1243                                                pCopiedNote->set_position( tick );
1244
1245                                                pCopiedNote->m_nHumanizeDelay = nOffset;        // humanize time
1246                                                m_songNoteQueue.push( pCopiedNote );
1247                                                //pCopiedNote->dumpInfo();
1248                                        }
1249                                }
1250                        }
1251                }
1252                ++tick;
1253        }
1254       
1255
1256        // audioEngine_process must send the pattern change event after mutex unlock
1257        if ( bSendPatternChange ) {
1258                return 2;
1259        }
1260        return 0;
1261}
1262
1263
1264
1265/// restituisce l'indice relativo al patternGroup in base al tick
1266inline int findPatternInTick( int nTick, bool bLoopMode, int *pPatternStartTick )
1267{
1268        assert( m_pSong );
1269
1270        int nTotalTick = 0;
1271        m_nSongSizeInTicks = 0;
1272
1273        std::vector<PatternList*> *pPatternColumns = m_pSong->get_pattern_group_vector();
1274        int nColumns = pPatternColumns->size();
1275
1276        int nPatternSize;
1277        for ( int i = 0; i < nColumns; ++i ) {
1278                PatternList *pColumn = ( *pPatternColumns )[ i ];
1279                if ( pColumn->get_size() != 0 ) {
1280                        // tengo in considerazione solo il primo pattern. I pattern nel gruppo devono avere la stessa lunghezza.
1281                        nPatternSize = pColumn->get( 0 )->get_lenght();
1282                } else {
1283                        nPatternSize = MAX_NOTES;
1284                }
1285
1286                if ( ( nTick >= nTotalTick ) && ( nTick < nTotalTick + nPatternSize ) ) {
1287                        ( *pPatternStartTick ) = nTotalTick;
1288                        return i;
1289                }
1290                nTotalTick += nPatternSize;
1291        }
1292
1293        if ( bLoopMode ) {
1294                m_nSongSizeInTicks = nTotalTick;
1295                int nLoopTick = 0;
1296                if ( m_nSongSizeInTicks != 0 ) {
1297                        nLoopTick = nTick % m_nSongSizeInTicks;
1298                }
1299                nTotalTick = 0;
1300                for ( int i = 0; i < nColumns; ++i ) {
1301                        PatternList *pColumn = ( *pPatternColumns )[ i ];
1302                        if ( pColumn->get_size() != 0 ) {
1303                                // tengo in considerazione solo il primo pattern. I pattern nel gruppo devono avere la stessa lunghezza.
1304                                nPatternSize = pColumn->get( 0 )->get_lenght();
1305                        } else {
1306                                nPatternSize = MAX_NOTES;
1307                        }
1308
1309                        if ( ( nLoopTick >= nTotalTick ) && ( nLoopTick < nTotalTick + nPatternSize ) ) {
1310                                ( *pPatternStartTick ) = nTotalTick;
1311                                return i;
1312                        }
1313                        nTotalTick += nPatternSize;
1314                }
1315        }
1316
1317        char tmp[200];
1318        sprintf( tmp, "[findPatternInTick] tick = %d. No pattern found", nTick );
1319        _ERRORLOG( tmp );
1320        return -1;
1321}
1322
1323
1324
1325void audioEngine_noteOn( Note *note )
1326{
1327        // check current state
1328        if ( ( m_audioEngineState != STATE_READY ) && ( m_audioEngineState != STATE_PLAYING ) ) {
1329                _ERRORLOG( "Error the audio engine is not in READY state" );
1330                delete note;
1331                return;
1332        }
1333
1334        m_midiNoteQueue.push_back( note );
1335}
1336
1337
1338
1339void audioEngine_noteOff( Note *note )
1340{
1341        if ( note == NULL )     {
1342                _ERRORLOG( "Error, note == NULL" );
1343        }
1344
1345        AudioEngine::get_instance()->lock( "audioEngine_noteOff" );
1346
1347        // check current state
1348        if ( ( m_audioEngineState != STATE_READY ) && ( m_audioEngineState != STATE_PLAYING ) ) {
1349                _ERRORLOG( "Error the audio engine is not in READY state" );
1350                delete note;
1351                AudioEngine::get_instance()->unlock();
1352                return;
1353        }
1354
1355        /*
1356                for ( unsigned i = 0; i < m_playingNotesQueue.size(); ++i ) {   // delete old note
1357                        Note *oldNote = m_playingNotesQueue[ i ];
1358
1359                        if ( oldNote->getInstrument() == note->getInstrument() ) {
1360                                m_playingNotesQueue.erase( m_playingNotesQueue.begin() + i );
1361                                delete oldNote;
1362                                break;
1363                        }
1364                }
1365        */
1366        AudioEngine::get_instance()->get_sampler()->note_off( note );
1367
1368        AudioEngine::get_instance()->unlock();
1369
1370        delete note;
1371}
1372
1373
1374
1375unsigned long audioEngine_getTickPosition()
1376{
1377        return m_nPatternTickPosition;
1378}
1379
1380
1381AudioOutput* createDriver( const QString& sDriver )
1382{
1383        _INFOLOG( QString( "Driver: '%1'" ).arg( sDriver ) );
1384        Preferences *pPref = Preferences::getInstance();
1385        AudioOutput *pDriver = NULL;
1386
1387        if ( sDriver == "Oss" ) {
1388                pDriver = new OssDriver( audioEngine_process );
1389                if ( pDriver->get_class_name() == "NullDriver" ) {
1390                        delete pDriver;
1391                        pDriver = NULL;
1392                }
1393        } else if ( sDriver == "Jack" ) {
1394                pDriver = new JackOutput( audioEngine_process );
1395                if ( pDriver->get_class_name() == "NullDriver" ) {
1396                        delete pDriver;
1397                        pDriver = NULL;
1398                } else {
1399#ifdef JACK_SUPPORT
1400                        m_bUseDefaultOuts = pPref->m_bJackConnectDefaults;
1401                        ( ( JackOutput* ) pDriver )->setConnectDefaults( m_bUseDefaultOuts );
1402#endif
1403                }
1404        } else if ( sDriver == "Alsa" ) {
1405                pDriver = new AlsaAudioDriver( audioEngine_process );
1406                if ( pDriver->get_class_name() == "NullDriver" ) {
1407                        delete pDriver;
1408                        pDriver = NULL;
1409                }
1410        } else if ( sDriver == "PortAudio" ) {
1411                pDriver = new PortAudioDriver( audioEngine_process );
1412                if ( pDriver->get_class_name() == "NullDriver" ) {
1413                        delete pDriver;
1414                        pDriver = NULL;
1415                }
1416        }
1417//#ifdef Q_OS_MACX
1418        else if ( sDriver == "CoreAudio" ) {
1419                _INFOLOG( "Creating CoreAudioDriver" );
1420                pDriver = new CoreAudioDriver( audioEngine_process );
1421                if ( pDriver->get_class_name() == "NullDriver" ) {
1422                        delete pDriver;
1423                        pDriver = NULL;
1424                }
1425        }
1426//#endif
1427        else if ( sDriver == "Fake" ) {
1428                _WARNINGLOG( "*** Using FAKE audio driver ***" );
1429                pDriver = new FakeDriver( audioEngine_process );
1430        } else {
1431                _ERRORLOG( "Unknown driver " + sDriver );
1432                audioEngine_raiseError( Hydrogen::UNKNOWN_DRIVER );
1433        }
1434
1435        if ( pDriver  ) {
1436                // initialize the audio driver
1437                int res = pDriver->init( pPref->m_nBufferSize );
1438                if ( res != 0 ) {
1439                        _ERRORLOG( "Error starting audio driver [audioDriver::init()]" );
1440                        delete pDriver;
1441                        pDriver = NULL;
1442                }
1443        }
1444
1445        return pDriver;
1446}
1447
1448
1449/// Start all audio drivers
1450void audioEngine_startAudioDrivers()
1451{
1452        Preferences *preferencesMng = Preferences::getInstance();
1453
1454        AudioEngine::get_instance()->lock( "audioEngine_startAudioDrivers" );
1455
1456        _INFOLOG( "[audioEngine_startAudioDrivers]" );
1457
1458        // check current state
1459        if ( m_audioEngineState != STATE_INITIALIZED ) {
1460                _ERRORLOG( QString( "Error the audio engine is not in INITIALIZED state. state=%1" ).arg( m_audioEngineState ) );
1461                AudioEngine::get_instance()->unlock();
1462                return;
1463        }
1464        if ( m_pAudioDriver ) { // check if the audio m_pAudioDriver is still alive
1465                _ERRORLOG( "The audio driver is still alive" );
1466        }
1467        if ( m_pMidiDriver ) {  // check if midi driver is still alive
1468                _ERRORLOG( "The MIDI driver is still active" );
1469        }
1470
1471
1472        QString sAudioDriver = preferencesMng->m_sAudioDriver;
1473//      sAudioDriver = "Auto";
1474        if ( sAudioDriver == "Auto" ) {
1475                if ( ( m_pAudioDriver = createDriver( "Jack" ) ) == NULL ) {
1476                        if ( ( m_pAudioDriver = createDriver( "Alsa" ) ) == NULL ) {
1477                                if ( ( m_pAudioDriver = createDriver( "CoreAudio" ) ) == NULL ) {
1478                                        if ( ( m_pAudioDriver = createDriver( "PortAudio" ) ) == NULL ) {
1479                                                if ( ( m_pAudioDriver = createDriver( "Oss" ) ) == NULL ) {
1480                                                        audioEngine_raiseError( Hydrogen::ERROR_STARTING_DRIVER );
1481                                                        _ERRORLOG( "Error starting audio driver" );
1482                                                        _ERRORLOG( "Using the NULL output audio driver" );
1483
1484                                                        // use the NULL output driver
1485                                                        m_pAudioDriver = new NullDriver( audioEngine_process );
1486                                                        m_pAudioDriver->init( 0 );
1487                                                }
1488                                        }
1489                                }
1490                        }
1491                }
1492        } else {
1493                m_pAudioDriver = createDriver( sAudioDriver );
1494                if ( m_pAudioDriver == NULL ) {
1495                        audioEngine_raiseError( Hydrogen::ERROR_STARTING_DRIVER );
1496                        _ERRORLOG( "Error starting audio driver" );
1497                        _ERRORLOG( "Using the NULL output audio driver" );
1498
1499                        // use the NULL output driver
1500                        m_pAudioDriver = new NullDriver( audioEngine_process );
1501                        m_pAudioDriver->init( 0 );
1502                }
1503        }
1504
1505        if ( preferencesMng->m_sMidiDriver == "ALSA" ) {
1506#ifdef ALSA_SUPPORT
1507                // Create MIDI driver
1508                m_pMidiDriver = new AlsaMidiDriver();
1509                m_pMidiDriver->open();
1510                m_pMidiDriver->setActive( true );
1511#endif
1512        } else if ( preferencesMng->m_sMidiDriver == "PortMidi" ) {
1513#ifdef PORTMIDI_SUPPORT
1514                m_pMidiDriver = new PortMidiDriver();
1515                m_pMidiDriver->open();
1516                m_pMidiDriver->setActive( true );
1517#endif
1518        } else if ( preferencesMng->m_sMidiDriver == "CoreMidi" ) {
1519#ifdef COREMIDI_SUPPORT
1520                m_pMidiDriver = new CoreMidiDriver();
1521                m_pMidiDriver->open();
1522                m_pMidiDriver->setActive( true );
1523#endif
1524        }
1525
1526        // change the current audio engine state
1527        if ( m_pSong == NULL ) {
1528                m_audioEngineState = STATE_PREPARED;
1529        } else {
1530                m_audioEngineState = STATE_READY;
1531        }
1532
1533
1534        if ( m_pSong ) {
1535                m_pAudioDriver->setBpm( m_pSong->__bpm );
1536        }
1537
1538        // update the audiodriver reference in the sampler
1539        AudioEngine::get_instance()->get_sampler()->set_audio_output( m_pAudioDriver );
1540
1541        if ( m_pAudioDriver ) {
1542                int res = m_pAudioDriver->connect();
1543                if ( res != 0 ) {
1544                        audioEngine_raiseError( Hydrogen::ERROR_STARTING_DRIVER );
1545                        _ERRORLOG( "Error starting audio driver [audioDriver::connect()]" );
1546                        _ERRORLOG( "Using the NULL output audio driver" );
1547
1548                        delete m_pAudioDriver;
1549                        m_pAudioDriver = new NullDriver( audioEngine_process );
1550                        m_pAudioDriver->init( 0 );
1551                        m_pAudioDriver->connect();
1552                }
1553
1554                if ( ( m_pMainBuffer_L = m_pAudioDriver->getOut_L() ) == NULL ) {
1555                        _ERRORLOG( "m_pMainBuffer_L == NULL" );
1556                }
1557                if ( ( m_pMainBuffer_R = m_pAudioDriver->getOut_R() ) == NULL ) {
1558                        _ERRORLOG( "m_pMainBuffer_R == NULL" );
1559                }
1560
1561#ifdef JACK_SUPPORT
1562                audioEngine_renameJackPorts();
1563#endif
1564
1565                audioEngine_setupLadspaFX( m_pAudioDriver->getBufferSize() );
1566        }
1567
1568
1569
1570        if ( m_audioEngineState == STATE_PREPARED ) {
1571                EventQueue::get_instance()->push_event( EVENT_STATE, STATE_PREPARED );
1572        } else if ( m_audioEngineState == STATE_READY ) {
1573                EventQueue::get_instance()->push_event( EVENT_STATE, STATE_READY );
1574        }
1575
1576        AudioEngine::get_instance()->unlock();  // Unlocking earlier might execute the jack process() callback before we are fully initialized.
1577}
1578
1579
1580
1581/// Stop all audio drivers
1582void audioEngine_stopAudioDrivers()
1583{
1584        _INFOLOG( "[audioEngine_stopAudioDrivers]" );
1585
1586        // check current state
1587        if ( m_audioEngineState == STATE_PLAYING ) {
1588                audioEngine_stop();
1589        }
1590
1591        if ( ( m_audioEngineState != STATE_PREPARED ) && ( m_audioEngineState != STATE_READY ) ) {
1592                _ERRORLOG( QString( "Error: the audio engine is not in PREPARED or READY state. state=%1" ).arg( m_audioEngineState ) );
1593                return;
1594        }
1595
1596        // delete MIDI driver
1597        if ( m_pMidiDriver ) {
1598                m_pMidiDriver->close();
1599                delete m_pMidiDriver;
1600                m_pMidiDriver = NULL;
1601        }
1602
1603        AudioEngine::get_instance()->get_sampler()->set_audio_output( NULL );
1604
1605        // delete audio driver
1606        if ( m_pAudioDriver ) {
1607                m_pAudioDriver->disconnect();
1608                delete m_pAudioDriver;
1609                m_pAudioDriver = NULL;
1610        }
1611
1612
1613        AudioEngine::get_instance()->lock( "audioEngine_stopAudioDrivers" );
1614        // change the current audio engine state
1615        m_audioEngineState = STATE_INITIALIZED;
1616        EventQueue::get_instance()->push_event( EVENT_STATE, STATE_INITIALIZED );
1617        AudioEngine::get_instance()->unlock();
1618}
1619
1620
1621
1622/// Restart all audio and midi drivers
1623void audioEngine_restartAudioDrivers()
1624{
1625        audioEngine_stopAudioDrivers();
1626        audioEngine_startAudioDrivers();
1627}
1628
1629
1630
1631
1632
1633
1634//----------------------------------------------------------------------------
1635//
1636// Implementation of Hydrogen class
1637//
1638//----------------------------------------------------------------------------
1639
1640
1641Hydrogen* Hydrogen::instance = NULL;            /// static reference of Hydrogen class (Singleton)
1642
1643
1644
1645
1646Hydrogen::Hydrogen()
1647                : Object( "Hydrogen" )
1648{
1649        if ( instance ) {
1650                _ERRORLOG( "Hydrogen audio engine is already running" );
1651                throw H2Exception( "Hydrogen audio engine is already running" );
1652        }
1653
1654        _INFOLOG( "[Hydrogen]" );
1655
1656        hydrogenInstance = this;
1657        instance = this;
1658        audioEngine_init();
1659        audioEngine_startAudioDrivers();
1660
1661}
1662
1663
1664
1665Hydrogen::~Hydrogen()
1666{
1667        _INFOLOG( "[~Hydrogen]" );
1668        if ( m_audioEngineState == STATE_PLAYING ) {
1669                audioEngine_stop();
1670        }
1671        removeSong();
1672        audioEngine_stopAudioDrivers();
1673        audioEngine_destroy();
1674        instance = NULL;
1675}
1676
1677
1678
1679/// Return the Hydrogen instance
1680Hydrogen* Hydrogen::get_instance()
1681{
1682        if ( instance == NULL ) {
1683                instance = new Hydrogen();
1684        }
1685        return instance;
1686}
1687
1688
1689
1690/// Start the internal sequencer
1691void Hydrogen::sequencer_play()
1692{
1693        // play from start if pattern mode is enabled
1694        if ( m_pSong->get_mode() == Song::PATTERN_MODE ) {
1695                setPatternPos( 0 );
1696        }
1697        m_pAudioDriver->play();
1698}
1699
1700
1701
1702/// Stop the internal sequencer
1703void Hydrogen::sequencer_stop()
1704{
1705        m_pAudioDriver->stop();
1706}
1707
1708
1709
1710void Hydrogen::setSong( Song *pSong )
1711{
1712        audioEngine_setSong( pSong );
1713}
1714
1715
1716
1717void Hydrogen::removeSong()
1718{
1719        audioEngine_removeSong();
1720}
1721
1722
1723
1724Song* Hydrogen::getSong()
1725{
1726        return m_pSong;
1727}
1728
1729
1730
1731void Hydrogen::midi_noteOn( Note *note )
1732{
1733        audioEngine_noteOn( note );
1734}
1735
1736
1737
1738void Hydrogen::midi_noteOff( Note *note )
1739{
1740        audioEngine_noteOff( note );
1741}
1742
1743
1744
1745void Hydrogen::addRealtimeNote( int instrument, float velocity, float pan_L, float pan_R, float pitch, bool forcePlay )
1746{
1747        UNUSED( pitch );
1748
1749        Preferences *pref = Preferences::getInstance();
1750        unsigned int realcolumn = 0;
1751        unsigned res = pref->getPatternEditorGridResolution();
1752        int nBase = pref->isPatternEditorUsingTriplets() ? 3 : 4;
1753        int scalar = ( 4 * MAX_NOTES ) / ( res * nBase );
1754        bool hearnote = forcePlay;
1755
1756
1757
1758        AudioEngine::get_instance()->lock( "Hydrogen::addRealtimeNote" );       // lock the audio engine
1759
1760        Song *song = getSong();
1761        if ( instrument >= ( int )song->get_instrument_list()->get_size() ) {
1762                // unused instrument
1763                AudioEngine::get_instance()->unlock();
1764                return;
1765        }
1766
1767        unsigned int column = getTickPosition();
1768
1769        realcolumn = getRealtimeTickPosition();
1770
1771        // quantize it to scale
1772        int qcolumn = ( int )::round( column / ( double )scalar ) * scalar;
1773        if ( qcolumn == MAX_NOTES ) qcolumn = 0;
1774
1775        if ( pref->getQuantizeEvents() ) {
1776                column = qcolumn;
1777        }
1778
1779
1780        unsigned position = column;
1781
1782        Pattern* currentPattern = NULL;
1783        PatternList *pPatternList = m_pSong->get_pattern_list();
1784        if ( ( m_nSelectedPatternNumber != -1 ) && ( m_nSelectedPatternNumber < ( int )pPatternList->get_size() ) ) {
1785                currentPattern = pPatternList->get( m_nSelectedPatternNumber );
1786        }
1787
1788        Instrument *instrRef = 0;
1789        if ( song ) {
1790                instrRef = song->get_instrument_list()->get( instrument );
1791        }
1792
1793        if ( currentPattern && ( getState() == STATE_PLAYING ) ) {
1794                bool bNoteAlreadyExist = false;
1795                for ( unsigned nNote = 0; nNote < currentPattern->get_lenght(); nNote++ ) {
1796                        std::multimap <int, Note*>::iterator pos;
1797                        for ( pos = currentPattern->note_map.lower_bound( nNote ); pos != currentPattern->note_map.upper_bound( nNote ); ++pos ) {
1798                                Note *pNote = pos->second;
1799                                if ( pNote!=NULL ) {
1800                                        if ( pNote->get_instrument() == instrRef && nNote==column ) {
1801                                                bNoteAlreadyExist = true;
1802                                                break;
1803                                        }
1804                                }
1805                        }
1806                }
1807
1808                if ( bNoteAlreadyExist ) {
1809                        // in this case, we'll leave the note alone
1810                        // hear note only if not playing too
1811                        if ( pref->getHearNewNotes() && getState() == STATE_READY ) {
1812                                hearnote = true;
1813                        }
1814                } else if ( !pref->getRecordEvents() ) {
1815                        if ( pref->getHearNewNotes() && ( getState() == STATE_READY || getState() == STATE_PLAYING ) ) {
1816                                hearnote = true;
1817                        }
1818                } else {
1819                        // create the new note
1820                        Note *note = new Note( instrRef, position, velocity, pan_L, pan_R, -1, 0 );
1821                        currentPattern->note_map.insert( std::make_pair( column, note ) );
1822
1823                        // hear note if its not in the future
1824                        if ( pref->getHearNewNotes() && position <= getTickPosition() ) {
1825                                hearnote = true;
1826                        }
1827
1828                        song->__is_modified = true;
1829
1830                        EventQueue::get_instance()->push_event( EVENT_PATTERN_MODIFIED, -1 );
1831                }
1832        } else if ( pref->getHearNewNotes() ) {
1833                hearnote = true;
1834        }
1835
1836        if ( hearnote && instrRef ) {
1837                Note *note2 = new Note( instrRef, realcolumn, velocity, pan_L, pan_R, -1, 0 );
1838                midi_noteOn( note2 );
1839        }
1840
1841        AudioEngine::get_instance()->unlock(); // unlock the audio engine
1842}
1843
1844
1845
1846float Hydrogen::getMasterPeak_L()
1847{
1848        return m_fMasterPeak_L;
1849}
1850
1851
1852
1853float Hydrogen::getMasterPeak_R()
1854{
1855        return m_fMasterPeak_R;
1856}
1857
1858
1859
1860unsigned long Hydrogen::getTickPosition()
1861{
1862        return audioEngine_getTickPosition();
1863}
1864
1865
1866
1867unsigned long Hydrogen::getRealtimeTickPosition()
1868{
1869        //unsigned long initTick = audioEngine_getTickPosition();
1870        unsigned int initTick = ( unsigned int )( m_nRealtimeFrames / m_pAudioDriver->m_transport.m_nTickSize );
1871        unsigned long retTick;
1872
1873        struct timeval currtime;
1874        struct timeval deltatime;
1875
1876        double sampleRate = ( double ) m_pAudioDriver->getSampleRate();
1877        gettimeofday ( &currtime, NULL );
1878
1879        timersub( &currtime, &m_currentTickTime, &deltatime );
1880
1881        // add a buffers worth for jitter resistance
1882        double deltaSec = ( double ) deltatime.tv_sec + ( deltatime.tv_usec / 1000000.0 ) +  ( m_pAudioDriver->getBufferSize() / ( double )sampleRate );
1883
1884        retTick = ( unsigned long ) ( ( sampleRate / ( double ) m_pAudioDriver->m_transport.m_nTickSize ) * deltaSec );
1885
1886        retTick = initTick + retTick;
1887
1888        return retTick;
1889}
1890
1891
1892
1893PatternList* Hydrogen::getCurrentPatternList()
1894{
1895        return m_pPlayingPatterns;
1896}
1897
1898PatternList * Hydrogen::getNextPatterns()
1899{
1900        return m_pNextPatterns;
1901}
1902
1903/// Set the next pattern (Pattern mode only)
1904void Hydrogen::sequencer_setNextPattern( int pos, bool appendPattern, bool deletePattern )
1905{
1906        m_bAppendNextPattern = appendPattern;
1907        m_bDeleteNextPattern = deletePattern;
1908
1909        AudioEngine::get_instance()->lock( "Hydrogen::sequencer_setNextPattern" );
1910
1911        if ( m_pSong && m_pSong->get_mode() == Song::PATTERN_MODE ) {
1912                PatternList *patternList = m_pSong->get_pattern_list();
1913                Pattern * p = patternList->get( pos );
1914                if ( ( pos >= 0 ) && ( pos < ( int )patternList->get_size() ) ) {
1915                        // if p is already on the next pattern list, delete it.
1916                        if ( m_pNextPatterns->del( p ) == NULL ) {
1917//                              WARNINGLOG( "Adding to nextPatterns" );
1918                                m_pNextPatterns->add( p );
1919                        }/* else {
1920//                              WARNINGLOG( "Removing " + to_string(pos) );
1921                        }*/
1922                } else {
1923                        _ERRORLOG( QString( "pos not in patternList range. pos=%1 patternListSize=%2" ).arg( pos ).arg( patternList->get_size() ) );
1924                        m_pNextPatterns->clear();
1925                }
1926        } else {
1927                _ERRORLOG( "can't set next pattern in song mode" );
1928                m_pNextPatterns->clear();
1929        }
1930
1931        AudioEngine::get_instance()->unlock();
1932}
1933
1934
1935
1936int Hydrogen::getPatternPos()
1937{
1938        return m_nSongPos;
1939}
1940
1941
1942
1943void Hydrogen::restartDrivers()
1944{
1945        audioEngine_restartAudioDrivers();
1946}
1947
1948
1949
1950/// Export a song to a wav file, returns the elapsed time in mSec
1951void Hydrogen::startExportSong( const QString& filename )
1952{
1953        if ( getState() == STATE_PLAYING ) {
1954                sequencer_stop();
1955        }
1956        Preferences *pPref = Preferences::getInstance();
1957
1958        m_oldEngineMode = m_pSong->get_mode();
1959        m_bOldLoopEnabled = m_pSong->is_loop_enabled();
1960
1961        m_pSong->set_mode( Song::SONG_MODE );
1962        m_pSong->set_loop_enabled( false );
1963        unsigned nSamplerate = m_pAudioDriver->getSampleRate();
1964
1965        // stop all audio drivers
1966        audioEngine_stopAudioDrivers();
1967
1968        /*
1969                FIXME: Questo codice fa davvero schifo....
1970        */
1971
1972
1973        m_pAudioDriver = new DiskWriterDriver( audioEngine_process, nSamplerate, filename );
1974
1975        AudioEngine::get_instance()->get_sampler()->stop_playing_notes();
1976        AudioEngine::get_instance()->get_sampler()->set_audio_output( m_pAudioDriver );
1977
1978        // reset
1979        m_pAudioDriver->m_transport.m_nFrames = 0;      // reset total frames
1980        m_pAudioDriver->setBpm( m_pSong->__bpm );
1981        m_nSongPos = 0;
1982        m_nPatternTickPosition = 0;
1983        m_audioEngineState = STATE_PLAYING;
1984        m_nPatternStartTick = -1;
1985
1986        int res = m_pAudioDriver->init( pPref->m_nBufferSize );
1987        if ( res != 0 ) {
1988                _ERRORLOG( "Error starting disk writer driver [DiskWriterDriver::init()]" );
1989        }
1990
1991        m_pMainBuffer_L = m_pAudioDriver->getOut_L();
1992        m_pMainBuffer_R = m_pAudioDriver->getOut_R();
1993
1994        audioEngine_setupLadspaFX( m_pAudioDriver->getBufferSize() );
1995
1996        audioEngine_seek( 0, false );
1997
1998        res = m_pAudioDriver->connect();
1999        if ( res != 0 ) {
2000                _ERRORLOG( "Error starting disk writer driver [DiskWriterDriver::connect()]" );
2001        }
2002}
2003
2004
2005
2006void Hydrogen::stopExportSong()
2007{
2008        if ( m_pAudioDriver->get_class_name() != "DiskWriterDriver" ) {
2009                return;
2010        }
2011
2012//      audioEngine_stopAudioDrivers();
2013        m_pAudioDriver->disconnect();
2014
2015        m_audioEngineState = STATE_INITIALIZED;
2016        delete m_pAudioDriver;
2017        m_pAudioDriver = NULL;
2018
2019        m_pMainBuffer_L = NULL;
2020        m_pMainBuffer_R = NULL;
2021
2022        m_pSong->set_mode( m_oldEngineMode );
2023        m_pSong->set_loop_enabled( m_bOldLoopEnabled );
2024
2025        m_nSongPos = -1;
2026        m_nPatternTickPosition = 0;
2027        audioEngine_startAudioDrivers();
2028
2029        if ( m_pAudioDriver ) {
2030                m_pAudioDriver->setBpm( m_pSong->__bpm );
2031        } else {
2032                _ERRORLOG( "m_pAudioDriver = NULL" );
2033        }
2034}
2035
2036
2037
2038/// Used to display audio driver info
2039AudioOutput* Hydrogen::getAudioOutput()
2040{
2041        return m_pAudioDriver;
2042}
2043
2044
2045
2046/// Used to display midi driver info
2047MidiInput* Hydrogen::getMidiInput()
2048{
2049        return m_pMidiDriver;
2050}
2051
2052
2053
2054void Hydrogen::setMasterPeak_L( float value )
2055{
2056        m_fMasterPeak_L = value;
2057}
2058
2059
2060
2061void Hydrogen::setMasterPeak_R( float value )
2062{
2063        m_fMasterPeak_R = value;
2064}
2065
2066
2067
2068int Hydrogen::getState()
2069{
2070        return m_audioEngineState;
2071}
2072
2073
2074
2075void Hydrogen::setCurrentPatternList( PatternList *pPatternList )
2076{
2077        AudioEngine::get_instance()->lock( "Hydrogen::setCurrentPatternList" );
2078        m_pPlayingPatterns = pPatternList;
2079        EventQueue::get_instance()->push_event( EVENT_PATTERN_CHANGED, -1 );
2080        AudioEngine::get_instance()->unlock();
2081}
2082
2083
2084
2085float Hydrogen::getProcessTime()
2086{
2087        return m_fProcessTime;
2088}
2089
2090
2091
2092float Hydrogen::getMaxProcessTime()
2093{
2094        return m_fMaxProcessTime;
2095}
2096
2097
2098
2099int Hydrogen::loadDrumkit( Drumkit *drumkitInfo )
2100{
2101        _INFOLOG( drumkitInfo->getName() );
2102        m_currentDrumkit = drumkitInfo->getName();
2103        LocalFileMng fileMng;
2104        QString sDrumkitPath = fileMng.getDrumkitDirectory( drumkitInfo->getName() );
2105
2106
2107        //current instrument list
2108        InstrumentList *songInstrList = m_pSong->get_instrument_list();
2109
2110        //new instrument list
2111        InstrumentList *pDrumkitInstrList = drumkitInfo->getInstrumentList();
2112
2113        /*
2114                If the old drumkit is bigger then the new drumkit,
2115                delete all instruments with a bigger pos then
2116                pDrumkitInstrList->get_size(). Otherwise the instruments
2117                from our old instrumentlist with
2118                pos > pDrumkitInstrList->get_size() stay in the
2119                new instrumentlist
2120               
2121        wolke: info!
2122                this has moved to the end of this function
2123                because we get lost objects in memory
2124                now:
2125                1. the new drumkit will loaded
2126                2. all not used instruments will complete deleted
2127       
2128        old funktion:
2129        while ( pDrumkitInstrList->get_size() < songInstrList->get_size() )
2130        {
2131                songInstrList->del(songInstrList->get_size() - 1);
2132        }
2133        */
2134       
2135        //needed for the new delete function
2136        int instrumentDiff =  songInstrList->get_size() - pDrumkitInstrList->get_size();
2137
2138        for ( unsigned nInstr = 0; nInstr < pDrumkitInstrList->get_size(); ++nInstr ) {
2139                Instrument *pInstr = NULL;
2140                if ( nInstr < songInstrList->get_size() ) {
2141                        //instrument exists already
2142                        pInstr = songInstrList->get( nInstr );
2143                        assert( pInstr );
2144                } else {
2145                        pInstr = new Instrument( "", "", new ADSR() );
2146                        AudioEngine::get_instance()->lock( "Hydrogen::loadDrumkit" );
2147                        songInstrList->add( pInstr );
2148                        AudioEngine::get_instance()->unlock();
2149                }
2150
2151                //if ( pInstr->m_bIsLocked ) {  // is instrument locking still useful?
2152                //      continue;
2153                //}
2154
2155                Instrument *pNewInstr = pDrumkitInstrList->get( nInstr );
2156                assert( pNewInstr );
2157                _INFOLOG( QString( "Loading instrument (%1 of %2) [%3]" ).arg( nInstr ).arg( pDrumkitInstrList->get_size() ).arg( pNewInstr->get_name() ) );
2158                // creo i nuovi layer in base al nuovo strumento
2159                for ( unsigned nLayer = 0; nLayer < MAX_LAYERS; ++nLayer ) {
2160                        InstrumentLayer *pNewLayer = pNewInstr->get_layer( nLayer );
2161                        if ( pNewLayer != NULL ) {
2162                                Sample *pNewSample = pNewLayer->get_sample();
2163                                QString sSampleFilename = sDrumkitPath + drumkitInfo->getName() + "/" + pNewSample->get_filename();
2164                                _INFOLOG( "    |-> Loading layer [ " + sSampleFilename + " ]" );
2165
2166                                // carico il nuovo sample e creo il nuovo layer
2167                                Sample *pSample = Sample::load( sSampleFilename );
2168//                              pSample->setFilename( pNewSample->getFilename() );      // riuso il path del nuovo sample (perche' e' gia relativo al path del drumkit)
2169                                InstrumentLayer *pOldLayer = pInstr->get_layer( nLayer );
2170
2171                                if ( pSample == NULL ) {
2172                                        //_ERRORLOG( "Error Loading drumkit: NULL sample, now using /emptySample.wav" );
2173                                        //pSample = Sample::load(string(DataPath::getDataPath() ).append( "/emptySample.wav" ));
2174                                        //pSample->m_sFilename = string(DataPath::getDataPath() ).append( "/emptySample.wav" );
2175                                        _ERRORLOG( "Error loading sample. Creating a new empty layer." );
2176                                        AudioEngine::get_instance()->lock( "Hydrogen::loadDrumkit" );
2177                                        pInstr->set_layer( NULL, nLayer );
2178                                        AudioEngine::get_instance()->unlock();
2179                                        delete pOldLayer;
2180                                        continue;
2181                                }
2182                                InstrumentLayer *pLayer = new InstrumentLayer( pSample );
2183                                pLayer->set_start_velocity( pNewLayer->get_start_velocity() );
2184                                pLayer->set_end_velocity( pNewLayer->get_end_velocity() );
2185                                pLayer->set_gain( pNewLayer->get_gain() );
2186
2187                                AudioEngine::get_instance()->lock( "Hydrogen::loadDrumkit" );
2188                                pInstr->set_layer( pLayer, nLayer );    // set the new layer
2189                                AudioEngine::get_instance()->unlock();
2190                                delete pOldLayer;               // delete the old layer
2191
2192                        } else {
2193                                InstrumentLayer *pOldLayer = pInstr->get_layer( nLayer );
2194                                AudioEngine::get_instance()->lock( "Hydrogen::loadDrumkit" );
2195                                pInstr->set_layer( NULL, nLayer );
2196                                AudioEngine::get_instance()->unlock();
2197                                delete pOldLayer;               // delete the old layer
2198                        }
2199
2200                }
2201                AudioEngine::get_instance()->lock( "Hydrogen::loadDrumkit" );
2202                // update instrument properties
2203                pInstr->set_id( pNewInstr->get_id() );
2204                pInstr->set_name( pNewInstr->get_name() );
2205                pInstr->set_pan_l( pNewInstr->get_pan_l() );
2206                pInstr->set_pan_r( pNewInstr->get_pan_r() );
2207                pInstr->set_volume( pNewInstr->get_volume() );
2208                pInstr->set_drumkit_name( pNewInstr->get_drumkit_name() );
2209                pInstr->set_muted( pNewInstr->is_muted() );
2210                pInstr->set_random_pitch_factor( pNewInstr->get_random_pitch_factor() );
2211                pInstr->set_adsr( new ADSR( *( pNewInstr->get_adsr() ) ) );
2212                pInstr->set_filter_active( pNewInstr->is_filter_active() );
2213                pInstr->set_filter_cutoff( pNewInstr->get_filter_cutoff() );
2214                pInstr->set_filter_resonance( pNewInstr->get_filter_resonance() );
2215                pInstr->set_mute_group( pNewInstr->get_mute_group() );
2216                AudioEngine::get_instance()->unlock();
2217        }
2218
2219        AudioEngine::get_instance()->lock( "Hydrogen::loadDrumkit" );
2220        audioEngine_renameJackPorts();
2221        AudioEngine::get_instance()->unlock();
2222
2223//wolke: new delete funktion
2224        if ( instrumentDiff >=0 ){
2225                for ( int i = 0; i < instrumentDiff ; i++ ){
2226                        functionDeleteInstrument( m_pSong->get_instrument_list()->get_size() - 1);
2227                }
2228        }
2229
2230        #ifdef JACK_SUPPORT
2231                renameJackPorts();
2232        #endif
2233
2234        return 0;       //ok
2235}
2236
2237
2238//this is also a new function and will used from the new delete function in Hydrogen::loadDrumkit to delete the instruments by number
2239void Hydrogen::functionDeleteInstrument( int instrumentnumber)
2240{
2241        AudioEngine::get_instance()->lock("InstrumentLine::Hydrogen::functionDeleteInstrument");
2242        Instrument *pInstr = m_pSong->get_instrument_list()->get( instrumentnumber );
2243
2244        // if the instrument was the last on the instruments list, select the next-last
2245        if ( instrumentnumber >= (int)getSong()->get_instrument_list()->get_size() -1 ) {
2246                Hydrogen::get_instance()->setSelectedInstrumentNumber(std::max(0, instrumentnumber - 1) );
2247        }
2248
2249        // delete the instrument from the instruments list
2250        getSong()->get_instrument_list()->del( instrumentnumber );
2251        getSong()->__is_modified = true;
2252
2253
2254        // delete all the notes using this instrument
2255        PatternList* pPatternList = getSong()->get_pattern_list();
2256        for ( int nPattern = 0; nPattern < (int)pPatternList->get_size(); ++nPattern ) {
2257                H2Core::Pattern *pPattern = pPatternList->get( nPattern );
2258
2259                std::multimap <int, Note*>::iterator pos;
2260                for ( pos = pPattern->note_map.begin(); pos != pPattern->note_map.end(); ++pos ) {
2261                        Note *pNote = pos->second;
2262                        assert( pNote );
2263                        if ( pNote->get_instrument() == pInstr ) {
2264                                delete pNote;
2265                                pPattern->note_map.erase( pos );
2266                        }
2267                }
2268        }
2269
2270        // stop all notes playing
2271        AudioEngine::get_instance()->get_sampler()->stop_playing_notes();
2272
2273        delete pInstr;
2274
2275        AudioEngine::get_instance()->unlock();
2276
2277        // this will force an update...
2278        EventQueue::get_instance()->push_event( EVENT_SELECTED_INSTRUMENT_CHANGED, -1 );
2279}
2280
2281
2282void Hydrogen::raiseError( unsigned nErrorCode )
2283{
2284        audioEngine_raiseError( nErrorCode );
2285}
2286
2287
2288unsigned long Hydrogen::getTotalFrames()
2289{
2290        return m_pAudioDriver->m_transport.m_nFrames;
2291}
2292
2293unsigned long Hydrogen::getRealtimeFrames()
2294{
2295        return m_nRealtimeFrames;
2296}
2297
2298/**
2299 * Get the ticks for pattern at pattern pos
2300 * @a int pos -- position in song
2301 * @return -1 if pos > number of patterns in the song, tick no. > 0 otherwise
2302 * The driver should be LOCKED when calling this!!
2303 */
2304long Hydrogen::getTickForPosition( int pos )
2305{
2306        int nPatternGroups = m_pSong->get_pattern_group_vector()->size();
2307        if ( pos >= nPatternGroups ) {
2308                if ( m_pSong->is_loop_enabled() ) {
2309                        pos = pos % nPatternGroups;
2310                } else {
2311                        _WARNINGLOG( QString( "patternPos > nPatternGroups. pos: %1, nPatternGroups: %2").arg( pos ).arg(  nPatternGroups ) );
2312                        return -1;
2313                }
2314        }
2315
2316        std::vector<PatternList*> *pColumns = m_pSong->get_pattern_group_vector();
2317        long totalTick = 0;
2318        int nPatternSize;
2319        Pattern *pPattern = NULL;
2320        for ( int i = 0; i < pos; ++i ) {
2321                PatternList *pColumn = ( *pColumns )[ i ];
2322                pPattern = pColumn->get( 0 );   // prendo solo il primo. I pattern nel gruppo devono avere la stessa lunghezza
2323                if ( pPattern ) {
2324                        nPatternSize = pPattern->get_lenght();
2325                } else {
2326                        nPatternSize = MAX_NOTES;
2327                }
2328
2329                totalTick += nPatternSize;
2330        }
2331        return totalTick;
2332}
2333
2334/// Set the position in the song
2335void Hydrogen::setPatternPos( int pos )
2336{
2337        AudioEngine::get_instance()->lock( "Hydrogen::setPatternPos" );
2338
2339        long totalTick = getTickForPosition( pos );
2340        if ( totalTick < 0 ) {
2341                AudioEngine::get_instance()->unlock();
2342                return;
2343        }
2344
2345        if ( getState() != STATE_PLAYING ) {
2346                // find pattern immediately when not playing
2347//              int dummy;
2348//              m_nSongPos = findPatternInTick( totalTick, m_pSong->is_loop_enabled(), &dummy );
2349                m_nSongPos = pos;
2350                m_nPatternTickPosition = 0;
2351        }
2352        m_pAudioDriver->locate( ( int ) ( totalTick * m_pAudioDriver->m_transport.m_nTickSize ) );
2353
2354        AudioEngine::get_instance()->unlock();
2355}
2356
2357
2358
2359
2360void Hydrogen::getLadspaFXPeak( int nFX, float *fL, float *fR )
2361{
2362#ifdef LADSPA_SUPPORT
2363        ( *fL ) = m_fFXPeak_L[nFX];
2364        ( *fR ) = m_fFXPeak_R[nFX];
2365#else
2366        ( *fL ) = 0;
2367        ( *fR ) = 0;
2368#endif
2369}
2370
2371
2372
2373void Hydrogen::setLadspaFXPeak( int nFX, float fL, float fR )
2374{
2375#ifdef LADSPA_SUPPORT
2376        m_fFXPeak_L[nFX] = fL;
2377        m_fFXPeak_R[nFX] = fR;
2378#endif
2379}
2380
2381
2382void Hydrogen::onTapTempoAccelEvent()
2383{
2384#ifndef WIN32
2385        INFOLOG( "tap tempo" );
2386        static timeval oldTimeVal;
2387
2388        struct timeval now;
2389        gettimeofday(&now, NULL);
2390
2391        float fInterval = (now.tv_sec - oldTimeVal.tv_sec) * 1000.0 + (now.tv_usec - oldTimeVal.tv_usec) / 1000.0;
2392
2393        oldTimeVal = now;
2394
2395        if ( fInterval < 1000.0 ) {
2396                setTapTempo( fInterval );
2397        }
2398#endif
2399}
2400
2401void Hydrogen::setTapTempo( float fInterval )
2402{
2403
2404//      infoLog( "set tap tempo" );
2405        static float fOldBpm1 = -1;
2406        static float fOldBpm2 = -1;
2407        static float fOldBpm3 = -1;
2408        static float fOldBpm4 = -1;
2409        static float fOldBpm5 = -1;
2410        static float fOldBpm6 = -1;
2411        static float fOldBpm7 = -1;
2412        static float fOldBpm8 = -1;
2413
2414        float fBPM = 60000.0 / fInterval;
2415
2416        if ( fabs( fOldBpm1 - fBPM ) > 20 ) {   // troppa differenza, niente media
2417                fOldBpm1 = fBPM;
2418                fOldBpm2 = fBPM;
2419                fOldBpm3 = fBPM;
2420                fOldBpm4 = fBPM;
2421                fOldBpm5 = fBPM;
2422                fOldBpm6 = fBPM;
2423                fOldBpm7 = fBPM;
2424                fOldBpm8 = fBPM;
2425        }
2426
2427        if ( fOldBpm1 == -1 ) {
2428                fOldBpm1 = fBPM;
2429                fOldBpm2 = fBPM;
2430                fOldBpm3 = fBPM;
2431                fOldBpm4 = fBPM;
2432                fOldBpm5 = fBPM;
2433                fOldBpm6 = fBPM;
2434                fOldBpm7 = fBPM;
2435                fOldBpm8 = fBPM;
2436        }
2437
2438        fBPM = ( fBPM + fOldBpm1 + fOldBpm2 + fOldBpm3 + fOldBpm4 + fOldBpm5 + fOldBpm6 + fOldBpm7 + fOldBpm8 ) / 9.0;
2439
2440
2441        _INFOLOG( QString( "avg BPM = %1" ).arg( fBPM ) );
2442        fOldBpm8 = fOldBpm7;
2443        fOldBpm7 = fOldBpm6;
2444        fOldBpm6 = fOldBpm5;
2445        fOldBpm5 = fOldBpm4;
2446        fOldBpm4 = fOldBpm3;
2447        fOldBpm3 = fOldBpm2;
2448        fOldBpm2 = fOldBpm1;
2449        fOldBpm1 = fBPM;
2450
2451        AudioEngine::get_instance()->lock( "Hydrogen::setTapTempo" );
2452
2453//      m_pAudioDriver->setBpm( fBPM );
2454//      m_pSong->setBpm( fBPM );
2455
2456        setBPM( fBPM );
2457
2458        AudioEngine::get_instance()->unlock();
2459}
2460
2461
2462// Called with audioEngine in LOCKED state.
2463void Hydrogen::setBPM( float fBPM )
2464{
2465        if ( m_pAudioDriver && m_pSong ) {
2466                m_pAudioDriver->setBpm( fBPM );
2467                m_pSong->__bpm = fBPM;
2468                m_nNewBpmJTM = fBPM;
2469//              audioEngine_process_checkBPMChanged();
2470        }
2471}
2472
2473
2474
2475void Hydrogen::restartLadspaFX()
2476{
2477        if ( m_pAudioDriver ) {
2478                AudioEngine::get_instance()->lock( "Hydrogen::restartLadspaFX" );
2479                audioEngine_setupLadspaFX( m_pAudioDriver->getBufferSize() );
2480                AudioEngine::get_instance()->unlock();
2481        } else {
2482                _ERRORLOG( "m_pAudioDriver = NULL" );
2483        }
2484}
2485
2486
2487
2488int Hydrogen::getSelectedPatternNumber()
2489{
2490        return m_nSelectedPatternNumber;
2491}
2492
2493
2494
2495void Hydrogen::setSelectedPatternNumber( int nPat )
2496{
2497        // FIXME: controllare se e' valido..
2498        if ( nPat == m_nSelectedPatternNumber ) return;
2499       
2500       
2501        if ( Preferences::getInstance()->patternModePlaysSelected() ) {
2502                AudioEngine::get_instance()->lock( "Hydrogen::setSelectedPatternNumber" );
2503       
2504                m_nSelectedPatternNumber = nPat;
2505                AudioEngine::get_instance()->unlock();
2506        } else {
2507                m_nSelectedPatternNumber = nPat;
2508        }
2509
2510        EventQueue::get_instance()->push_event( EVENT_SELECTED_PATTERN_CHANGED, -1 );
2511}
2512
2513
2514
2515int Hydrogen::getSelectedInstrumentNumber()
2516{
2517        return m_nSelectedInstrumentNumber;
2518}
2519
2520
2521
2522void Hydrogen::setSelectedInstrumentNumber( int nInstrument )
2523{
2524        if ( m_nSelectedInstrumentNumber == nInstrument )       return;
2525
2526        m_nSelectedInstrumentNumber = nInstrument;
2527        EventQueue::get_instance()->push_event( EVENT_SELECTED_INSTRUMENT_CHANGED, -1 );
2528}
2529
2530#ifdef JACK_SUPPORT
2531void Hydrogen::renameJackPorts()
2532{
2533        if( Preferences::getInstance()->m_bJackTrackOuts == true ){
2534                audioEngine_renameJackPorts();
2535        }
2536}
2537#endif
2538
2539
2540///BeatCounter
2541
2542void Hydrogen::setbeatsToCount( int beatstocount)
2543{
2544        m_nbeatsToCount = beatstocount;
2545}
2546
2547
2548int Hydrogen::getbeatsToCount()
2549{
2550        return m_nbeatsToCount;
2551}
2552
2553
2554void Hydrogen::setNoteLengh( float notelengh)
2555{
2556        m_ntaktoMeterCompute = notelengh;
2557}
2558
2559
2560
2561float Hydrogen::getNoteLengh()
2562{
2563        return m_ntaktoMeterCompute;
2564}
2565
2566
2567
2568int Hydrogen::getBcStatus()
2569{
2570        return eventCount;
2571}
2572
2573
2574
2575void Hydrogen::handleBeatCounter()
2576{
2577        // Get first time value:
2578        if (beatCount == 1)
2579                gettimeofday(&currentTime,NULL);
2580
2581        eventCount++;
2582               
2583        // Set wlastTime to wcurrentTime to remind the time:           
2584                lastTime = currentTime;
2585       
2586        // Get new time:
2587                gettimeofday(&currentTime,NULL);
2588       
2589
2590        // Build doubled time difference:
2591                lastBeatTime = (double)(lastTime.tv_sec + (double)(lastTime.tv_usec * MS_DIVIDER));
2592                currentBeatTime = (double)(currentTime.tv_sec + (double)(currentTime.tv_usec * MS_DIVIDER));
2593                beatDiff = beatCount == 1 ? 0 : currentBeatTime - lastBeatTime;
2594               
2595        //if differences are to big reset the beatconter
2596                if( beatDiff > 3.001){
2597                        eventCount = 1;
2598                        beatCount = 1;
2599                        return;
2600                }
2601        // Only accept differences big enough
2602                if (beatCount == 1 || beatDiff > .001) {
2603                        if (beatCount > 1)
2604                                beatDiffs[beatCount - 2] = beatDiff ;
2605                // Compute and reset:
2606                        if (beatCount == m_nbeatsToCount){
2607//                              unsigned long currentframe = getRealtimeFrames();
2608                                double beatTotalDiffs = 0;
2609                                for(int i = 0; i < (m_nbeatsToCount - 1); i++)
2610                                        beatTotalDiffs += beatDiffs[i];
2611                                double beatDiffAverage = beatTotalDiffs / (beatCount - 1) * m_ntaktoMeterCompute ;
2612                                beatCountBpm = (float) ((int) (60 / beatDiffAverage * 100)) / 100;
2613                                AudioEngine::get_instance()->lock( "Hydrogen::handleBeatCounter");
2614                                if ( beatCountBpm > 500)
2615                                                beatCountBpm = 500;
2616                                setBPM( beatCountBpm );
2617                                AudioEngine::get_instance()->unlock();
2618                                if (Preferences::getInstance()->m_mmcsetplay == Preferences::SET_PLAY_OFF) {
2619                                        beatCount = 1;
2620                                        eventCount = 1;
2621                                }else{
2622                                        if ( m_audioEngineState != STATE_PLAYING ){
2623                                                unsigned bcsamplerate = m_pAudioDriver->getSampleRate();
2624                                                unsigned long rtstartframe = 0;
2625                                                if ( m_ntaktoMeterCompute <= 1){
2626                                                        rtstartframe = bcsamplerate * beatDiffAverage * ( 1/ m_ntaktoMeterCompute ) ;
2627                                                }else
2628                                                {
2629                                                        rtstartframe = bcsamplerate * beatDiffAverage / m_ntaktoMeterCompute ;
2630                                                }
2631
2632                                                int sleeptime =  (float) rtstartframe / (float) bcsamplerate * ( int ) 1000 ;
2633                                                #ifdef WIN32
2634                                                Sleep( sleeptime );
2635                                                #else
2636                                                usleep( 1000 * sleeptime );
2637                                                #endif
2638
2639                                                sequencer_play();
2640                                        }
2641                                       
2642                                        beatCount = 1;
2643                                        eventCount = 1;
2644                                        return;
2645                                }
2646                        }
2647                        else {
2648                                beatCount ++;
2649                        }                               
2650                }
2651                return;
2652}
2653//~ beatcounter
2654
2655// jack transport master
2656unsigned long Hydrogen::getHumantimeFrames()
2657{
2658        return m_nHumantimeFrames;
2659}
2660
2661void Hydrogen::setHumantimeFrames(unsigned long hframes)
2662{
2663        m_nHumantimeFrames = hframes;
2664}
2665
2666
2667
2668#ifdef JACK_SUPPORT
2669void Hydrogen::offJackMaster()
2670{
2671        static_cast< JackOutput* >( m_pAudioDriver )->com_release();
2672}
2673
2674void Hydrogen::onJackMaster()
2675{
2676        static_cast< JackOutput* >( m_pAudioDriver )->initTimeMaster();
2677}
2678
2679unsigned long Hydrogen::getTimeMasterFrames()
2680{
2681        float allframes = 0 ;
2682
2683        if ( m_pAudioDriver->m_transport.m_status == TransportInfo::STOPPED ){
2684
2685                int oldtick = getTickPosition();
2686                for (int i = 0; i <= getPatternPos(); i++){
2687                        float framesforposition = (long)getTickForHumanPosition(i) * (float)m_pAudioDriver->m_transport.m_nTickSize;
2688                        allframes = framesforposition + allframes;
2689                }
2690                unsigned long framesfortimemaster = (unsigned int)(allframes + oldtick * (float)m_pAudioDriver->m_transport.m_nTickSize);
2691                m_nHumantimeFrames = framesfortimemaster;
2692                return framesfortimemaster;
2693        }else
2694        {
2695        return m_nHumantimeFrames;
2696        }
2697}
2698#endif
2699
2700long Hydrogen::getTickForHumanPosition( int humanpos )
2701{
2702        std::vector< PatternList* > * columns = m_pSong->get_pattern_group_vector();
2703       
2704        int nPatternGroups = columns->size();
2705        if ( humanpos >= nPatternGroups ) {
2706                if ( m_pSong->is_loop_enabled() ) {
2707                        humanpos = humanpos % nPatternGroups;
2708                } else {
2709                        return -1;
2710                }
2711        }
2712
2713//      std::vector<PatternList*> *pColumns = m_pSong->get_pattern_group_vector()[ humanpos - 1 ].get( 0 )->get_lenght();
2714       
2715//      ERRORLOG( "Kick me!" );
2716        if ( humanpos == 0 ) return 0;
2717        Pattern *pPattern = columns->at( humanpos - 1 )->get( 0 );
2718        if ( pPattern ) {
2719                return pPattern->get_lenght();
2720        } else {
2721                return MAX_NOTES;
2722        }
2723//      int nPatternSize;
2724       
2725//      pColumns
2726       
2727/*      Pattern *pPattern = NULL;
2728        for ( int i = 0; i < humanpos; ++i ) {
2729                PatternList *pColumn = ( *pColumns )[ i ];
2730                pPattern = pColumn->get( 0 );
2731                if ( pPattern ) {
2732                        nPatternSize = pPattern->get_lenght();
2733                } else {
2734                        nPatternSize = MAX_NOTES;
2735                }
2736
2737                humanTick = nPatternSize;
2738        }*/
2739//      return humanTick;
2740}
2741
2742
2743
2744float Hydrogen::getNewBpmJTM()
2745{
2746        return m_nNewBpmJTM;
2747}
2748
2749void Hydrogen::setNewBpmJTM( float bpmJTM )
2750{
2751        m_nNewBpmJTM = bpmJTM;
2752}
2753
2754
2755void Hydrogen::ComputeHumantimeFrames(uint32_t nFrames)
2756{
2757        if ( ( m_audioEngineState == STATE_PLAYING ) )
2758        m_nHumantimeFrames = nFrames + m_nHumantimeFrames;
2759}
2760//~ jack transport master
2761void Hydrogen::triggerRelocateDuringPlay() {
2762        if ( m_pSong->get_mode() == Song::PATTERN_MODE )
2763                m_nPatternStartTick = -1; // This forces the barline position
2764}
2765
2766void Hydrogen::togglePlaysSelected() {
2767        if ( getSong()->get_mode() != Song::PATTERN_MODE )
2768                return;
2769        Preferences * P = Preferences::getInstance();
2770       
2771        AudioEngine::get_instance()->lock( "Live mode" );
2772       
2773        bool isPlaysSelected = P->patternModePlaysSelected();
2774
2775        if (isPlaysSelected)
2776        {
2777                m_pPlayingPatterns->clear();
2778                Pattern * pSelectedPattern = m_pSong->get_pattern_list()->get(m_nSelectedPatternNumber);
2779                m_pPlayingPatterns->add( pSelectedPattern );
2780        }
2781
2782        P->setPatternModePlaysSelected( !isPlaysSelected );
2783       
2784        AudioEngine::get_instance()->unlock();
2785       
2786}
2787
2788};
2789
Note: See TracBrowser for help on using the browser.