root/trunk/src/core/src/hydrogen.cpp @ 2253

Revision 2253, 86.4 KB (checked in by jeremyz, 2 years ago)

Filesystem: drumkit_path=>drumkit_path_search, drumkit_location=>drumkit_dir_search + fix comments

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