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

Revision 1467, 86.7 KB (checked in by wolke, 3 years ago)

fix the export end of song problem

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