root/branches/new_fx_rack_and_sample_fun/libs/hydrogen/src/hydrogen.cpp @ 781

Revision 781, 78.6 KB (checked in by wolke, 4 years ago)

apply rec. button patch from pablomme and merge 772:780 from trunk

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