root/branches/jackMidi/libs/hydrogen/src/hydrogen.cpp @ 401

Revision 401, 72.3 KB (checked in by gabriel, 5 years ago)

Merge rev 373:374 from trunk.

Conflicts:

features.pri
libs/hydrogen/src/hydrogen.cpp

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