root/branches/transport_redesign_2/libs/hydrogen/src/sampler/sampler.cpp @ 1078

Revision 1078, 23.6 KB (checked in by gabriel@…, 4 years ago)

Change how the instrument index is handled to get Song* out of Sampler.

Everything compiles except hydrogen.cpp.

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 <cassert>
24#include <cmath>
25#include <list>
26
27#include <hydrogen/IO/AudioOutput.h>
28#include <hydrogen/IO/JackOutput.h>
29
30#include <hydrogen/adsr.h>
31#include <hydrogen/audio_engine.h>
32#include <hydrogen/data_path.h>
33#include <hydrogen/globals.h>
34#include <hydrogen/hydrogen.h>
35#include <hydrogen/instrument.h>
36#include <hydrogen/note.h>
37#include <hydrogen/Preferences.h>
38#include <hydrogen/sample.h>
39#include <hydrogen/SeqScriptIterator.h>
40
41#include <hydrogen/fx/Effects.h>
42#include <hydrogen/sampler/Sampler.h>
43#include <hydrogen/TransportPosition.h>
44
45using namespace H2Core;
46
47inline static float linear_interpolation( float fVal_A, float fVal_B, float fVal )
48{
49        return fVal_A * ( 1 - fVal ) + fVal_B * fVal;
50//      return fVal_A + fVal * ( fVal_B - fVal_A );
51//      return fVal_A + ((fVal_B - fVal_A) * fVal);
52}
53
54struct H2Core::SamplerPrivate : public Object
55{
56        Sampler& parent;
57        typedef std::list<Note> NoteList;
58        NoteList current_notes;                // Replaces __playing_notes_queue
59        AudioOutput* audio_output;              // Replaces __audio_output
60        Instrument* preview_instrument;         // Replaces __preview_instrument
61#ifdef JACK_SUPPORT
62        float* track_out_L[ MAX_INSTRUMENTS ];  // Replaces __track_out_L
63        float* track_out_R[ MAX_INSTRUMENTS ];  // Replaces __track_out_R
64#endif
65        SamplerPrivate(Sampler* par) :
66                Object( "SamplerPrivate" ),
67                parent( *par ),
68                audio_output( 0 ),
69                preview_instrument( 0 )
70                {}
71
72        // Add/Remove notes from current_notes based on event 'ev'
73        void handle_event(const SeqEvent& ev);
74
75        // These are utils for handle_event().
76        void panic();  // Cease all sounc
77        void handle_note_on(const SeqEvent& ev);
78        void handle_note_off(const SeqEvent& ev);
79
80        // Actually render the specific note(s) to the buffers.
81        int render_note(Note& note, uint32_t nFrames, uint32_t frame_rate);
82        int render_note_no_resample(
83                Sample *pSample,
84                Note& note,
85                int nFrames,
86                float cost_L,
87                float cost_R,
88                float cost_track_L,
89                float cost_track_R,
90                float fSendFXLevel_L,
91                float fSendFXLevel_R
92                );
93        int render_note_resample(
94                Sample *pSample,
95                Note& note,
96                int nFrames,
97                uint32_t frame_rate,
98                float cost_L,
99                float cost_R,
100                float cost_track_L,
101                float cost_track_R,
102                float fLayerPitch,
103                float fSendFXLevel_L,
104                float fSendFXLevel_R
105                );
106
107}; // class SamplerPrivate
108
109void SamplerPrivate::handle_event(const SeqEvent& ev)
110{
111        switch(ev.type) {
112        case SeqEvent::NOTE_ON:
113                handle_note_on(ev);
114                break;
115        case SeqEvent::NOTE_OFF:
116                handle_note_off(ev);
117                break;
118        case SeqEvent::ALL_OFF:
119                panic();
120                break;
121        }
122}
123
124void SamplerPrivate::panic()
125{
126        parent.stop_playing_notes(0);
127}
128
129void SamplerPrivate::handle_note_on(const SeqEvent& ev)
130{
131        // Respect the mute groups.
132        Instrument *pInstr = ev.note.get_instrument();
133        if ( pInstr->get_mute_group() != -1 ) {
134                // remove all notes using the same mute group
135                NoteList::iterator j, prev;
136                Instrument *otherInst = 0;
137                for ( j = current_notes.begin() ; j != current_notes.end() ; ++j ) {
138                        otherInst = j->get_instrument();
139                        if( (otherInst != pInstr)
140                            && (otherInst->get_mute_group() == pInstr->get_mute_group())) {
141                                j->m_adsr.release();
142                        }
143                }
144        }
145        pInstr->enqueue();
146        current_notes.push_back( ev.note );
147        current_notes.back().m_nSilenceOffset = ev.frame;
148        current_notes.back().m_uInstrumentIndex = ev.instrument_index;
149        assert(ev.instrument_index >= 0);
150        assert(ev.instrument_index < MAX_INSTRUMENTS);
151}
152
153void SamplerPrivate::handle_note_off(const SeqEvent& ev)
154{
155        NoteList::iterator k;
156        for( k=current_notes.begin() ; k!=current_notes.end() ; ++k ) {
157                if( k->get_instrument() == ev.note.get_instrument() ) {
158                        k->m_nReleaseOffset = ev.frame;
159                }
160        }
161}
162
163Sampler::Sampler()
164                : Object( "Sampler" )
165                , __main_out_L( 0 )
166                , __main_out_R( 0 )
167{
168        INFOLOG( "INIT" );
169
170        d = new SamplerPrivate(this);
171
172        __main_out_L = new float[ MAX_BUFFER_SIZE ];
173        __main_out_R = new float[ MAX_BUFFER_SIZE ];
174
175        // instrument used in file preview
176        QString sEmptySampleFilename = DataPath::get_data_path() + "/emptySample.wav";
177        d->preview_instrument = new Instrument( sEmptySampleFilename, "preview", new ADSR() );
178        d->preview_instrument->set_volume( 0.8 );
179        d->preview_instrument->set_layer( new InstrumentLayer( Sample::load( sEmptySampleFilename ) ), 0 );
180}
181
182
183
184Sampler::~Sampler()
185{
186        INFOLOG( "DESTROY" );
187
188        delete[] __main_out_L;
189        delete[] __main_out_R;
190
191        delete d->preview_instrument;
192        d->preview_instrument = NULL;
193}
194
195void Sampler::panic()
196{
197        d->panic();
198}
199
200int Sampler::get_playing_notes_number()
201{
202        return d->current_notes.size();
203}
204
205// Do not use B:b.t or frame info from pos.
206// This param may be replaced with 'frame_rate' instead.
207void Sampler::process( SeqScriptConstIterator beg,
208                       SeqScriptConstIterator end,
209                       const TransportPosition& pos,
210                       uint32_t nFrames )
211{
212        //infoLog( "[process]" );
213        assert( d->audio_output );
214
215        memset( __main_out_L, 0, nFrames * sizeof( float ) );
216        memset( __main_out_R, 0, nFrames * sizeof( float ) );
217
218
219#ifdef JACK_SUPPORT
220        JackOutput* jao;
221        jao = dynamic_cast<JackOutput*>(d->audio_output);
222        if (jao) {
223                int numtracks = jao->getNumTracks();
224
225                if ( jao->has_track_outs() ) {
226                        for(int nTrack = 0; nTrack < numtracks; nTrack++) {
227                                memset( d->track_out_L[nTrack],
228                                        0,
229                                        jao->getBufferSize( ) * sizeof( float ) );
230                                memset( d->track_out_R[nTrack],
231                                        0,
232                                        jao->getBufferSize( ) * sizeof( float ) );
233                        }
234                }
235        }
236#endif // JACK_SUPPORT
237
238        // Max notes limit
239        int m_nMaxNotes = Preferences::getInstance()->m_nMaxNotes;
240        while ( ( int )d->current_notes.size() > m_nMaxNotes ) {
241                d->current_notes.front().get_instrument()->dequeue();
242                d->current_notes.pop_front();
243        }
244
245        // Handle new events from the sequencer (add/remove notes from the "currently playing"
246        // list.
247        SeqScriptConstIterator ev;
248        for( ev = beg ; ev != end ; ++ev ) {
249                d->handle_event(*ev);
250        }
251
252        // Play all of the currently playing notes.
253        SamplerPrivate::NoteList::iterator k, die;
254        for( k=d->current_notes.begin() ; k != d->current_notes.end() ; /*++k*/ ) {
255                unsigned res = d->render_note( *k, nFrames, pos.frame_rate );
256                if( res == 1 ) { // Note is finished playing
257                        die = k;  ++k;
258                        die->get_instrument()->dequeue();
259                        d->current_notes.erase(die);
260                } else {
261                        ++k;
262                }
263        }
264}
265
266/// Render a note
267/// Return 0: the note is not ended
268/// Return 1: the note is ended
269int SamplerPrivate::render_note( Note& note, uint32_t nFrames, uint32_t frame_rate )
270{
271        //infoLog( "[renderNote] instr: " + note.getInstrument()->m_sName );
272
273        Instrument *pInstr = note.get_instrument();
274        if ( !pInstr ) {
275                ERRORLOG( "NULL instrument" );
276                return 1;
277        }
278
279        float fLayerGain = 1.0;
280        float fLayerPitch = 0.0;
281
282        // scelgo il sample da usare in base alla velocity
283        Sample *pSample = NULL;
284        for ( unsigned nLayer = 0; nLayer < MAX_LAYERS; ++nLayer ) {
285                InstrumentLayer *pLayer = pInstr->get_layer( nLayer );
286                if ( pLayer == NULL ) continue;
287
288                if ( ( note.get_velocity() >= pLayer->get_start_velocity() )
289                     && ( note.get_velocity() <= pLayer->get_end_velocity() ) ) {
290                        pSample = pLayer->get_sample();
291                        fLayerGain = pLayer->get_gain();
292                        fLayerPitch = pLayer->get_pitch();
293                        break;
294                }
295        }
296        if ( !pSample ) {
297                QString dummy = QString( "NULL sample for instrument %1. Note velocity: %2" )
298                        .arg( pInstr->get_name() )
299                        .arg( note.get_velocity() );
300                WARNINGLOG( dummy );
301                return 1;
302        }
303
304        if ( note.m_fSamplePosition >= pSample->get_n_frames() ) {
305                WARNINGLOG( "sample position out of bounds. The layer has been resized during note play?" );
306                return 1;
307        }
308
309        float cost_L = 1.0f;
310        float cost_R = 1.0f;
311        float cost_track_L = 1.0f;
312        float cost_track_R = 1.0f;
313        float fSendFXLevel_L = 1.0f;
314        float fSendFXLevel_R = 1.0f;
315
316        if ( pInstr->is_muted() ) {                             // is instrument muted?
317                cost_L = 0.0;
318                cost_R = 0.0;
319                if ( Preferences::getInstance()->m_nJackTrackOutputMode == 0 ) {
320                // Post-Fader
321                        cost_track_L = 0.0;
322                        cost_track_R = 0.0;
323                }
324
325                fSendFXLevel_L = 0.0f;
326                fSendFXLevel_R = 0.0f;
327        } else {        // Precompute some values...
328                cost_L = cost_L * note.get_velocity();          // note velocity
329                cost_L = cost_L * note.get_pan_l();             // note pan
330                cost_L = cost_L * fLayerGain;                           // layer gain
331                cost_L = cost_L * pInstr->get_pan_l();          // instrument pan
332                cost_L = cost_L * pInstr->get_gain();           // instrument gain
333                fSendFXLevel_L = cost_L;
334
335                cost_L = cost_L * pInstr->get_volume();         // instrument volume
336                if ( Preferences::getInstance()->m_nJackTrackOutputMode == 0 ) {
337                // Post-Fader
338                        cost_track_L = cost_L * 2;
339                }
340                #warning "WTF is song volume???"
341                /*
342                cost_L = cost_L * pSong->get_volume();  // song volume
343                */
344                cost_L = cost_L * 2; // max pan is 0.5
345
346
347                cost_R = cost_R * note.get_velocity();          // note velocity
348                cost_R = cost_R * note.get_pan_r();             // note pan
349                cost_R = cost_R * fLayerGain;                           // layer gain
350                cost_R = cost_R * pInstr->get_pan_r();          // instrument pan
351                cost_R = cost_R * pInstr->get_gain();           // instrument gain
352                fSendFXLevel_R = cost_R;
353
354                cost_R = cost_R * pInstr->get_volume();         // instrument volume
355                if ( Preferences::getInstance()->m_nJackTrackOutputMode == 0 ) {
356                // Post-Fader
357                        cost_track_R = cost_R * 2;
358                }
359                #warning "WTF is song volume???"
360                /*
361                cost_R = cost_R * pSong->get_volume();  // song pan
362                */
363                cost_R = cost_R * 2; // max pan is 0.5
364        }
365
366        // direct track outputs only use velocity
367        if ( Preferences::getInstance()->m_nJackTrackOutputMode == 1 ) {
368                cost_track_L = cost_track_L * note.get_velocity();
369                cost_track_L = cost_track_L * fLayerGain;
370                cost_track_R = cost_track_L;
371        }
372
373        // Se non devo fare resample (drumkit) posso evitare di utilizzare i float e gestire il tutto in
374        // maniera ottimizzata
375        //      constant^12 = 2, so constant = 2^(1/12) = 1.059463.
376        //      float nStep = 1.0;1.0594630943593
377
378        float fTotalPitch = note.m_noteKey.m_nOctave * 12 + note.m_noteKey.m_key;
379        fTotalPitch += note.get_pitch();
380        fTotalPitch += fLayerPitch;
381
382        //_INFOLOG( "total pitch: " + to_string( fTotalPitch ) );
383
384        if ( fTotalPitch == 0.0
385             && pSample->get_sample_rate() == frame_rate ) {
386                // NO RESAMPLE
387                return render_note_no_resample(
388                        pSample,
389                        note,
390                        nFrames,
391                        cost_L,
392                        cost_R,
393                        cost_track_L,
394                        cost_track_R,
395                        fSendFXLevel_L,
396                        fSendFXLevel_R
397                        );
398        } else {
399                // RESAMPLE
400                return render_note_resample(
401                        pSample,
402                        note,
403                        nFrames,
404                        frame_rate,
405                        cost_L,
406                        cost_R,
407                        cost_track_L,
408                        cost_track_R,
409                        fLayerPitch,
410                        fSendFXLevel_L,
411                        fSendFXLevel_R
412                        );
413        }
414} // SamplerPrivate::render_note()
415
416
417
418
419int SamplerPrivate::render_note_no_resample(
420    Sample *pSample,
421    Note& note,
422    int nFrames,
423    float cost_L,
424    float cost_R,
425    float cost_track_L,
426    float cost_track_R,
427    float fSendFXLevel_L,
428    float fSendFXLevel_R
429)
430{
431        int retValue = 1; // the note is ended
432
433        int nAvail_bytes = pSample->get_n_frames() - ( int )note.m_fSamplePosition;   // verifico
434
435        if ( nAvail_bytes > nFrames - note.m_nSilenceOffset ) {   // il sample e' piu' grande del buff
436                // imposto il numero dei bytes disponibili uguale al buffersize
437                nAvail_bytes = nFrames - note.m_nSilenceOffset;
438                retValue = 0; // the note is not ended yet
439        }
440       
441        //ADSR *pADSR = note.m_pADSR;
442
443        int nInitialBufferPos = note.m_nSilenceOffset;
444        int nInitialSamplePos = ( int )note.m_fSamplePosition;
445        int nSamplePos = nInitialSamplePos;
446        int nTimes = nInitialBufferPos + nAvail_bytes;
447        int nInstrument = note.m_uInstrumentIndex;
448
449        // filter
450        bool bUseLPF = note.get_instrument()->is_filter_active();
451        float fResonance = note.get_instrument()->get_filter_resonance();
452        float fCutoff = note.get_instrument()->get_filter_cutoff();
453
454        float *pSample_data_L = pSample->get_data_l();
455        float *pSample_data_R = pSample->get_data_r();
456
457        float fInstrPeak_L = note.get_instrument()->get_peak_l(); // this value will be reset to 0 by the mixer..
458        float fInstrPeak_R = note.get_instrument()->get_peak_r(); // this value will be reset to 0 by the mixer..
459
460        float fADSRValue;
461        float fVal_L;
462        float fVal_R;
463
464        /*
465         * nInstrument could be -1 if the instrument is not found in the current drumset.
466         * This happens when someone is using the prelistening function of the soundlibrary.
467         */
468
469        if( nInstrument < 0 ) {
470                nInstrument = 0;
471        }
472
473
474        for ( int nBufferPos = nInitialBufferPos; nBufferPos < nTimes; ++nBufferPos ) {
475                if( note.m_nReleaseOffset != (uint32_t)-1
476                    && nBufferPos >= note.m_nReleaseOffset ) {
477                        if ( note.m_adsr.release() == 0 ) {
478                                retValue = 1;   // the note is ended
479                        }
480                }
481
482                fADSRValue = note.m_adsr.get_value( 1 );
483                fVal_L = pSample_data_L[ nSamplePos ] * fADSRValue;
484                fVal_R = pSample_data_R[ nSamplePos ] * fADSRValue;
485
486                // Low pass resonant filter
487                if ( bUseLPF ) {
488                        note.m_fBandPassFilterBuffer_L = fResonance * note.m_fBandPassFilterBuffer_L + fCutoff * ( fVal_L - note.m_fLowPassFilterBuffer_L );
489                        note.m_fLowPassFilterBuffer_L += fCutoff * note.m_fBandPassFilterBuffer_L;
490                        fVal_L = note.m_fLowPassFilterBuffer_L;
491
492                        note.m_fBandPassFilterBuffer_R = fResonance * note.m_fBandPassFilterBuffer_R + fCutoff * ( fVal_R - note.m_fLowPassFilterBuffer_R );
493                        note.m_fLowPassFilterBuffer_R += fCutoff * note.m_fBandPassFilterBuffer_R;
494                        fVal_R = note.m_fLowPassFilterBuffer_R;
495                }
496
497#ifdef JACK_SUPPORT
498                if ( audio_output->has_track_outs()
499                     && dynamic_cast<JackOutput*>(audio_output) ) {
500                        assert( track_out_L[ nInstrument ] );
501                        assert( track_out_R[ nInstrument ] );
502                        track_out_L[ nInstrument ][nBufferPos] += fVal_L * cost_track_L;
503                        track_out_R[ nInstrument ][nBufferPos] += fVal_R * cost_track_R;
504                }
505#endif
506
507                fVal_L = fVal_L * cost_L;
508                fVal_R = fVal_R * cost_R;
509
510                // update instr peak
511                if ( fVal_L > fInstrPeak_L ) {
512                        fInstrPeak_L = fVal_L;
513                }
514                if ( fVal_R > fInstrPeak_R ) {
515                        fInstrPeak_R = fVal_R;
516                }
517
518                // to main mix
519                parent.__main_out_L[nBufferPos] += fVal_L;
520                parent.__main_out_R[nBufferPos] += fVal_R;
521
522                ++nSamplePos;
523        }
524        note.m_fSamplePosition += nAvail_bytes;
525        note.m_nSilenceOffset = 0;
526        note.get_instrument()->set_peak_l( fInstrPeak_L );
527        note.get_instrument()->set_peak_r( fInstrPeak_R );
528
529
530#ifdef LADSPA_SUPPORT
531        // LADSPA
532        for ( unsigned nFX = 0; nFX < MAX_FX; ++nFX ) {
533                LadspaFX *pFX = Effects::getInstance()->getLadspaFX( nFX );
534
535                float fLevel = note.get_instrument()->get_fx_level( nFX );
536
537                if ( ( pFX ) && ( fLevel != 0.0 ) ) {
538                        fLevel = fLevel * pFX->getVolume();
539                        float *pBuf_L = pFX->m_pBuffer_L;
540                        float *pBuf_R = pFX->m_pBuffer_R;
541
542//                      float fFXCost_L = cost_L * fLevel;
543//                      float fFXCost_R = cost_R * fLevel;
544                        float fFXCost_L = fLevel * fSendFXLevel_L;
545                        float fFXCost_R = fLevel * fSendFXLevel_R;
546
547                        int nBufferPos = nInitialBufferPos;
548                        int nSamplePos = nInitialSamplePos;
549                        for ( int i = 0; i < nAvail_bytes; ++i ) {
550                                pBuf_L[ nBufferPos ] += pSample_data_L[ nSamplePos ] * fFXCost_L * cost_L;
551                                pBuf_R[ nBufferPos ] += pSample_data_R[ nSamplePos ] * fFXCost_R * cost_R;
552                                ++nSamplePos;
553                                ++nBufferPos;
554                        }
555                }
556        }
557        // ~LADSPA
558#endif
559
560        return retValue;
561}
562
563
564
565int SamplerPrivate::render_note_resample(
566    Sample *pSample,
567    Note& note,
568    int nFrames,
569    uint32_t frame_rate,
570    float cost_L,
571    float cost_R,
572    float cost_track_L,
573    float cost_track_R,
574    float fLayerPitch,
575    float fSendFXLevel_L,
576    float fSendFXLevel_R
577)
578{
579        float fNotePitch = note.get_pitch() + fLayerPitch;
580        fNotePitch += note.m_noteKey.m_nOctave * 12 + note.m_noteKey.m_key;
581
582        //_INFOLOG( "pitch: " + to_string( fNotePitch ) );
583
584        float fStep = pow( 1.0594630943593, ( double )fNotePitch );
585        fStep *= ( float )pSample->get_sample_rate() / frame_rate; // Adjust for audio driver sample rate
586
587        int nAvail_bytes = ( int )( ( float )( pSample->get_n_frames() - note.m_fSamplePosition ) / fStep );    // verifico il numero di frame disponibili ancora da eseguire
588
589        int retValue = 1; // the note is ended
590        if ( nAvail_bytes > nFrames - note.m_nSilenceOffset ) { // il sample e' piu' grande del buffersize
591                // imposto il numero dei bytes disponibili uguale al buffersize
592                nAvail_bytes = nFrames - note.m_nSilenceOffset;
593                retValue = 0; // the note is not ended yet
594        }
595
596//      ADSR *pADSR = note.m_pADSR;
597
598        int nInitialBufferPos = note.m_nSilenceOffset;
599        float fInitialSamplePos = note.m_fSamplePosition;
600        float fSamplePos = note.m_fSamplePosition;
601        int nTimes = nInitialBufferPos + nAvail_bytes;
602        int nInstrument = note.m_uInstrumentIndex;
603
604        // filter
605        bool bUseLPF = note.get_instrument()->is_filter_active();
606        float fResonance = note.get_instrument()->get_filter_resonance();
607        float fCutoff = note.get_instrument()->get_filter_cutoff();
608
609        float *pSample_data_L = pSample->get_data_l();
610        float *pSample_data_R = pSample->get_data_r();
611
612        float fInstrPeak_L = note.get_instrument()->get_peak_l(); // this value will be reset to 0 by the mixer..
613        float fInstrPeak_R = note.get_instrument()->get_peak_r(); // this value will be reset to 0 by the mixer..
614
615        float fADSRValue = 1.0;
616        float fVal_L;
617        float fVal_R;
618        int nSampleFrames = pSample->get_n_frames();
619
620        /*
621         * nInstrument could be -1 if the instrument is not found in the current drumset.
622         * This happens when someone is using the prelistening function of the soundlibrary.
623         */
624
625        if( nInstrument < 0 ) {
626                nInstrument = 0;
627        }
628
629
630        for ( int nBufferPos = nInitialBufferPos; nBufferPos < nTimes; ++nBufferPos ) {
631                if( note.m_nReleaseOffset != (uint32_t)-1
632                    && nBufferPos >= note.m_nReleaseOffset )
633                {
634                        if ( note.m_adsr.release() == 0 ) {
635                                retValue = 1;   // the note is ended
636                        }
637                }
638
639                int nSamplePos = ( int )fSamplePos;
640                float fDiff = fSamplePos - nSamplePos;
641                if ( ( nSamplePos + 1 ) >= nSampleFrames ) {
642                        fVal_L = linear_interpolation( pSample_data_L[ nSampleFrames ], 0, fDiff );
643                        fVal_R = linear_interpolation( pSample_data_R[ nSampleFrames ], 0, fDiff );
644                } else {
645                        fVal_L = linear_interpolation( pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], fDiff );
646                        fVal_R = linear_interpolation( pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], fDiff );
647                }
648
649                // ADSR envelope
650                fADSRValue = note.m_adsr.get_value( fStep );
651                fVal_L = fVal_L * fADSRValue;
652                fVal_R = fVal_R * fADSRValue;
653
654                // Low pass resonant filter
655                if ( bUseLPF ) {
656                        note.m_fBandPassFilterBuffer_L = fResonance * note.m_fBandPassFilterBuffer_L + fCutoff * ( fVal_L - note.m_fLowPassFilterBuffer_L );
657                        note.m_fLowPassFilterBuffer_L += fCutoff * note.m_fBandPassFilterBuffer_L;
658                        fVal_L = note.m_fLowPassFilterBuffer_L;
659
660                        note.m_fBandPassFilterBuffer_R = fResonance * note.m_fBandPassFilterBuffer_R + fCutoff * ( fVal_R - note.m_fLowPassFilterBuffer_R );
661                        note.m_fLowPassFilterBuffer_R += fCutoff * note.m_fBandPassFilterBuffer_R;
662                        fVal_R = note.m_fLowPassFilterBuffer_R;
663                }
664
665
666#ifdef JACK_SUPPORT
667                if ( audio_output->has_track_outs()
668                        && dynamic_cast<JackOutput*>(audio_output) ) {
669                        assert( track_out_L[ nInstrument ] );
670                        assert( track_out_R[ nInstrument ] );
671                        track_out_L[ nInstrument ][nBufferPos] += (fVal_L * cost_track_L);
672                        track_out_R[ nInstrument ][nBufferPos] += (fVal_R * cost_track_R);
673                }
674#endif
675
676                fVal_L = fVal_L * cost_L;
677                fVal_R = fVal_R * cost_R;
678
679                // update instr peak
680                if ( fVal_L > fInstrPeak_L ) {
681                        fInstrPeak_L = fVal_L;
682                }
683                if ( fVal_R > fInstrPeak_R ) {
684                        fInstrPeak_R = fVal_R;
685                }
686
687                // to main mix
688                parent.__main_out_L[nBufferPos] += fVal_L;
689                parent.__main_out_R[nBufferPos] += fVal_R;
690
691                fSamplePos += fStep;
692        }
693        note.m_fSamplePosition += nAvail_bytes * fStep;
694        note.get_instrument()->set_peak_l( fInstrPeak_L );
695        note.get_instrument()->set_peak_r( fInstrPeak_R );
696
697
698
699#ifdef LADSPA_SUPPORT
700        // LADSPA
701        for ( unsigned nFX = 0; nFX < MAX_FX; ++nFX ) {
702                LadspaFX *pFX = Effects::getInstance()->getLadspaFX( nFX );
703                float fLevel = note.get_instrument()->get_fx_level( nFX );
704                if ( ( pFX ) && ( fLevel != 0.0 ) ) {
705                        fLevel = fLevel * pFX->getVolume();
706
707                        float *pBuf_L = pFX->m_pBuffer_L;
708                        float *pBuf_R = pFX->m_pBuffer_R;
709
710//                      float fFXCost_L = cost_L * fLevel;
711//                      float fFXCost_R = cost_R * fLevel;
712                        float fFXCost_L = fLevel * fSendFXLevel_L;
713                        float fFXCost_R = fLevel * fSendFXLevel_R;
714
715                        int nBufferPos = nInitialBufferPos;
716                        float fSamplePos = fInitialSamplePos;
717                        for ( int i = 0; i < nAvail_bytes; ++i ) {
718                                int nSamplePos = ( int )fSamplePos;
719                                float fDiff = fSamplePos - nSamplePos;
720
721                                if ( ( nSamplePos + 1 ) >= nSampleFrames ) {
722                                        fVal_L = linear_interpolation( pSample_data_L[nSamplePos], 0, fDiff );
723                                        fVal_R = linear_interpolation( pSample_data_R[nSamplePos], 0, fDiff );
724                                } else {
725                                        fVal_L = linear_interpolation( pSample_data_L[nSamplePos], pSample_data_L[nSamplePos + 1], fDiff );
726                                        fVal_R = linear_interpolation( pSample_data_R[nSamplePos], pSample_data_R[nSamplePos + 1], fDiff );
727                                }
728
729                                pBuf_L[ nBufferPos ] += fVal_L * fFXCost_L * cost_L;
730                                pBuf_R[ nBufferPos ] += fVal_R * fFXCost_R * cost_R;
731                                fSamplePos += fStep;
732                                ++nBufferPos;
733                        }
734                }
735        }
736#endif
737
738        return retValue;
739}
740
741void note_on( Note* note )
742{
743        assert(false);
744}
745
746void note_off( Note* note )
747{
748        assert(false);
749}
750
751void Sampler::stop_playing_notes( Instrument* instrument )
752{
753        /*
754        // send a note-off event to all notes present in the playing note queue
755        for ( int i = 0; i < d->current_notes.size(); ++i ) {
756                Note *pNote = d->current_notes[ i ];
757                note.m_pADSR->release();
758        }
759        */
760
761        if ( instrument ) { // stop all notes using this instrument
762                SamplerPrivate::NoteList::iterator k, die;
763                for( k=d->current_notes.begin() ; k!=d->current_notes.end() ; /* ++k */ ) {
764                        if( k->get_instrument() == instrument ) {
765                                die = k; ++k;
766                                d->current_notes.erase(die);
767                                instrument->dequeue();
768                        } else {
769                                ++k;
770                        }
771                }
772        } else { // stop all notes
773                SamplerPrivate::NoteList::iterator k;
774                for( k=d->current_notes.begin() ; k!=d->current_notes.end() ; ++k ) {
775                        k->get_instrument()->dequeue();
776                }
777                d->current_notes.clear();
778        }
779}
780
781
782
783/// Preview, uses only the first layer
784void Sampler::preview_sample( Sample* sample, int length )
785{
786        AudioEngine::get_instance()->lock( "Sampler::previewSample" );
787
788        InstrumentLayer *pLayer = d->preview_instrument->get_layer( 0 );
789
790        Sample *pOldSample = pLayer->get_sample();
791        pLayer->set_sample( sample );
792
793        Note *previewNote = new Note( d->preview_instrument, 0, 1.0, 0.5, 0.5, 0 );
794
795        stop_playing_notes( d->preview_instrument );
796        note_on( previewNote );
797        delete pOldSample;
798
799        AudioEngine::get_instance()->unlock();
800}
801
802
803
804void Sampler::preview_instrument( Instrument* instr )
805{
806        Instrument * old_preview;
807        AudioEngine::get_instance()->lock( "Sampler::previewInstrument" );
808
809        stop_playing_notes( d->preview_instrument );
810
811        old_preview = d->preview_instrument;
812        d->preview_instrument = instr;
813
814        Note *previewNote = new Note( d->preview_instrument, 0, 1.0, 0.5, 0.5, 0 );
815
816        note_on( previewNote ); // exclusive note
817        AudioEngine::get_instance()->unlock();
818        delete old_preview;
819}
820
821
822
823void Sampler::set_audio_output( AudioOutput* audio_output )
824{
825        d->audio_output = audio_output;
826}
827
828void Sampler::makeTrackOutputQueues( )
829{
830        INFOLOG( "Making Output Queues" );
831
832#ifdef JACK_SUPPORT
833        JackOutput* jao = 0;
834        if (d->audio_output && d->audio_output->has_track_outs() ) {
835                jao = dynamic_cast<JackOutput*>(d->audio_output);
836        }
837        if ( jao ) {
838                for (int nTrack = 0; nTrack < jao->getNumTracks( ); nTrack++) {
839                        d->track_out_L[nTrack] = jao->getTrackOut_L( nTrack );
840                        assert( d->track_out_L[ nTrack ] );
841                        d->track_out_R[nTrack] = jao->getTrackOut_R( nTrack );
842                        assert( d->track_out_R[ nTrack ] );
843                }
844        }
845#endif // JACK_SUPPORT
846
847}
Note: See TracBrowser for help on using the browser.