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

Revision 1284, 74.7 KB (checked in by gabriel@…, 4 years ago)

Drop audioEngine state when loading drum kit.

Loading a drumkit (Hydrogen::loadDrumkit()) is not RT safe because
some of the functions that it calls will load samples and allocate
memory for those samples. Therefore, m_audioEngineState
(hydrogen.cpp) is dropped below STATE_READY so that the process()
callback will "short-circuit" while we wait on the drumkit to load.

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