~ubuntu-branches/ubuntu/quantal/muse/quantal

« back to all changes in this revision

Viewing changes to muse/audiotrack.cpp

  • Committer: Package Import Robot
  • Author(s): Alessio Treglia
  • Date: 2012-07-18 16:07:06 UTC
  • mto: (10.1.11 sid) (1.1.12)
  • mto: This revision was merged to the branch mainline in revision 31.
  • Revision ID: package-import@ubuntu.com-20120718160706-yc6332ishfcq7b7g
ImportĀ upstreamĀ versionĀ 2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
//
22
22
//=========================================================
23
23
 
24
 
#include <values.h>
 
24
#include <limits.h>
25
25
#include <stdlib.h>
26
26
#include <map>
27
27
 
39
39
#include "synth.h"
40
40
#include "dssihost.h"
41
41
#include "app.h"
 
42
#include "controlfifo.h"
42
43
 
43
44
namespace MusECore {
44
45
 
48
49
bool AudioGroup::_isVisible =false;
49
50
bool WaveTrack::_isVisible=true;
50
51
 
 
52
// DELETETHIS 40. this caching stuff seems to be not used any more
51
53
// By T356. For caching jack in/out routing names BEFORE file save. 
52
54
// Jack often shuts down during file save, causing the routes to be lost in the file.
53
55
// cacheJackRouteNames() is ONLY called from MusE::save() in app.cpp
95
97
AudioTrack::AudioTrack(TrackType t)
96
98
   : Track(t)
97
99
      {
98
 
      //_totalOutChannels = num_out_bufs; // Is either parameter-default MAX_CHANNELS, or custom value passed (used by syntis).
99
100
      _processed = false;
100
101
      _haveData = false;
101
102
      _sendMetronome = false;
102
103
      _prefader = false;
103
104
      _efxPipe  = new Pipeline();
104
 
      _recFile  = 0;
 
105
      //_recFile  = 0; //unneeded, _recFile's ctor does this
105
106
      _channels = 0;
106
107
      _automationType = AUTO_OFF;
107
 
      //setChannels(1);
108
108
      setChannels(2);
109
109
      addController(new CtrlList(AC_VOLUME,"Volume",0.001,3.163 /* roughly 10 db */, VAL_LOG));
110
110
      addController(new CtrlList(AC_PAN, "Pan", -1.0, 1.0, VAL_LINEAR));
111
111
      addController(new CtrlList(AC_MUTE,"Mute",0.0,1.0, VAL_LINEAR, true /*dont show in arranger */));
112
112
      
113
 
      //outBuffers = new float*[MAX_CHANNELS];
114
 
      //for (int i = 0; i < MAX_CHANNELS; ++i)
115
 
      //      outBuffers[i] = new float[MusEGlobal::segmentSize];
116
 
      //for (int i = 0; i < MAX_CHANNELS; ++i)
117
 
      //      posix_memalign((void**)(outBuffers + i), 16, sizeof(float) * MusEGlobal::segmentSize);
118
 
      
119
 
      // Let's allocate it all in one block, and just point the remaining buffer pointers into the block
120
 
      //  which allows faster one-shot buffer copying.
121
 
      // Nope. Nice but interferes with possibility we don't know if other buffers are contiguous (jack buffers, local stack buffers etc.).
122
 
      //posix_memalign((void**)(outBuffers), 16, sizeof(float) * MusEGlobal::segmentSize * MAX_CHANNELS);
123
 
      //for (int i = 0; i < MAX_CHANNELS; ++i)
124
 
      //  *(outBuffers + i) = sizeof(float) * MusEGlobal::segmentSize * i;
125
 
            
126
 
      // Easy way, less desirable... Start out with enough for MAX_CHANNELS. Then multi-channel syntis can re-allocate, 
127
 
      //  via a call to (a modified!) setChannels().
128
 
      // Hard way, more desirable... Creating a synti instance passes the total channels to this constructor, overriding MAX_CHANNELS.
 
113
      // for a lot of considerations and failures, see revision 1402 or earlier (flo)
129
114
      _totalOutChannels = MAX_CHANNELS;
130
115
      outBuffers = new float*[_totalOutChannels];
131
116
      for (int i = 0; i < _totalOutChannels; ++i)
134
119
      // This is only set by multi-channel syntis...
135
120
      _totalInChannels = 0;
136
121
      
137
 
      bufferPos = MAXINT;
 
122
      bufferPos = INT_MAX;
138
123
      
139
124
      setVolume(1.0);
140
125
      }
152
137
      // This is only set by multi-channel syntis...
153
138
      _totalInChannels = 0;
154
139
      
155
 
      bufferPos = MAXINT;
 
140
      bufferPos = INT_MAX;
156
141
      
157
 
      //_recFile  = t._recFile;
158
142
      _recFile = NULL;
159
143
      
160
144
      internal_assign(t, flags | ASSIGN_PROPERTIES);  
193
177
        setTotalOutChannels(at._totalOutChannels);
194
178
        
195
179
        // This is only set by multi-channel syntis...
196
 
        //_totalInChannels = 0;
197
 
        //_totalInChannels = t._totalInChannels;
198
180
        setTotalInChannels(at._totalInChannels);
199
181
       
200
182
        setChannels(at.channels()); // Set track channels (max 2).
201
 
        
202
 
        //bufferPos = MAXINT;
203
 
        
204
 
        //_recFile  = at._recFile;
205
 
        //_recFile  = NULL;
206
183
      }    
207
184
      
208
185
      if(flags & ASSIGN_PLUGINS)
231
208
        }
232
209
      }
233
210
      
234
 
      // FIXME: May get "addRoute: src track route already exists" when say, 
235
 
      //         an audio output and wave track are selected just because
236
 
      //         of the redundancy (wave track wants to connect to output by default).
237
211
      if(flags & ASSIGN_ROUTES)
238
212
      {
239
213
        for(ciRoute ir = at._inRoutes.begin(); ir != at._inRoutes.end(); ++ir)
241
215
          // Defer all Jack routes to Audio Input and Output copy constructors or assign !
242
216
          if(ir->type == Route::JACK_ROUTE)
243
217
            continue;
244
 
          // Amazingly, this single line seems to work.
245
 
          MusEGlobal::audio->msgAddRoute(*ir, Route(this, ir->channel, ir->channels));
 
218
          // Don't call msgAddRoute. Caller later calls msgAddTrack which 'mirrors' this routing node.
 
219
          _inRoutes.push_back(*ir);
246
220
        }
247
221
        
248
222
        for(ciRoute ir = at._outRoutes.begin(); ir != at._outRoutes.end(); ++ir)
250
224
          // Defer all Jack routes to Audio Input and Output copy constructors or assign !
251
225
          if(ir->type == Route::JACK_ROUTE)
252
226
            continue;
253
 
          // Amazingly, this single line seems to work.
254
 
          MusEGlobal::audio->msgAddRoute(Route(this, ir->channel, ir->channels), *ir);
 
227
          // Don't call msgAddRoute. Caller later calls msgAddTrack which 'mirrors' this routing node.
 
228
          _outRoutes.push_back(*ir);
255
229
        }
256
230
      } 
257
231
      else if(flags & ASSIGN_DEFAULT_ROUTES)
263
237
        if (!ol->empty()) {
264
238
              AudioOutput* ao = ol->front();
265
239
              switch(type()) {
266
 
                    //case Track::MIDI:
267
 
                    //case Track::DRUM:
268
 
                    //case Track::AUDIO_OUTPUT:
269
 
                    //      break;
270
 
                    
271
240
                    case Track::WAVE:
272
 
                    //case Track::AUDIO_GROUP:  
273
241
                    case Track::AUDIO_AUX:
274
 
                    //case Track::AUDIO_INPUT:  
275
 
                    //case Track::AUDIO_SOFTSYNTH:
276
 
                          MusEGlobal::audio->msgAddRoute(Route(this, -1), Route(ao, -1));
277
 
                          //updateFlags |= SC_ROUTE;
 
242
                          // Don't call msgAddRoute. Caller later calls msgAddTrack which 'mirrors' this routing node.
 
243
                          _outRoutes.push_back(Route(ao, -1));
278
244
                          break;
279
245
                    // It should actually never get here now, but just in case.
280
246
                    case Track::AUDIO_SOFTSYNTH:
281
 
                          MusEGlobal::audio->msgAddRoute(Route(this, 0, channels()), Route(ao, 0, channels()));
282
 
                          //updateFlags |= SC_ROUTE;
 
247
                          // Don't call msgAddRoute. Caller later calls msgAddTrack which 'mirrors' this routing node.
 
248
                          _outRoutes.push_back(Route(ao, 0, channels()));
283
249
                          break;
284
250
                    default:
285
251
                          break;
420
386
 
421
387
void AudioTrack::removeController(int id)
422
388
      {
 
389
      AudioMidiCtrlStructMap amcs;
 
390
      _controller.midiControls()->find_audio_ctrl_structs(id, &amcs);  
 
391
      for(ciAudioMidiCtrlStructMap iamcs = amcs.begin(); iamcs != amcs.end(); ++ iamcs)
 
392
        _controller.midiControls()->erase(*iamcs);
423
393
      iCtrlList i = _controller.find(id);
424
394
      if (i == _controller.end()) {
425
395
            printf("AudioTrack::removeController id %d not found\n", id);
434
404
 
435
405
void AudioTrack::swapControllerIDX(int idx1, int idx2)
436
406
{
437
 
  // FIXME This code is ugly.
438
 
  // At best we would like to modify the keys (IDXs) in-place and
439
 
  //  do some kind of deferred re-sort, but it can't be done...
440
 
  
441
 
  if(idx1 == idx2)
442
 
    return;
443
 
    
444
 
  if(idx1 < 0 || idx2 < 0 || idx1 >= PipelineDepth || idx2 >= PipelineDepth)
 
407
  if(idx1 == idx2 || idx1 < 0 || idx2 < 0 || idx1 >= PipelineDepth || idx2 >= PipelineDepth)
445
408
    return;
446
409
  
447
410
  CtrlList *cl;
448
411
  CtrlList *newcl;
449
412
  int id1 = (idx1 + 1) * AC_PLUGIN_CTL_BASE;
450
413
  int id2 = (idx2 + 1) * AC_PLUGIN_CTL_BASE;
 
414
  int id_mask = ~((int)AC_PLUGIN_CTL_ID_MASK);
451
415
  int i, j;
452
416
  
453
417
  CtrlListList tmpcll;
457
421
  {
458
422
    cl = icl->second;
459
423
    i = cl->id() & AC_PLUGIN_CTL_ID_MASK;
460
 
    j = cl->id() & ~((unsigned long)AC_PLUGIN_CTL_ID_MASK);
 
424
    j = cl->id() & id_mask;
461
425
    if(j == id1 || j == id2)
462
426
    {
463
427
      newcl = new CtrlList(i | (j == id1 ? id2 : id1));
495
459
    _controller.insert(std::pair<const int, CtrlList*>(newcl->id(), newcl));
496
460
  } 
497
461
  
498
 
  
499
 
  /*
500
 
  unsigned int idmask = ~AC_PLUGIN_CTL_ID_MASK;
501
 
  
502
 
  CtrlList* cl;
503
 
  CtrlList* ctl1 = 0;
504
 
  CtrlList* ctl2 = 0;
505
 
  CtrlList* newcl1 = 0;
506
 
  CtrlList* newcl2 = 0;
507
 
  CtrlVal cv(0, 0.0);
508
 
  int id1 = (idx1 + 1) * AC_PLUGIN_CTL_BASE;
509
 
  int id2 = (idx2 + 1) * AC_PLUGIN_CTL_BASE;
510
 
  int i, j;
511
 
  double min, max;
512
 
  
513
 
  for(ciCtrlList icl = _controller.begin(); icl != _controller.end(); ++icl) 
 
462
  // Remap midi to audio controls...
 
463
  MidiAudioCtrlMap* macm = _controller.midiControls();
 
464
  for(iMidiAudioCtrlMap imacm = macm->begin(); imacm != macm->end(); ++imacm)
514
465
  {
515
 
    cl = icl->second;
516
 
    i = cl->id() & AC_PLUGIN_CTL_ID_MASK;
517
 
    j = cl->id() & idmask;
518
 
    
519
 
    if(j == id1)
520
 
    {
521
 
      ctl1 = cl;
522
 
      newcl1 = new CtrlList( i | id2 );
523
 
      newcl1->setMode(cl->mode());
524
 
      newcl1->setValueType(cl->valueType());
525
 
      newcl1->setName(cl->name());
526
 
      cl->range(&min, &max);
527
 
      newcl1->setRange(min, max);
528
 
      newcl1->setCurVal(cl->curVal());
529
 
      newcl1->setDefault(cl->getDefault());
530
 
      for(iCtrl ic = cl->begin(); ic != cl->end(); ++ic) 
531
 
      {
532
 
        cv = ic->second;
533
 
        newcl1->insert(std::pair<const int, CtrlVal>(cv.frame, cv));
534
 
      }
535
 
    }
536
 
    //else  
537
 
    if(j == id2)
538
 
    {
539
 
      ctl2 = cl;
540
 
      newcl2 = new CtrlList( i | id1 );
541
 
      newcl2->setMode(cl->mode());
542
 
      newcl2->setValueType(cl->valueType());
543
 
      newcl2->setName(cl->name());
544
 
      cl->range(&min, &max);
545
 
      newcl2->setRange(min, max);
546
 
      newcl2->setCurVal(cl->curVal());
547
 
      newcl2->setDefault(cl->getDefault());
548
 
      for(iCtrl ic = cl->begin(); ic != cl->end(); ++ic) 
549
 
      {
550
 
        cv = ic->second;
551
 
        newcl2->insert(std::pair<const int, CtrlVal>(cv.frame, cv));
552
 
      }
553
 
    }
554
 
  }  
555
 
  if(ctl1)
556
 
    _controller.erase(ctl1->id());
557
 
  if(ctl2)
558
 
    _controller.erase(ctl2->id());
559
 
  if(newcl1)
560
 
    //_controller.add(newcl1);
561
 
    _controller.insert(std::pair<const int, CtrlList*>(newcl1->id(), newcl1));
562
 
  if(newcl2)
563
 
    _controller.insert(std::pair<const int, CtrlList*>(newcl2->id(), newcl2));
564
 
    //_controller.add(newcl2);
565
 
  */  
 
466
    int actrl = imacm->second.audioCtrlId();
 
467
    int id = actrl & id_mask;
 
468
    actrl &= AC_PLUGIN_CTL_ID_MASK;
 
469
    if(id == id1)
 
470
      actrl |= id2;
 
471
    else if(id == id2)
 
472
      actrl |= id1;
 
473
    else
 
474
      continue;
 
475
    imacm->second.setAudioCtrlId(actrl);
 
476
  }
566
477
}
567
478
 
568
479
//---------------------------------------------------------
616
527
      {
617
528
        // Don't bother looking for start, it's OK, just take the first one.
618
529
        // Needed for mousewheel and paging etc.
619
 
        //if (icr->id == id && icr->type == ARVT_START) 
620
530
        if (icr->id == id) 
621
531
        {
622
532
          int start = icr->frame;
646
556
            if(icr->id == id && icr->type == ARVT_STOP) 
647
557
            {
648
558
              int end = icr->frame;
649
 
              // Erase everything up to, not including, this stop event's frame.
650
 
              // Because an event was already stored directly when slider released.
651
 
              if(end > start)
652
 
                --end;
653
 
                  
 
559
              
654
560
              iCtrl s = cl->lower_bound(start);
655
561
              iCtrl e = cl->lower_bound(end);
656
562
              
672
578
    //  from CtrlRecList and put into cl.
673
579
    for (iCtrlRec icr = _recEvents.begin(); icr != _recEvents.end(); ++icr) 
674
580
    {
675
 
          if (icr->id == id && (icr->type == ARVT_VAL || icr->type == ARVT_START))
 
581
          if (icr->id == id)
 
582
          {
 
583
                // Must optimize these types otherwise multiple vertices appear on flat straight lines in the graphs.
 
584
                CtrlValueType vtype = cl->valueType();
 
585
                if(!cl->empty() && (cl->mode() == CtrlList::DISCRETE || vtype == VAL_BOOL || vtype == VAL_INT))
 
586
                {
 
587
                  iCtrl icl_prev = cl->lower_bound(icr->frame);
 
588
                  if(icl_prev != cl->begin())
 
589
                    --icl_prev;
 
590
                  if(icl_prev->second.val == icr->val)
 
591
                    continue;
 
592
                }  
 
593
                // Now add the value.
676
594
                cl->add(icr->frame, icr->val);
 
595
          }
677
596
    }
678
597
  }
679
598
  
680
599
  // Done with the recorded automation event list. Clear it.
681
600
  _recEvents.clear();
682
 
        
683
 
  // Try muse without this, so that the user can remain in automation write mode
684
 
  //  after a stop. 
685
 
  /*
686
 
  if (automationType() == AUTO_WRITE)
687
 
    {
688
 
        setAutomationType(AUTO_READ);
689
 
        MusEGlobal::song->update(SC_AUTOMATION);
690
 
    }     
691
 
  */
692
 
  
693
601
}
694
602
 
695
603
//---------------------------------------------------------
734
642
    if(cl->empty())
735
643
      return;
736
644
    
737
 
    //iCtrl s = cl->lower_bound(MusEGlobal::song->cPos().frame());
738
 
    iCtrl s = cl->lower_bound(MusEGlobal::audio->pos().frame());    // p4.0.33
 
645
    iCtrl s = cl->lower_bound(MusEGlobal::audio->pos().frame());    
739
646
    if(s != cl->begin())
740
647
      --s;
741
648
    
742
 
    //MusEGlobal::song->setPos(Song::CPOS, Pos(s->second.frame, false), true, false, true);
743
 
    MusEGlobal::song->setPos(Song::CPOS, Pos(s->second.frame, false), false, true, false);  // p4.0.33
 
649
    MusEGlobal::song->setPos(Song::CPOS, Pos(s->second.frame, false), false, true, false);  
744
650
    return;
745
651
}
746
652
 
758
664
    if(cl->empty())
759
665
      return;
760
666
    
761
 
    //iCtrl s = cl->upper_bound(MusEGlobal::song->cPos().frame());
762
 
    iCtrl s = cl->upper_bound(MusEGlobal::audio->pos().frame());         // p4.0.33
 
667
    iCtrl s = cl->upper_bound(MusEGlobal::audio->pos().frame());         
763
668
    
764
669
    if(s == cl->end())
765
670
    {
766
671
      --s;
767
672
    }
768
673
    
769
 
    //MusEGlobal::song->setPos(Song::CPOS, Pos(s->second.frame, false), true, false, true);
770
 
    MusEGlobal::song->setPos(Song::CPOS, Pos(s->second.frame, false), false, true, false);  // p4.0.33
 
674
    MusEGlobal::song->setPos(Song::CPOS, Pos(s->second.frame, false), false, true, false);  
771
675
    return;  
772
676
}
773
677
 
841
745
  iCtrl ic = cl->find(frame); 
842
746
  if(ic != cl->end())
843
747
    cl->erase(ic);
844
 
  cl->insert(std::pair<const int, CtrlVal> (newframe, CtrlVal(newframe, newval)));      
 
748
  cl->insert(std::pair<const int, CtrlVal> (newframe, CtrlVal(newframe, newval)));
845
749
}
846
750
 
847
751
//---------------------------------------------------------
850
754
 
851
755
double AudioTrack::volume() const
852
756
      {
853
 
      ciCtrlList cl = _controller.find(AC_VOLUME);
854
 
      if (cl == _controller.end())
855
 
            return 0.0;
856
 
      
857
 
      if (MusEGlobal::automation && 
858
 
          automationType() != AUTO_OFF && _volumeEnCtrl && _volumeEn2Ctrl )
859
 
            return cl->second->value(MusEGlobal::song->cPos().frame());
860
 
      else
861
 
            return cl->second->curVal();
 
757
      return _controller.value(AC_VOLUME, MusEGlobal::audio->curFramePos(), 
 
758
                               !MusEGlobal::automation || automationType() == AUTO_OFF || !_volumeEnCtrl || !_volumeEn2Ctrl);
862
759
      }
863
760
 
864
761
//---------------------------------------------------------
882
779
 
883
780
double AudioTrack::pan() const
884
781
      {
885
 
      ciCtrlList cl = _controller.find(AC_PAN);
886
 
      if (cl == _controller.end())
887
 
            return 0.0;
888
 
      
889
 
      if (MusEGlobal::automation && 
890
 
          automationType() != AUTO_OFF && _panEnCtrl && _panEn2Ctrl )
891
 
        return cl->second->value(MusEGlobal::song->cPos().frame());
892
 
      else
893
 
        return cl->second->curVal();
 
782
      return _controller.value(AC_PAN, MusEGlobal::audio->curFramePos(), 
 
783
                               !MusEGlobal::automation || automationType() == AUTO_OFF || !_panEnCtrl || !_panEn2Ctrl);
894
784
      }
895
785
 
896
786
//---------------------------------------------------------
913
803
 
914
804
double AudioTrack::pluginCtrlVal(int ctlID) const
915
805
      {
916
 
      ciCtrlList cl = _controller.find(ctlID);
917
 
      if (cl == _controller.end())
918
 
            return 0.0;
919
 
      
920
 
      if (MusEGlobal::automation && (automationType() != AUTO_OFF))
921
 
        return cl->second->value(MusEGlobal::song->cPos().frame());
 
806
      bool en_1 = true, en_2 = true;
 
807
      if(ctlID < AC_PLUGIN_CTL_BASE)  
 
808
      {
 
809
        if(ctlID == AC_VOLUME)
 
810
        {
 
811
          en_1 = _volumeEnCtrl; 
 
812
          en_2 = _volumeEn2Ctrl;
 
813
        }
 
814
        else
 
815
        if(ctlID == AC_PAN)
 
816
        {
 
817
          en_1 = _panEnCtrl; 
 
818
          en_2 = _panEn2Ctrl;
 
819
        }
 
820
      }
922
821
      else
923
 
        return cl->second->curVal();
 
822
      {
 
823
        if(ctlID < (int)genACnum(MAX_PLUGINS, 0))  // The beginning of the special dssi synth controller block.             
 
824
        {
 
825
          _efxPipe->controllersEnabled(ctlID, &en_1, &en_2); 
 
826
        }
 
827
        else
 
828
        {
 
829
          if(type() == AUDIO_SOFTSYNTH)
 
830
          {
 
831
            const SynthI* synth = static_cast<const SynthI*>(this);
 
832
            if(synth->synth() && synth->synth()->synthType() == Synth::DSSI_SYNTH)
 
833
            {
 
834
              SynthIF* sif = synth->sif();
 
835
              if(sif)
 
836
              {
 
837
                const DssiSynthIF* dssi_sif = static_cast<const DssiSynthIF*>(sif);
 
838
                int in_ctrl_idx = ctlID & AC_PLUGIN_CTL_ID_MASK;
 
839
                en_1 = dssi_sif->controllerEnabled(in_ctrl_idx);
 
840
                en_2 = dssi_sif->controllerEnabled2(in_ctrl_idx);
 
841
              }
 
842
            }
 
843
          }
 
844
        }
 
845
      }  
 
846
            
 
847
      return _controller.value(ctlID, MusEGlobal::audio->curFramePos(), 
 
848
                               !MusEGlobal::automation || automationType() == AUTO_OFF || !en_1 || !en_2);
924
849
      }
925
850
 
926
851
//---------------------------------------------------------
936
861
  cl->second->setCurVal(val);
937
862
}
938
863
      
 
864
//---------------------------------------------------------
 
865
//   addScheduledControlEvent
 
866
//   returns true if event cannot be delivered
 
867
//---------------------------------------------------------
 
868
 
 
869
bool AudioTrack::addScheduledControlEvent(int track_ctrl_id, float val, unsigned frame) 
 
870
{
 
871
  if(track_ctrl_id < AC_PLUGIN_CTL_BASE)  // FIXME: These controllers (three so far - vol, pan, mute) have no vari-run-length support.
 
872
  {
 
873
    iCtrlList icl = _controller.find(track_ctrl_id);
 
874
    if(icl == _controller.end())
 
875
      return true;
 
876
    icl->second->setCurVal(val);
 
877
    return false;
 
878
  }
 
879
  else
 
880
  {
 
881
    if(track_ctrl_id < (int)genACnum(MAX_PLUGINS, 0))  // The beginning of the special dssi synth controller block.             
 
882
      return _efxPipe->addScheduledControlEvent(track_ctrl_id, val, frame);
 
883
    else
 
884
    {
 
885
      if(type() == AUDIO_SOFTSYNTH)
 
886
      {
 
887
        const SynthI* synth = static_cast<const SynthI*>(this);
 
888
        if(synth->synth() && synth->synth()->synthType() == Synth::DSSI_SYNTH)
 
889
        {
 
890
          SynthIF* sif = synth->sif();
 
891
          if(sif)
 
892
          {
 
893
            DssiSynthIF* dssi_sif = static_cast<DssiSynthIF*>(sif);
 
894
            int in_ctrl_idx = track_ctrl_id & AC_PLUGIN_CTL_ID_MASK;
 
895
            return dssi_sif->addScheduledControlEvent(in_ctrl_idx, val, frame);
 
896
          }
 
897
        }
 
898
      }
 
899
    }
 
900
  }  
 
901
  return true;
 
902
}
 
903
 
 
904
//---------------------------------------------------------
 
905
//   enableController
 
906
//   Enable or disable gui controls. 
 
907
//   Used during automation recording to inhibit gui controls 
 
908
//    from playback controller stream
 
909
//---------------------------------------------------------
 
910
 
 
911
void AudioTrack::enableController(int track_ctrl_id, bool en) 
 
912
{
 
913
  if(track_ctrl_id < AC_PLUGIN_CTL_BASE)  
 
914
  {
 
915
    if(track_ctrl_id == AC_VOLUME)
 
916
      enableVolumeController(en);
 
917
    else
 
918
    if(track_ctrl_id == AC_PAN)
 
919
      enablePanController(en);
 
920
  }
 
921
  else
 
922
  {
 
923
    if(track_ctrl_id < (int)genACnum(MAX_PLUGINS, 0))  // The beginning of the special dssi synth controller block.             
 
924
      _efxPipe->enableController(track_ctrl_id, en);
 
925
    else
 
926
    {
 
927
      if(type() == AUDIO_SOFTSYNTH)
 
928
      {
 
929
        SynthI* synth = static_cast<SynthI*>(this);
 
930
        if(synth->synth() && synth->synth()->synthType() == Synth::DSSI_SYNTH)
 
931
        {
 
932
          SynthIF* sif = synth->sif();
 
933
          if(sif)
 
934
          {
 
935
            DssiSynthIF* dssi_sif = static_cast<DssiSynthIF*>(sif);
 
936
            int in_ctrl_idx = track_ctrl_id & AC_PLUGIN_CTL_ID_MASK;
 
937
            dssi_sif->enableController(in_ctrl_idx, en);
 
938
          }
 
939
        }
 
940
      }
 
941
    }
 
942
  }  
 
943
}
 
944
 
 
945
//---------------------------------------------------------
 
946
//   controllersEnabled
 
947
//---------------------------------------------------------
 
948
 
 
949
void AudioTrack::controllersEnabled(int track_ctrl_id, bool* en1, bool* en2) const
 
950
      {
 
951
      bool en_1 = true, en_2 = true;
 
952
      if(track_ctrl_id < AC_PLUGIN_CTL_BASE)  
 
953
      {
 
954
        if(track_ctrl_id == AC_VOLUME)
 
955
        {
 
956
          en_1 = _volumeEnCtrl; 
 
957
          en_2 = _volumeEn2Ctrl;
 
958
        }
 
959
        else
 
960
        if(track_ctrl_id == AC_PAN)
 
961
        {
 
962
          en_1 = _panEnCtrl; 
 
963
          en_2 = _panEn2Ctrl;
 
964
        }
 
965
      }
 
966
      else
 
967
      {
 
968
        if(track_ctrl_id < (int)genACnum(MAX_PLUGINS, 0))  // The beginning of the special dssi synth controller block.             
 
969
        {
 
970
          _efxPipe->controllersEnabled(track_ctrl_id, &en_1, &en_2); 
 
971
        }
 
972
        else
 
973
        {
 
974
          if(type() == AUDIO_SOFTSYNTH)
 
975
          {
 
976
            const SynthI* synth = static_cast<const SynthI*>(this);
 
977
            if(synth->synth() && synth->synth()->synthType() == Synth::DSSI_SYNTH)
 
978
            {
 
979
              SynthIF* sif = synth->sif();
 
980
              if(sif)
 
981
              {
 
982
                const DssiSynthIF* dssi_sif = static_cast<const DssiSynthIF*>(sif);
 
983
                int in_ctrl_idx = track_ctrl_id & AC_PLUGIN_CTL_ID_MASK;
 
984
                en_1 = dssi_sif->controllerEnabled(in_ctrl_idx);
 
985
                en_2 = dssi_sif->controllerEnabled2(in_ctrl_idx);
 
986
              }
 
987
            }
 
988
          }
 
989
        }
 
990
      }  
 
991
        
 
992
      if(en1)
 
993
        *en1 = en_1;
 
994
      if(en2)
 
995
        *en2 = en_2;
 
996
      }
 
997
 
939
998
void AudioTrack::recordAutomation(int n, double v)
940
999
      {
941
1000
        if(!MusEGlobal::automation)
942
1001
          return;
943
1002
        if(MusEGlobal::audio->isPlaying())
944
 
          _recEvents.push_back(CtrlRecVal(MusEGlobal::song->cPos().frame(), n, v));
 
1003
          _recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v));      
945
1004
        else 
946
1005
        {
947
1006
          if(automationType() == AUTO_WRITE)
948
 
            _recEvents.push_back(CtrlRecVal(MusEGlobal::song->cPos().frame(), n, v));
 
1007
            _recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v));    
949
1008
          else 
950
1009
          if(automationType() == AUTO_TOUCH)
951
1010
          // In touch mode and not playing. Send directly to controller list.
954
1013
            if (cl == _controller.end()) 
955
1014
              return;
956
1015
            // Add will replace if found.
957
 
            cl->second->add(MusEGlobal::song->cPos().frame(), v);
 
1016
            cl->second->add(MusEGlobal::audio->curFramePos(), v);   
958
1017
          }  
959
1018
        }
960
1019
      }
966
1025
        if(MusEGlobal::audio->isPlaying())
967
1026
        {
968
1027
          if(automationType() == AUTO_TOUCH)
969
 
              _recEvents.push_back(CtrlRecVal(MusEGlobal::song->cPos().frame(), n, v, ARVT_START));
970
 
          else    
 
1028
              _recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v, ARVT_START));
 
1029
          else
971
1030
          if(automationType() == AUTO_WRITE)
972
 
              _recEvents.push_back(CtrlRecVal(MusEGlobal::song->cPos().frame(), n, v));
 
1031
              _recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v));
973
1032
        } 
974
1033
        else
975
1034
        {
976
1035
          if(automationType() == AUTO_TOUCH)
977
1036
          // In touch mode and not playing. Send directly to controller list.
978
1037
          {
 
1038
            // FIXME: Unsafe? Should sync by sending a message, but that'll really slow it down with large audio bufs.
979
1039
            iCtrlList cl = _controller.find(n);
980
1040
            if (cl == _controller.end()) 
981
1041
              return;
982
1042
            // Add will replace if found.
983
 
            cl->second->add(MusEGlobal::song->cPos().frame(), v);
 
1043
            cl->second->add(MusEGlobal::audio->curFramePos(), v);                 
984
1044
          }    
985
1045
          else    
986
1046
          if(automationType() == AUTO_WRITE)
987
 
            _recEvents.push_back(CtrlRecVal(MusEGlobal::song->cPos().frame(), n, v));
 
1047
            _recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v));    
988
1048
        }   
989
1049
      }
990
1050
 
996
1056
        {
997
1057
          if(automationType() == AUTO_TOUCH)
998
1058
          {
999
 
              MusEGlobal::audio->msgAddACEvent(this, n, MusEGlobal::song->cPos().frame(), v);
1000
 
              _recEvents.push_back(CtrlRecVal(MusEGlobal::song->cPos().frame(), n, v, ARVT_STOP));
 
1059
              MusEGlobal::audio->msgAddACEvent(this, n, MusEGlobal::audio->curFramePos(), v);
 
1060
              _recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v, ARVT_STOP));   
1001
1061
          }   
1002
1062
        } 
1003
1063
      }
1015
1075
      if (hasAuxSend()) {
1016
1076
            int naux = MusEGlobal::song->auxs()->size();
1017
1077
            for (int idx = 0; idx < naux; ++idx) {
1018
 
                  //QString s("<auxSend idx=%1>%2</auxSend>\n");
1019
1078
                  QString s("<auxSend idx=\"%1\">%2</auxSend>\n");  // Aux fix from Remon, thanks.
1020
1079
                  xml.nput(level, s.arg(idx).arg(_auxSend[idx]).toAscii().constData());
1021
1080
                  }
1024
1083
            if (*ip)
1025
1084
                  (*ip)->writeConfiguration(level, xml);
1026
1085
            }
1027
 
      for (ciCtrlList icl = _controller.begin(); icl != _controller.end(); ++icl) {
1028
 
            const CtrlList* cl = icl->second;
1029
 
 
1030
 
            QString s= QString("controller id=\"%1\" cur=\"%2\"").arg(cl->id()).arg(cl->curVal()).toAscii().constData();
1031
 
            s += QString(" color=\"%1\" visible=\"%2\"").arg(cl->color().name()).arg(cl->isVisible());
1032
 
            xml.tag(level++, s.toAscii().constData());
1033
 
            int i = 0;
1034
 
            for (ciCtrl ic = cl->begin(); ic != cl->end(); ++ic) {
1035
 
                  QString s("%1 %2, ");
1036
 
                  xml.nput(level, s.arg(ic->second.frame).arg(ic->second.val).toAscii().constData());
1037
 
                  ++i;
1038
 
                  if (i >= 4) {
1039
 
                        xml.put(level, "");
1040
 
                        i = 0;
1041
 
                        }
1042
 
                  }
1043
 
            if (i)
1044
 
                  xml.put(level, "");
1045
 
            xml.etag(level--, "controller");
1046
 
            }
 
1086
      _controller.write(level, xml);            
1047
1087
      }
1048
1088
 
1049
1089
//---------------------------------------------------------
1117
1157
            _sendMetronome = xml.parseInt();
1118
1158
      else if (tag == "automation")
1119
1159
            setAutomationType(AutomationType(xml.parseInt()));
1120
 
      // Removed by T356
1121
 
      // "recfile" tag not saved anymore
1122
 
      //else if (tag == "recfile")
1123
 
      //      readRecfile(xml);
1124
1160
      else if (tag == "controller") {
1125
1161
            CtrlList* l = new CtrlList();
1126
1162
            l->read(xml);
1132
1168
            //  controls would all be set to zero.
1133
1169
            // But we will allow for the (unintended, useless) possibility of a controller 
1134
1170
            //  with no matching plugin control.
1135
 
            //PluginI* p = 0;
1136
1171
            PluginIBase* p = 0;     
1137
1172
            bool ctlfound = false;
1138
1173
            unsigned m = l->id() & AC_PLUGIN_CTL_ID_MASK;       
1143
1178
              if(p && m < p->parameters())
1144
1179
                  ctlfound = true;
1145
1180
            }
1146
 
            // Support a special block for dssi synth ladspa controllers. p4.0.20
 
1181
            // Support a special block for dssi synth ladspa controllers. 
1147
1182
            else if(n == MAX_PLUGINS && type() == AUDIO_SOFTSYNTH)    
1148
1183
            {
1149
1184
              SynthI* synti = dynamic_cast < SynthI* > (this);
1152
1187
                SynthIF* sif = synti->sif();
1153
1188
                if(sif)
1154
1189
                {
 
1190
#ifdef DSSI_SUPPORT
1155
1191
                  DssiSynthIF* dsif = dynamic_cast < DssiSynthIF* > (sif);
1156
1192
                  if(dsif)
1157
1193
                  {
1159
1195
                    if(p && m < p->parameters())
1160
1196
                        ctlfound = true;
1161
1197
                  }
 
1198
#endif
1162
1199
                }
1163
1200
              }
1164
1201
            }
1187
1224
                  l->setMode(p->ctrlMode(m));  
1188
1225
                } 
1189
1226
            }
 
1227
      else if (tag == "midiMapper") 
 
1228
            _controller.midiControls()->read(xml);
1190
1229
      else
1191
1230
            return Track::readProperties(xml, tag);
1192
1231
      return false;
1285
1324
      l->setValueType(p->ctrlValueType(i));
1286
1325
      l->setMode(p->ctrlMode(i));  
1287
1326
      l->setCurVal(p->param(i));
1288
 
      //l->setDefault(p->defaultValue(i));
1289
1327
    }  
1290
1328
  }
1291
1329
  
1301
1339
      // Ignore volume, pan, mute etc.
1302
1340
      if(id < AC_PLUGIN_CTL_BASE)
1303
1341
        continue;
 
1342
        
1304
1343
      unsigned param = id & AC_PLUGIN_CTL_ID_MASK;    
1305
1344
      int idx = (id >> AC_PLUGIN_CTL_BASE_POW) - 1;
1306
 
      //PluginI* p = (*_efxPipe)[idx];
1307
1345
      
1308
 
      // p4.0.20
1309
 
      PluginIBase* p = 0;
 
1346
      const PluginIBase* p = 0;
1310
1347
      if(idx >= 0 && idx < PipelineDepth)
1311
1348
        p = (*_efxPipe)[idx];
1312
1349
      // Support a special block for dssi synth ladspa controllers. 
1313
1350
      else if(idx == MAX_PLUGINS && type() == AUDIO_SOFTSYNTH)    
1314
1351
      {
1315
 
        SynthI* synti = dynamic_cast < SynthI* > (this);
 
1352
        const SynthI* synti = dynamic_cast < const SynthI* > (this);
1316
1353
        if(synti)
1317
1354
        {
1318
1355
          SynthIF* sif = synti->sif();
1319
1356
          if(sif)
1320
1357
          {
1321
 
            DssiSynthIF* dsif = dynamic_cast < DssiSynthIF* > (sif);
 
1358
#ifdef DSSI_SUPPORT
 
1359
            const DssiSynthIF* dsif = dynamic_cast < const DssiSynthIF* > (sif);
1322
1360
            if(dsif)
1323
1361
              p = dsif;
 
1362
#endif
1324
1363
          }
1325
1364
        }
1326
1365
      }
1341
1380
  while (loop);
1342
1381
    
1343
1382
    
 
1383
    // DELETETHIS 40 i DO trust the below. some container's erase functions
 
1384
    // return an iterator to the next, so sometimes you need it=erase(it)
 
1385
    // instead of erase(it++).
 
1386
    // i'm happy with both AS LONG the above does not slow down things.
 
1387
    // when in doubt, i'd prefer the below however.
 
1388
    // so either remove the below completely (if the above works fast),
 
1389
    // or remove the above and use the below.
 
1390
    // CAUTION: the below isn't quite up-to-date! first recheck.
 
1391
    // this "not-being-up-to-date" is another reason for NOT keeping such
 
1392
    // comments!
 
1393
    
1344
1394
    // FIXME: Although this tested OK, and is the 'official' way to erase while iterating,
1345
1395
    //  I don't trust it. I'm weary of this method. The technique didn't work 
1346
1396
    //  in Audio::msgRemoveTracks(), see comments there.
1357
1407
        ++icl;
1358
1408
        continue;
1359
1409
      }  
 
1410
      
1360
1411
      int param = id & AC_PLUGIN_CTL_ID_MASK;
1361
1412
      int idx = (id >> AC_PLUGIN_CTL_BASE_POW) - 1;
1362
1413
      PluginI* p = (*_efxPipe)[idx];
1372
1423
    */
1373
1424
}
1374
1425
 
1375
 
/*
1376
 
//---------------------------------------------------------
1377
 
//   writeRouting
1378
 
//---------------------------------------------------------
1379
 
 
1380
 
void AudioTrack::writeRouting(int level, Xml& xml) const
1381
 
{
1382
 
      QString n;
1383
 
      if (type() == Track::AUDIO_INPUT) {
1384
 
                ciJackRouteNameCache circ = jackRouteNameCache.find(this);
1385
 
                if(circ != jackRouteNameCache.end())
1386
 
                {
1387
 
                  jackRouteNameMap rm = circ->second;
1388
 
                  for(ciJackRouteNameMap cirm = rm.begin(); cirm != rm.end(); ++cirm)
1389
 
                  {
1390
 
                    n = cirm->second;
1391
 
                    if(!n.isEmpty())
1392
 
                    {
1393
 
                      Route dst(name(), true, cirm->first);
1394
 
                      xml.tag(level++, "Route");
1395
 
                      xml.strTag(level, "srcNode", n);
1396
 
                      xml.strTag(level, "dstNode", dst.name());
1397
 
                      xml.etag(level--, "Route");
1398
 
                    }  
1399
 
                  }  
1400
 
                }
1401
 
            }
1402
 
      if(type() == Track::AUDIO_OUTPUT) 
1403
 
      {
1404
 
        ciJackRouteNameCache circ = jackRouteNameCache.find(this);
1405
 
        if(circ != jackRouteNameCache.end())
1406
 
        {
1407
 
          jackRouteNameMap rm = circ->second;
1408
 
          for(ciJackRouteNameMap cirm = rm.begin(); cirm != rm.end(); ++cirm)
1409
 
          {
1410
 
            n = cirm->second;
1411
 
            if(!n.isEmpty())
1412
 
            {
1413
 
              Route src(name(), false, cirm->first);
1414
 
              xml.tag(level++, "Route");
1415
 
              xml.strTag(level, "srcNode", src.name());
1416
 
              xml.strTag(level, "dstNode", n);
1417
 
              xml.etag(level--, "Route");
1418
 
            }  
1419
 
          }  
1420
 
        }
1421
 
      }
1422
 
      else
1423
 
      {
1424
 
        const RouteList* rl = &_outRoutes;
1425
 
        for (ciRoute r = rl->begin(); r != rl->end(); ++r) {
1426
 
            if(!r->name().isEmpty())
1427
 
            {
1428
 
              xml.tag(level++, "Route");
1429
 
              xml.strTag(level, "srcNode", name());
1430
 
              xml.strTag(level, "dstNode", r->name());
1431
 
              xml.etag(level--, "Route");
1432
 
            }
1433
 
        }  
1434
 
      }  
1435
 
}
1436
 
*/       
1437
 
       
1438
1426
//---------------------------------------------------------
1439
1427
//   AudioInput
1440
1428
//---------------------------------------------------------
1444
1432
      {
1445
1433
      // set Default for Input Ports:
1446
1434
      _mute = true;
1447
 
      //setVolume(1.0);
1448
1435
      for (int i = 0; i < MAX_CHANNELS; ++i)
1449
1436
            jackPorts[i] = 0;
1450
 
      //_channels = 0;
1451
 
      //setChannels(2);
1452
1437
      }
1453
1438
 
1454
1439
AudioInput::AudioInput(const AudioInput& t, int flags)
1455
1440
  : AudioTrack(t, flags)
1456
1441
{
1457
1442
  for (int i = 0; i < MAX_CHANNELS; ++i)
1458
 
        //jackPorts[i] = t.jackPorts[i];
1459
1443
        jackPorts[i] = 0;
1460
1444
 
1461
1445
  // Register ports.
1491
1475
      // Defer all Jack routes to these copy constructors or assign !
1492
1476
      if(ir->type != Route::JACK_ROUTE)
1493
1477
        continue;
1494
 
      MusEGlobal::audio->msgAddRoute(*ir, Route(this, ir->channel, ir->channels));
 
1478
      // FIXME Must use msgAddRoute instead of _inRoutes.push_back, because it connects to Jack. 
 
1479
      // The track is still fresh has not been added to track lists yet. Will cause audio processing problems ?
 
1480
      MusEGlobal::audio->msgAddRoute(*ir, Route(this, ir->channel, ir->channels));  
1495
1481
    }
1496
1482
  } 
1497
1483
}
1559
1545
      {
1560
1546
      for (int i = 0; i < MAX_CHANNELS; ++i)
1561
1547
            jackPorts[i] = 0;
1562
 
      //_channels = 0;
1563
 
      //setChannels(2);
1564
1548
      }
1565
1549
 
1566
1550
AudioOutput::AudioOutput(const AudioOutput& t, int flags)
1567
1551
  : AudioTrack(t, flags)
1568
1552
{
1569
1553
  for (int i = 0; i < MAX_CHANNELS; ++i)
1570
 
        //jackPorts[i] = t.jackPorts[i];
1571
1554
        jackPorts[i] = 0;
1572
 
  //_nframes = t._nframes;
1573
1555
  _nframes = 0;
1574
1556
  
1575
1557
  // Register ports. 
1605
1587
      // Defer all Jack routes to these copy constructors or assign !
1606
1588
      if(ir->type != Route::JACK_ROUTE)
1607
1589
        continue;
1608
 
      MusEGlobal::audio->msgAddRoute(Route(this, ir->channel, ir->channels), *ir);
 
1590
      // FIXME Must use msgAddRoute instead of _outRoutes.push_back, because it connects to Jack. 
 
1591
      // The track is still fresh has not been added to track lists yet. Will cause audio processing problems ?
 
1592
      MusEGlobal::audio->msgAddRoute(Route(this, ir->channel, ir->channels), *ir); 
1609
1593
    }
1610
1594
  } 
1611
1595
}
1724
1708
AudioAux::AudioAux()
1725
1709
   : AudioTrack(AUDIO_AUX)
1726
1710
{
1727
 
      //_channels = 0;
1728
 
      //setChannels(2);
1729
 
      //for (int i = 0; i < MAX_CHANNELS; ++i)
1730
 
      //      buffer[i] = (i < channels()) ? new float[MusEGlobal::segmentSize] : 0;
1731
1711
      for(int i = 0; i < MAX_CHANNELS; ++i)
1732
1712
      {
1733
1713
        if(i < channels())
1740
1720
AudioAux::AudioAux(const AudioAux& t, int flags)
1741
1721
   : AudioTrack(t, flags)
1742
1722
{
1743
 
      //_channels = 0;
1744
 
      //setChannels(2);
1745
 
      //for (int i = 0; i < MAX_CHANNELS; ++i)
1746
 
      //      buffer[i] = (i < channels()) ? new float[MusEGlobal::segmentSize] : 0;
1747
1723
      for(int i = 0; i < MAX_CHANNELS; ++i)
1748
1724
      {
1749
1725
        if(i < channels())
1757
1733
//---------------------------------------------------------
1758
1734
 
1759
1735
AudioAux::~AudioAux()
1760
 
      {
1761
 
      //for (int i = 0; i < channels(); ++i)
1762
 
      //      delete[] buffer[i];
 
1736
{
1763
1737
      for (int i = 0; i < MAX_CHANNELS; ++i) {
1764
1738
            if (buffer[i])
1765
1739
                free(buffer[i]);
1766
 
            }
1767
1740
      }
 
1741
}
1768
1742
 
1769
1743
//---------------------------------------------------------
1770
1744
//   read
1803
1777
 
1804
1778
bool AudioAux::getData(unsigned pos, int ch, unsigned samples, float** data)
1805
1779
      {
1806
 
      // Make sure all the aux-supporting tracks are processed first so aux data is gathered.    p4.0.37
 
1780
      // Make sure all the aux-supporting tracks are processed first so aux data is gathered.    
1807
1781
      TrackList* tl = MusEGlobal::song->tracks();
1808
1782
      AudioTrack* track;
1809
1783
      for(ciTrack it = tl->begin(); it != tl->end(); ++it) 
1821
1795
          for (int i = 0; i < chans; ++i)
1822
1796
                buff[i] = buff_data + i * samples;
1823
1797
          
1824
 
          //printf("AudioAux::getData name:%s\n    calling copyData on:%s auxRefCount:%d\n", 
1825
 
          //       name().toLatin1().constData(), track->name().toLatin1().constData(), track->auxRefCount()); 
1826
 
          
1827
1798
          track->copyData(pos, chans, -1, -1, samples, buff);
1828
 
          
1829
 
          /* float* buff[ch];
1830
 
          float buff_data[samples * ch];
1831
 
          for (int i = 0; i < ch; ++i)
1832
 
                buff[i] = buff_data + i * samples;
1833
 
          //printf("Audio::process1 calling track->copyData for track:%s\n", track->name().toLatin1());
1834
 
          track->copyData(pos, ch, -1, -1, samples, buff);  */
1835
1799
        }
1836
1800
      }      
1837
1801
  
1848
1812
{
1849
1813
  if(n > channels()) 
1850
1814
  {
1851
 
    //for (int i = channels(); i < n; ++i)
1852
 
    //      buffer[i] = new float[MusEGlobal::segmentSize];
1853
1815
    for(int i = channels(); i < n; ++i)
1854
1816
      posix_memalign((void**)(buffer + i), 16, sizeof(float) * MusEGlobal::segmentSize);
1855
1817
  }
1856
1818
  else if(n < channels()) 
1857
1819
  {
1858
 
    //for (int i = n; i < channels(); ++i)
1859
 
    //      delete[] buffer[i];
1860
1820
    for(int i = n; i < channels(); ++i) 
1861
1821
    {
1862
1822
      if(buffer[i])
1876
1836
      if (f == _recordFlag)
1877
1837
            return true;
1878
1838
      if (f) {
1879
 
        // do nothing
1880
 
        if (_recFile == 0 && MusEGlobal::song->record()) {
 
1839
        if (_recFile.isNull() && MusEGlobal::song->record()) {
1881
1840
          // this rec-enables a track if the global arm already was done
1882
1841
          // the standard case would be that rec-enable be done there
1883
1842
          prepareRecording();
1893
1852
              //  recording, the _recFile pointer is made into an event, 
1894
1853
              //  then _recFile is made zero before this function is called.
1895
1854
              QString s = _recFile->path();
1896
 
              delete _recFile;
1897
 
              setRecFile(0);
 
1855
              setRecFile(NULL);
1898
1856
              
1899
1857
              remove(s.toLatin1().constData());
1900
1858
              if(MusEGlobal::debugMsg)
1901
1859
                printf("AudioNode::setRecordFlag1: remove file %s if it exists\n", s.toLatin1().constData());
1902
 
              //_recFile = 0;
1903
1860
            }
1904
1861
          }
1905
1862
      return true;
1918
1875
      if(MusEGlobal::debugMsg)
1919
1876
        printf("prepareRecording for track %s\n", _name.toLatin1().constData());
1920
1877
 
1921
 
      if (_recFile == 0) {
 
1878
      if (_recFile.isNull()) {
1922
1879
            //
1923
1880
            // create soundfile for recording
1924
1881
            //