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

Revision 2444, 87.6 KB (checked in by wolke, 16 months ago)

bugfix against ticket 131 "the export song function don't support bpm changes in timeline"

tempo changing without use of rubberband batch processor is now possible.
the rubberband batch processor is not fast enough here. so i decide to disable them on audio export.

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