1 //=========================================================
2 //  MusE
3 //  Linux Music Editor
4 //  $Id: audiotrack.cpp,v 1.14.2.21 2009/12/20 05:00:35 terminator356 Exp $
5 //
6 //  (C) Copyright 2004 Werner Schweer (ws@seh.de)
7 //  (C) Copyright 2013 Tim E. Real (terminator356 on users dot sourceforge dot net)
8 //
9 //  This program is free software; you can redistribute it and/or
10 //  modify it under the terms of the GNU General Public License
11 //  as published by the Free Software Foundation; version 2 of
12 //  the License, or (at your option) any later version.
13 //
14 //  This program is distributed in the hope that it will be useful,
15 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 //  GNU General Public License for more details.
18 //
19 //  You should have received a copy of the GNU General Public License
20 //  along with this program; if not, write to the Free Software
21 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
22 //
23 //=========================================================
24 
25 #include <limits.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <map>
29 
30 #include <QMessageBox>
31 
32 #include "globals.h"
33 #include "globaldefs.h"
34 #include "track.h"
35 #include "event.h"
36 #include "song.h"
37 #include "audio.h"
38 #include "wave.h"
39 #include "xml.h"
40 #include "undo.h"
41 #include "plugin.h"
42 #include "audiodev.h"
43 #include "synth.h"
44 #include "dssihost.h"
45 #include "vst_native.h"
46 #include "app.h"
47 #include "controlfifo.h"
48 #include "fastlog.h"
49 #include "gconfig.h"
50 #include "latency_compensator.h"
51 #include "ticksynth.h"
52 
53 namespace MusECore {
54 
55 bool AudioAux::_isVisible=true;
56 bool AudioInput::_isVisible=true;
57 bool AudioOutput::_isVisible=true;
58 bool AudioGroup::_isVisible =true;
59 bool WaveTrack::_isVisible=true;
60 
61 // DELETETHIS 40. this caching stuff seems to be not used any more
62 // By T356. For caching jack in/out routing names BEFORE file save.
63 // Jack often shuts down during file save, causing the routes to be lost in the file.
64 // cacheJackRouteNames() is ONLY called from MusE::save() in app.cpp
65 // Update: Not required any more because the real problem was Jack RT priority, which has been fixed.
66 // Keep this around for now. It may come in handy if we want to preserve route names with dummy audio driver!
67 /*
68 typedef std::multimap <const int, QString> jackRouteNameMap;
69 std::map <const AudioTrack*, jackRouteNameMap > jackRouteNameCache;
70 typedef std::multimap <const int, QString>::const_iterator ciJackRouteNameMap;
71 typedef std::map <const AudioTrack*, jackRouteNameMap>::const_iterator ciJackRouteNameCache;
72 void cacheJackRouteNames()
73 {
74     jackRouteNameCache.clear();
75     const InputList* il = MusEGlobal::song->inputs();
76     for(ciAudioInput iai = il->begin(); iai != il->end(); ++iai)
77     {
78       const RouteList* rl = (*iai)->inRoutes();
79       if(!rl->empty())
80       {
81         jackRouteNameMap rm = jackRouteNameMap();
82         for(ciRoute r = rl->begin(); r != rl->end(); ++r)
83           rm.insert(std::pair<const int, QString>(r->channel, r->name()));
84         jackRouteNameCache.insert(std::pair<const AudioTrack*, jackRouteNameMap>(*iai, rm));
85       }
86     }
87     const OutputList* ol = MusEGlobal::song->outputs();
88     for(ciAudioOutput iao = ol->begin(); iao != ol->end(); ++iao)
89     {
90       const RouteList* rl = (*iao)->outRoutes();
91       if(!rl->empty())
92       {
93         jackRouteNameMap rm = jackRouteNameMap();
94         for(ciRoute r = rl->begin(); r != rl->end(); ++r)
95           rm.insert(std::pair<const int, QString>(r->channel, r->name()));
96         jackRouteNameCache.insert(std::pair<const AudioTrack*, jackRouteNameMap>(*iao, rm));
97       }
98     }
99 }
100 */
101 
102 //---------------------------------------------------------
103 //   init_buffers
104 //---------------------------------------------------------
105 
initBuffers()106 void AudioTrack::initBuffers()
107 {
108   int chans = _totalOutChannels;
109   // Number of allocated buffers is always MAX_CHANNELS or more, even if _totalOutChannels is less.
110   if(chans < MusECore::MAX_CHANNELS)
111     chans = MusECore::MAX_CHANNELS;
112   if(!outBuffers)
113   {
114     outBuffers = new float*[chans];
115     for(int i = 0; i < chans; ++i)
116     {
117 #ifdef _WIN32
118       outBuffers[i] = (float *) _aligned_malloc(16, sizeof(float) * MusEGlobal::segmentSize);
119       if(outBuffers[i] == NULL)
120       {
121           fprintf(stderr, "ERROR: AudioTrack::init_buffers: _aligned_malloc returned error: NULL. Aborting!\n");
122           abort();
123       }
124 #else
125       int rv = posix_memalign((void**)&outBuffers[i], 16, sizeof(float) * MusEGlobal::segmentSize);
126       if(rv != 0)
127       {
128         fprintf(stderr, "ERROR: AudioTrack::init_buffers: posix_memalign returned error:%d. Aborting!\n", rv);
129         abort();
130       }
131 #endif
132     }
133   }
134   for(int i = 0; i < chans; ++i)
135   {
136     if(MusEGlobal::config.useDenormalBias)
137     {
138       for(unsigned q = 0; q < MusEGlobal::segmentSize; ++q)
139         outBuffers[i][q] = MusEGlobal::denormalBias;
140     }
141     else
142       memset(outBuffers[i], 0, sizeof(float) * MusEGlobal::segmentSize);
143   }
144 
145   if(!outBuffersExtraMix)
146   {
147     outBuffersExtraMix = new float*[MusECore::MAX_CHANNELS];
148     for(int i = 0; i < MusECore::MAX_CHANNELS; ++i)
149     {
150 #ifdef _WIN32
151       outBuffersExtraMix[i] = (float *) _aligned_malloc(16, sizeof(float) * MusEGlobal::segmentSize);
152       if(outBuffersExtraMix[i] == NULL)
153       {
154           fprintf(stderr, "ERROR: AudioTrack::init_buffers: _aligned_malloc outBuffersMonoMix returned error: NULL. Aborting!\n");
155           abort();
156       }
157 #else
158       int rv = posix_memalign((void**)&outBuffersExtraMix[i], 16, sizeof(float) * MusEGlobal::segmentSize);
159       if(rv != 0)
160       {
161         fprintf(stderr, "ERROR: AudioTrack::init_buffers: posix_memalign outBuffersMonoMix returned error:%d. Aborting!\n", rv);
162         abort();
163       }
164 #endif
165     }
166   }
167   for(int i = 0; i < MusECore::MAX_CHANNELS; ++i)
168   {
169     if(MusEGlobal::config.useDenormalBias)
170     {
171       for(unsigned q = 0; q < MusEGlobal::segmentSize; ++q)
172         outBuffersExtraMix[i][q] = MusEGlobal::denormalBias;
173     }
174     else
175       memset(outBuffersExtraMix[i], 0, sizeof(float) * MusEGlobal::segmentSize);
176   }
177 
178   if(!_dataBuffers)
179   {
180     _dataBuffers = new float*[_totalOutChannels];
181     for(int i = 0; i < _totalOutChannels; ++i)
182     {
183 #ifdef _WIN32
184       _dataBuffers[i] = (float *) _aligned_malloc(16, sizeof(float) * MusEGlobal::segmentSize);
185       if(_dataBuffers[i] == NULL)
186       {
187           fprintf(stderr, "ERROR: AudioTrack::init_buffers: _aligned_malloc _dataBuffers returned error: NULL. Aborting!\n");
188           abort();
189       }
190 #else
191       int rv = posix_memalign((void**)&_dataBuffers[i], 16, sizeof(float) * MusEGlobal::segmentSize);
192       if(rv != 0)
193       {
194         fprintf(stderr, "ERROR: AudioTrack::init_buffers: posix_memalign _dataBuffers returned error:%d. Aborting!\n", rv);
195         abort();
196       }
197 #endif
198     }
199   }
200   for(int i = 0; i < _totalOutChannels; ++i)
201   {
202     if(MusEGlobal::config.useDenormalBias)
203     {
204       for(unsigned q = 0; q < MusEGlobal::segmentSize; ++q)
205         _dataBuffers[i][q] = MusEGlobal::denormalBias;
206     }
207     else
208       memset(_dataBuffers[i], 0, sizeof(float) * MusEGlobal::segmentSize);
209   }
210 
211   if(!audioInSilenceBuf)
212   {
213 #ifdef _WIN32
214     audioInSilenceBuf = (float *) _aligned_malloc(16, sizeof(float) * MusEGlobal::segmentSize);
215     if(audioInSilenceBuf == NULL)
216     {
217       fprintf(stderr, "ERROR: AudioTrack::init_buffers: _aligned_malloc returned error: NULL. Aborting!\n");
218       abort();
219     }
220 #else
221     int rv = posix_memalign((void**)&audioInSilenceBuf, 16, sizeof(float) * MusEGlobal::segmentSize);
222     if(rv != 0)
223     {
224       fprintf(stderr, "ERROR: AudioTrack::init_buffers: posix_memalign returned error:%d. Aborting!\n", rv);
225       abort();
226     }
227 #endif
228     if(MusEGlobal::config.useDenormalBias)
229     {
230       for(unsigned q = 0; q < MusEGlobal::segmentSize; ++q)
231         audioInSilenceBuf[q] = MusEGlobal::denormalBias;
232     }
233     else
234       memset(audioInSilenceBuf, 0, sizeof(float) * MusEGlobal::segmentSize);
235   }
236 
237   if(!audioOutDummyBuf)
238   {
239 #ifdef _WIN32
240     audioOutDummyBuf = (float *) _aligned_malloc(16, sizeof(float) * MusEGlobal::segmentSize);
241     if(audioOutDummyBuf == NULL)
242     {
243       fprintf(stderr, "ERROR: AudioTrack::init_buffers: _aligned_malloc returned error: NULL. Aborting!\n");
244       abort();
245     }
246 #else
247     int rv = posix_memalign((void**)&audioOutDummyBuf, 16, sizeof(float) * MusEGlobal::segmentSize);
248     if(rv != 0)
249     {
250       fprintf(stderr, "ERROR: AudioTrack::init_buffers: posix_memalign returned error:%d. Aborting!\n", rv);
251       abort();
252     }
253 #endif
254     if(MusEGlobal::config.useDenormalBias)
255     {
256       for(unsigned q = 0; q < MusEGlobal::segmentSize; ++q)
257         audioOutDummyBuf[q] = MusEGlobal::denormalBias;
258     }
259     else
260       memset(audioOutDummyBuf, 0, sizeof(float) * MusEGlobal::segmentSize);
261   }
262 
263   if(!_controls && _controlPorts != 0)
264   {
265     _controls = new Port[_controlPorts];
266     ciCtrlList icl = _controller.begin();
267     for(unsigned long k = 0; k < _controlPorts; ++k)
268     {
269       double val = 0.0;
270       if(icl != _controller.end())
271       {
272         // Since the list is sorted by id, if no match is found just let k catch up to the id.
273         if((unsigned long)icl->second->id() == k)
274         {
275           val = icl->second->getDefault();
276           ++icl;
277         }
278       }
279       _controls[k].idx    = k;
280       _controls[k].dval    = val;
281       _controls[k].enCtrl = true;
282     }
283   }
284 }
285 
286 //---------------------------------------------------------
287 //   AudioTrack
288 //---------------------------------------------------------
289 
AudioTrack(TrackType t,int channels)290 AudioTrack::AudioTrack(TrackType t, int channels)
291    : Track(t)
292       {
293       _totalOutChannels = MAX_CHANNELS;
294       _latencyComp = new LatencyCompensator();
295       _recFilePos = 0;
296       _previousLatency = 0.0f;
297 
298       _processed = false;
299       _haveData = false;
300       _sendMetronome = false;
301       _prefader = false;
302       _efxPipe  = new Pipeline();
303       recFileNumber = 1;
304       _channels = 0;
305       _automationType = AUTO_OFF;
306       setChannels(channels);
307 
308       addController(new CtrlList(AC_VOLUME,"Volume",0.001,3.163 /* roughly 10 db */, VAL_LOG));
309       addController(new CtrlList(AC_PAN, "Pan", -1.0, 1.0, VAL_LINEAR));
310       addController(new CtrlList(AC_MUTE,"Mute",0.0,1.0, VAL_LINEAR, true /*don't show in arranger */));
311       _controlPorts = 3;
312 
313       _curVolume = 0.0;
314       _curVol1 = 0.0;
315       _curVol2 = 0.0;
316 
317       _controls = 0;
318       outBuffers = 0;
319       outBuffersExtraMix = 0;
320       audioInSilenceBuf = 0;
321       audioOutDummyBuf = 0;
322       _dataBuffers = 0;
323 
324       // This is only set by multi-channel syntis...
325       _totalInChannels = 0;
326 
327       initBuffers();
328 
329       setVolume(1.0);
330       _gain = 1.0;
331       }
332 
AudioTrack(const AudioTrack & t,int flags)333 AudioTrack::AudioTrack(const AudioTrack& t, int flags)
334   :  Track(t, flags)
335       {
336       _latencyComp = new LatencyCompensator();
337       _recFilePos = 0;
338       _previousLatency = 0.0f;
339 
340       _processed      = false;
341       _haveData       = false;
342       _efxPipe        = new Pipeline();                 // Start off with a new pipeline.
343       recFileNumber = 1;
344 
345       addController(new CtrlList(AC_VOLUME,"Volume",0.001,3.163 /* roughly 10 db */, VAL_LOG));
346       addController(new CtrlList(AC_PAN, "Pan", -1.0, 1.0, VAL_LINEAR));
347       addController(new CtrlList(AC_MUTE,"Mute",0.0,1.0, VAL_LINEAR, true /*don't show in arranger */));
348       _controlPorts = 3;
349 
350       _curVolume = 0.0;
351       _curVol1 = 0.0;
352       _curVol2 = 0.0;
353 
354       // Don't allocate outBuffers here. Let internal_assign() call setTotalOutChannels to set them up.
355       _controls = 0;
356       outBuffers = 0;
357       outBuffersExtraMix = 0;
358       audioInSilenceBuf = 0;
359       audioOutDummyBuf = 0;
360       _dataBuffers = 0;
361 
362       _totalOutChannels = 0;
363 
364       // This is only set by multi-channel syntis...
365       _totalInChannels = 0;
366 
367       _recFile = NULL;
368 
369       internal_assign(t, flags | ASSIGN_PROPERTIES);
370       }
371 
internal_assign(const Track & t,int flags)372 void AudioTrack::internal_assign(const Track& t, int flags)
373 {
374       if(t.isMidiTrack())
375         return;
376 
377       const AudioTrack& at = (const AudioTrack&)t;
378 
379       if(flags & ASSIGN_PROPERTIES)
380       {
381         _sendMetronome  = at._sendMetronome;
382         _prefader       = at._prefader;
383         _auxSend        = at._auxSend;
384         _automationType = at._automationType;
385         _gain           = at._gain;
386 
387         if(!(flags & ASSIGN_STD_CTRLS))
388         {
389           // Copy the standard controller block...
390           ciCtrlList icl          = at._controller.begin();
391           ciCtrlList icl_this     = _controller.begin();
392           ciCtrlList icl_end      = at._controller.lower_bound(AC_PLUGIN_CTL_BASE);
393           ciCtrlList icl_this_end = _controller.lower_bound(AC_PLUGIN_CTL_BASE);
394           int id, id_this;
395           CtrlList* cl, *cl_this;
396           while(icl != icl_end && icl_this != icl_this_end)
397           {
398             cl      = icl->second;
399             cl_this = icl_this->second;
400             id      = cl->id();
401             id_this = cl_this->id();
402             if(id < id_this)
403               ++icl;      // Let id catch up to this id.
404             else if(id > id_this)
405               ++icl_this; // Let this id catch up to id.
406             else
407             {
408               // Match found. Copy properties but not values.
409               cl_this->assign(*cl, CtrlList::ASSIGN_PROPERTIES);
410               ++icl;
411               ++icl_this;
412             }
413           }
414 
415           // Copy the special synth controller block...
416           const int synth_id = (int)genACnum(MusECore::MAX_PLUGINS, 0);     // The beginning of the special synth controller block.
417           const int synth_id_end = synth_id + AC_PLUGIN_CTL_BASE; // The end of the special block.
418           icl           = at._controller.lower_bound(synth_id);
419           icl_this      = _controller.lower_bound(synth_id);
420           icl_end       = at._controller.lower_bound(synth_id_end);
421           icl_this_end  = _controller.lower_bound(synth_id_end);
422           while(icl != icl_end && icl_this != icl_this_end)
423           {
424             cl      = icl->second;
425             cl_this = icl_this->second;
426             id      = cl->id();
427             id_this = cl_this->id();
428             if(id < id_this)
429               ++icl;      // Let id catch up to this id.
430             else if(id > id_this)
431               ++icl_this; // Let this id catch up to id.
432             else
433             {
434               // Match found. Copy properties but not values.
435               cl_this->assign(*cl, CtrlList::ASSIGN_PROPERTIES);
436               ++icl;
437               ++icl_this;
438             }
439           }
440         }
441 
442         // This will set up or reallocate the outBuffers. _controlPorts must be valid by now.
443         setTotalOutChannels(at._totalOutChannels);
444 
445         // This is only set by multi-channel syntis...
446         setTotalInChannels(at._totalInChannels);
447 
448         // FIXME: setChannels also called in setTotalOutChannels above, causing redundant efxpipe setChannels.
449         setChannels(at.channels()); // Set track channels (max 2).
450 
451         unsigned long cp = _controlPorts;
452         if(at._controlPorts < cp)
453           cp = at._controlPorts;
454         for(unsigned long k = 0; k < cp; ++k)
455           _controls[k] = at._controls[k];  // Assign the structures.
456       }
457 
458       if(flags & ASSIGN_PLUGINS)
459       {
460         delete _efxPipe;
461         _efxPipe = new Pipeline(*(at._efxPipe), this);  // Make copies of the plugins.
462       }
463 
464       if(flags & (ASSIGN_STD_CTRLS | ASSIGN_PLUGIN_CTRLS))
465       {
466         const int synth_id = (int)genACnum(MusECore::MAX_PLUGINS, 0);     // The beginning of the special synth controller block.
467         const int synth_id_end = synth_id + AC_PLUGIN_CTL_BASE; // The end of the special block.
468         ciCtrlList icl, icl_end, icl_this, icl_this_end;
469         int id, id_this;
470         CtrlList* cl, *cl_this;
471 
472         if(flags & ASSIGN_STD_CTRLS)
473         {
474           // Copy the standard controller block...
475           icl          = at._controller.begin();
476           icl_this     = _controller.begin();
477           icl_end      = at._controller.lower_bound(AC_PLUGIN_CTL_BASE);
478           icl_this_end = _controller.lower_bound(AC_PLUGIN_CTL_BASE);
479           while(icl != icl_end && icl_this != icl_this_end)
480           {
481             cl      = icl->second;
482             cl_this = icl_this->second;
483             id      = cl->id();
484             id_this = cl_this->id();
485             if(id < id_this)
486               ++icl;      // Let id catch up to this id.
487             else if(id > id_this)
488               ++icl_this; // Let this id catch up to id.
489             else
490             {
491               // Match found. Copy properties and values.
492               cl_this->assign(*cl, CtrlList::ASSIGN_PROPERTIES | CtrlList::ASSIGN_VALUES);
493               ++icl;
494               ++icl_this;
495             }
496           }
497 
498           // Copy the special synth controller block...
499           icl           = at._controller.lower_bound(synth_id);
500           icl_this      = _controller.lower_bound(synth_id);
501           icl_end       = at._controller.lower_bound(synth_id_end);
502           icl_this_end  = _controller.lower_bound(synth_id_end);
503           while(icl != icl_end && icl_this != icl_this_end)
504           {
505             cl      = icl->second;
506             cl_this = icl_this->second;
507             id      = cl->id();
508             id_this = cl_this->id();
509             if(id < id_this)
510               ++icl;      // Let id catch up to this id.
511             else if(id > id_this)
512               ++icl_this; // Let this id catch up to id.
513             else
514             {
515               // Match found. Copy properties and values.
516               cl_this->assign(*cl, CtrlList::ASSIGN_PROPERTIES | CtrlList::ASSIGN_VALUES);
517               ++icl;
518               ++icl_this;
519             }
520           }
521         }
522 
523         if(flags & ASSIGN_PLUGIN_CTRLS)
524         {
525           // Copy all plugin controller blocks...
526           icl           = at._controller.lower_bound(AC_PLUGIN_CTL_BASE);
527           icl_this      = _controller.lower_bound(AC_PLUGIN_CTL_BASE);
528           icl_end       = at._controller.lower_bound(synth_id);
529           icl_this_end  = _controller.lower_bound(synth_id);
530           while(icl != icl_end && icl_this != icl_this_end)
531           {
532             cl      = icl->second;
533             cl_this = icl_this->second;
534             id      = cl->id();
535             id_this = cl_this->id();
536             if(id < id_this)
537               ++icl;      // Let id catch up to this id.
538             else if(id > id_this)
539               ++icl_this; // Let this id catch up to id.
540             else
541             {
542               // Match found. Copy properties and values.
543               cl_this->assign(*cl, CtrlList::ASSIGN_PROPERTIES | CtrlList::ASSIGN_VALUES);
544               ++icl;
545               ++icl_this;
546             }
547           }
548         }
549       }
550 
551       if(flags & ASSIGN_ROUTES)
552       {
553         for(ciRoute ir = at._inRoutes.begin(); ir != at._inRoutes.end(); ++ir)
554         {
555           // Defer all Jack routes to Audio Input and Output copy constructors or assign !
556           if(ir->type == Route::JACK_ROUTE)
557             continue;
558           // Don't call msgAddRoute. Caller later calls msgAddTrack which 'mirrors' this routing node.
559           _inRoutes.push_back(*ir);
560         }
561 
562         for(ciRoute ir = at._outRoutes.begin(); ir != at._outRoutes.end(); ++ir)
563         {
564           // Defer all Jack routes to Audio Input and Output copy constructors or assign !
565           if(ir->type == Route::JACK_ROUTE)
566             continue;
567           // Don't call msgAddRoute. Caller later calls msgAddTrack which 'mirrors' this routing node.
568           _outRoutes.push_back(*ir);
569         }
570       }
571       else if(flags & ASSIGN_DEFAULT_ROUTES)
572       {
573         //
574         //  add default route to master
575         //
576         OutputList* ol = MusEGlobal::song->outputs();
577         if (!ol->empty()) {
578               AudioOutput* ao = ol->front();
579               switch(type()) {
580                     case Track::WAVE:
581                     case Track::AUDIO_AUX:
582                           // Don't call msgAddRoute. Caller later calls msgAddTrack which 'mirrors' this routing node.
583                           _outRoutes.push_back(Route(ao));
584                           break;
585                     // It should actually never get here now, but just in case.
586                     case Track::AUDIO_SOFTSYNTH:
587                           // Don't call msgAddRoute. Caller later calls msgAddTrack which 'mirrors' this routing node.
588                           // Add an Omni route.
589                           _outRoutes.push_back(Route(ao));
590                           break;
591                     default:
592                           break;
593                     }
594               }
595       }
596 }
597 
assign(const Track & t,int flags)598 void AudioTrack::assign(const Track& t, int flags)
599 {
600       Track::assign(t, flags);
601       internal_assign(t, flags);
602 }
603 
~AudioTrack()604 AudioTrack::~AudioTrack()
605 {
606       delete _efxPipe;
607 
608       if(audioInSilenceBuf)
609         free(audioInSilenceBuf);
610 
611       if(audioOutDummyBuf)
612         free(audioOutDummyBuf);
613 
614       if(_latencyComp)
615         delete _latencyComp;
616 
617       if(_dataBuffers)
618       {
619         for(int i = 0; i < _totalOutChannels; ++i)
620         {
621           if(_dataBuffers[i])
622             free(_dataBuffers[i]);
623         }
624         delete[] _dataBuffers;
625       }
626 
627       if(outBuffersExtraMix)
628       {
629         for(int i = 0; i < MusECore::MAX_CHANNELS; ++i)
630         {
631           if(outBuffersExtraMix[i])
632             free(outBuffersExtraMix[i]);
633         }
634         delete[] outBuffersExtraMix;
635       }
636 
637       int chans = _totalOutChannels;
638       // Number of allocated buffers is always MAX_CHANNELS or more, even if _totalOutChannels is less.
639       if(chans < MusECore::MAX_CHANNELS)
640         chans = MusECore::MAX_CHANNELS;
641       if(outBuffers)
642       {
643         for(int i = 0; i < chans; ++i)
644         {
645           if(outBuffers[i])
646             free(outBuffers[i]);
647         }
648         delete[] outBuffers;
649       }
650 
651       if(_controls)
652         delete[] _controls;
653 
654       _controller.clearDelete();
655 }
656 
657 //---------------------------------------------------------
658 //   deleteAllEfxGuis
659 //---------------------------------------------------------
660 
deleteAllEfxGuis()661 void AudioTrack::deleteAllEfxGuis()
662 {
663   if(_efxPipe)
664     _efxPipe->deleteAllGuis();
665 }
666 
667 //---------------------------------------------------------
668 //   clearEfxList
669 //---------------------------------------------------------
670 
clearEfxList()671 void AudioTrack::clearEfxList()
672 {
673   if(_efxPipe)
674     for(int i = 0; i < MusECore::PipelineDepth; i++)
675       (*_efxPipe)[i] = 0;
676 }
677 
678 //---------------------------------------------------------
679 //   newPart
680 //---------------------------------------------------------
681 
newPart(Part *,bool)682 Part* AudioTrack::newPart(Part*, bool /*clone*/)
683       {
684       return 0;
685       }
686 
687 //---------------------------------------------------------
688 //   addPlugin
689 //---------------------------------------------------------
690 
addPlugin(PluginI * plugin,int idx)691 void AudioTrack::addPlugin(PluginI* plugin, int idx)
692 {
693   if (plugin == 0)
694   {
695     PluginI* oldPlugin = (*_efxPipe)[idx];
696     if (oldPlugin)
697     {
698       oldPlugin->setID(-1);
699       oldPlugin->setTrack(0);
700 
701       int controller = oldPlugin->parameters();
702       for (int i = 0; i < controller; ++i)
703       {
704         int id = genACnum(idx, i);
705         removeController(id);
706       }
707     }
708   }
709   efxPipe()->insert(plugin, idx);
710   setupPlugin(plugin, idx);
711 }
712 
713 //---------------------------------------------------------
714 //   setupPlugin
715 //---------------------------------------------------------
716 
setupPlugin(PluginI * plugin,int idx)717 void AudioTrack::setupPlugin(PluginI* plugin, int idx)
718 {
719   if (plugin)
720   {
721     plugin->setID(idx);
722     plugin->setTrack(this);
723 
724     int controller = plugin->parameters();
725     for (int i = 0; i < controller; ++i)
726     {
727       int id = genACnum(idx, i);
728       const char* name = plugin->paramName(i);
729       float min, max;
730       plugin->range(i, &min, &max);
731       CtrlList* cl = new CtrlList(id);
732       cl->setRange(min, max);
733       cl->setName(QString(name));
734       cl->setValueType(plugin->ctrlValueType(i));
735       cl->setMode(plugin->ctrlMode(i));
736       cl->setCurVal(plugin->param(i));
737       addController(cl);
738     }
739   }
740 }
741 
742 //---------------------------------------------------------
743 //   addAuxSend
744 //---------------------------------------------------------
745 
addAuxSend(int n)746 void AudioTrack::addAuxSend(int n)
747       {
748       int nn = _auxSend.size();
749       for (int i = nn; i < n; ++i) {
750             _auxSend.push_back(0.0);
751             _auxSend[i] = 0.0;  //??
752             }
753       }
754 
755 //---------------------------------------------------------
756 //   addController
757 //---------------------------------------------------------
758 
addController(CtrlList * list)759 void AudioTrack::addController(CtrlList* list)
760       {
761       _controller.add(list);
762       }
763 
764 //---------------------------------------------------------
765 //   removeController
766 //---------------------------------------------------------
767 
removeController(int id)768 void AudioTrack::removeController(int id)
769       {
770       AudioMidiCtrlStructMap amcs;
771       _controller.midiControls()->find_audio_ctrl_structs(id, &amcs);
772       for(ciAudioMidiCtrlStructMap iamcs = amcs.begin(); iamcs != amcs.end(); ++ iamcs)
773         _controller.midiControls()->erase(*iamcs);
774       iCtrlList i = _controller.find(id);
775       if (i == _controller.end()) {
776             printf("AudioTrack::removeController id %d not found\n", id);
777             return;
778             }
779       _controller.erase(i);
780       }
781 
782 //---------------------------------------------------------
783 //   swapControllerIDX
784 //---------------------------------------------------------
785 
swapControllerIDX(int idx1,int idx2)786 void AudioTrack::swapControllerIDX(int idx1, int idx2)
787 {
788   if(idx1 == idx2 || idx1 < 0 || idx2 < 0 || idx1 >= MusECore::PipelineDepth || idx2 >= MusECore::PipelineDepth)
789     return;
790 
791   CtrlList *cl;
792   CtrlList *newcl;
793   int id1 = (idx1 + 1) * AC_PLUGIN_CTL_BASE;
794   int id2 = (idx2 + 1) * AC_PLUGIN_CTL_BASE;
795   int id_mask = ~((int)AC_PLUGIN_CTL_ID_MASK);
796   int i, j;
797 
798   CtrlListList tmpcll;
799   CtrlVal cv(0, 0.0);
800 
801   for(ciCtrlList icl = _controller.begin(); icl != _controller.end(); ++icl)
802   {
803     cl = icl->second;
804     i = cl->id() & AC_PLUGIN_CTL_ID_MASK;
805     j = cl->id() & id_mask;
806     if(j == id1 || j == id2)
807     {
808       newcl = new CtrlList(i | (j == id1 ? id2 : id1), cl->dontShow());
809       newcl->setMode(cl->mode());
810       newcl->setValueType(cl->valueType());
811       newcl->setName(cl->name());
812       double min, max;
813       cl->range(&min, &max);
814       newcl->setRange(min, max);
815       newcl->setCurVal(cl->curVal());
816       newcl->setDefault(cl->getDefault());
817       newcl->setColor(cl->color());
818       newcl->setVisible(cl->isVisible());
819       for(iCtrl ic = cl->begin(); ic != cl->end(); ++ic)
820       {
821         cv = ic->second;
822         newcl->insert(CtrlListInsertPair_t(cv.frame, cv));
823       }
824       tmpcll.insert(std::pair<const int, CtrlList*>(newcl->id(), newcl));
825     }
826     else
827     {
828       newcl = new CtrlList();
829       *newcl = *cl;
830       tmpcll.insert(std::pair<const int, CtrlList*>(newcl->id(), newcl));
831     }
832   }
833 
834   for(iCtrlList ci = _controller.begin(); ci != _controller.end(); ++ci)
835     delete (*ci).second;
836 
837   _controller.clear();
838 
839   for(ciCtrlList icl = tmpcll.begin(); icl != tmpcll.end(); ++icl)
840   {
841     newcl = icl->second;
842     _controller.insert(std::pair<const int, CtrlList*>(newcl->id(), newcl));
843   }
844 
845   // Remap midi to audio controls...
846   MidiAudioCtrlMap* macm = _controller.midiControls();
847   for(iMidiAudioCtrlMap imacm = macm->begin(); imacm != macm->end(); ++imacm)
848   {
849     int actrl = imacm->second.audioCtrlId();
850     int id = actrl & id_mask;
851     actrl &= AC_PLUGIN_CTL_ID_MASK;
852     if(id == id1)
853       actrl |= id2;
854     else if(id == id2)
855       actrl |= id1;
856     else
857       continue;
858     imacm->second.setAudioCtrlId(actrl);
859   }
860 }
861 
862 //---------------------------------------------------------
863 //   setAutomationType
864 //---------------------------------------------------------
865 
setAutomationType(AutomationType t)866 void AudioTrack::setAutomationType(AutomationType t)
867 {
868   // Clear pressed and touched and rec event list.
869   clearRecAutomation(true);
870 
871   // Now set the type.
872   _automationType = t;
873 }
874 
875 //---------------------------------------------------------
876 //   setControllerMode
877 //---------------------------------------------------------
878 
setControllerMode(int ctlID,CtrlList::Mode m)879 void AudioTrack::setControllerMode(int ctlID, CtrlList::Mode m)
880       {
881       ciCtrlList cl = _controller.find(ctlID);
882       if(cl == _controller.end())
883         return;
884 
885       cl->second->setMode(m);
886       }
887 
888 //---------------------------------------------------------
889 //   clearControllerEvents
890 //---------------------------------------------------------
891 
clearControllerEvents(int id)892 void AudioTrack::clearControllerEvents(int id)
893 {
894   ciCtrlList icl = _controller.find(id);
895   if(icl == _controller.end())
896     return;
897 
898   CtrlList* cl = icl->second;
899   cl->clear();
900   return;
901 }
902 
903 //---------------------------------------------------------
904 //   seekPrevACEvent
905 //---------------------------------------------------------
906 
seekPrevACEvent(int id)907 void AudioTrack::seekPrevACEvent(int id)
908 {
909   ciCtrlList icl = _controller.find(id);
910   if(icl == _controller.end()){
911     return;
912   }
913 
914     CtrlList* cl = icl->second;
915     if(cl->empty())
916       return;
917 
918     iCtrl s = cl->lower_bound(MusEGlobal::audio->pos().frame());
919     if(s != cl->begin())
920       --s;
921 
922     MusEGlobal::song->setPos(Song::CPOS, Pos(s->second.frame, false), false, true, false);
923     return;
924 }
925 
926 //---------------------------------------------------------
927 //   seekNextACEvent
928 //---------------------------------------------------------
929 
seekNextACEvent(int id)930 void AudioTrack::seekNextACEvent(int id)
931 {
932   ciCtrlList icl = _controller.find(id);
933   if(icl == _controller.end()) {
934     return;
935   }
936 
937     CtrlList* cl = icl->second;
938     if(cl->empty())
939       return;
940 
941     iCtrl s = cl->upper_bound(MusEGlobal::audio->pos().frame());
942 
943     if(s == cl->end())
944     {
945       --s;
946     }
947 
948     MusEGlobal::song->setPos(Song::CPOS, Pos(s->second.frame, false), false, true, false);
949     return;
950 }
951 
952 //---------------------------------------------------------
953 //   eraseACEvent
954 //---------------------------------------------------------
955 
eraseACEvent(int id,int frame)956 void AudioTrack::eraseACEvent(int id, int frame)
957 {
958   ciCtrlList icl = _controller.find(id);
959   if(icl == _controller.end()) {
960     return;
961   }
962 
963 
964     CtrlList* cl = icl->second;
965     if(cl->empty())
966       return;
967 
968     iCtrl s = cl->find(frame);
969     if(s != cl->end())
970       cl->erase(s);
971     return;
972 }
973 
974 //---------------------------------------------------------
975 //   eraseRangeACEvents
976 //---------------------------------------------------------
977 
eraseRangeACEvents(int id,int frame1,int frame2)978 void AudioTrack::eraseRangeACEvents(int id, int frame1, int frame2)
979 {
980   ciCtrlList icl = _controller.find(id);
981   if(icl == _controller.end()) {
982     return;
983   }
984 
985     CtrlList* cl = icl->second;
986     if(cl->empty())
987       return;
988 
989     iCtrl s = cl->lower_bound(frame1);
990     iCtrl e = cl->lower_bound(frame2);
991     cl->erase(s, e);
992     return;
993 }
994 
995 //---------------------------------------------------------
996 //   addACEvent
997 //---------------------------------------------------------
998 
addACEvent(int id,int frame,double val)999 void AudioTrack::addACEvent(int id, int frame, double val)
1000 {
1001   ciCtrlList icl = _controller.find(id);
1002   if(icl == _controller.end()) {
1003     return;
1004   }
1005 
1006     CtrlList* cl = icl->second;
1007 
1008     // Add will replace if found.
1009     cl->add(frame, val);
1010     return;
1011 }
1012 
1013 //---------------------------------------------------------
1014 //   changeACEvent
1015 //---------------------------------------------------------
1016 
changeACEvent(int id,int frame,int newframe,double newval)1017 void AudioTrack::changeACEvent(int id, int frame, int newframe, double newval)
1018 {
1019   ciCtrlList icl = _controller.find(id);
1020   if(icl == _controller.end())
1021     return;
1022   CtrlList* cl = icl->second;
1023   iCtrl ic = cl->find(frame);
1024   if(ic != cl->end())
1025     cl->erase(ic);
1026   cl->insert(CtrlListInsertPair_t(newframe, CtrlVal(newframe, newval)));
1027 }
1028 
1029 //---------------------------------------------------------
1030 //   useLatencyCorrection
1031 //---------------------------------------------------------
1032 
useLatencyCorrection() const1033 bool AudioTrack::useLatencyCorrection() const
1034 {
1035   return _latencyComp && MusEGlobal::config.enableLatencyCorrection;
1036 }
1037 
1038 //---------------------------------------------------------
1039 //   selfLatencyAudio
1040 //---------------------------------------------------------
1041 
selfLatencyAudio(int) const1042 float AudioTrack::selfLatencyAudio(int /*channel*/) const
1043 {
1044   if(!_efxPipe)
1045     return 0.0;
1046   return _efxPipe->latency();
1047 }
1048 
1049 //---------------------------------------------------------
1050 //   getDominanceInfo
1051 //---------------------------------------------------------
1052 
getDominanceInfo(bool input)1053 TrackLatencyInfo& AudioTrack::getDominanceInfo(bool input)
1054 {
1055   // Have we been here before during this scan?
1056   // Just return the cached value.
1057   if((input && _latencyInfo._canDominateInputProcessed) ||
1058      (!input && _latencyInfo._canDominateProcessed))
1059     return _latencyInfo;
1060 
1061   // Get the default domination for this track type.
1062   bool can_dominate_lat = input ? canDominateInputLatency() : canDominateOutputLatency();
1063   bool can_correct_lat = canCorrectOutputLatency();
1064 
1065   const bool passthru = canPassThruLatency();
1066 
1067   bool item_found = false;
1068 
1069   if(!off() && (passthru || input))
1070   {
1071     RouteList* rl = inRoutes();
1072     for (iRoute ir = rl->begin(); ir != rl->end(); ++ir)
1073     {
1074       switch(ir->type)
1075       {
1076         case Route::TRACK_ROUTE:
1077           if(!ir->track)
1078             continue;
1079           if(ir->track->isMidiTrack())
1080           {
1081             // TODO ?
1082           }
1083           else
1084           {
1085             Track* track = ir->track;
1086             if(!track->off())
1087             {
1088               const TrackLatencyInfo& li = track->getDominanceInfo(false);
1089 
1090               // Whether the branch can dominate or correct latency or if we
1091               //  want to allow unterminated input branches to
1092               //  participate in worst branch latency calculations.
1093               const bool participate =
1094                 (li._canCorrectOutputLatency ||
1095                 li._canDominateOutputLatency ||
1096                 MusEGlobal::config.correctUnterminatedInBranchLatency);
1097 
1098               if(participate)
1099               {
1100                 // Is it the first found item?
1101                 if(item_found)
1102                 {
1103                   // If any one of the branches can dominate the latency,
1104                   //  that overrides any which cannot.
1105                   if(li._canDominateOutputLatency)
1106                     can_dominate_lat = true;
1107                   if(li._canCorrectOutputLatency)
1108                     can_correct_lat = true;
1109                 }
1110                 else
1111                 {
1112                   item_found = true;
1113                   // Override the defaults with this first item's values.
1114                   can_dominate_lat = li._canDominateOutputLatency;
1115                   can_correct_lat = li._canCorrectOutputLatency;
1116                 }
1117               }
1118             }
1119           }
1120         break;
1121 
1122         default:
1123         break;
1124       }
1125     }
1126 
1127     // Special for the built-in metronome.
1128     //if(!off() && !MusECore::metronome->off() && (passthru || input) && sendMetronome())
1129     if(!MusECore::metronome->off() && sendMetronome())
1130     {
1131       const TrackLatencyInfo& li = MusECore::metronome->getDominanceInfo(false);
1132 
1133       // Whether the branch can dominate or correct latency or if we
1134       //  want to allow unterminated input branches to
1135       //  participate in worst branch latency calculations.
1136       const bool participate =
1137         (li._canCorrectOutputLatency ||
1138         li._canDominateOutputLatency ||
1139         MusEGlobal::config.correctUnterminatedInBranchLatency);
1140 
1141       if(participate)
1142       {
1143         // Is it the first found item?
1144         if(item_found)
1145         {
1146           // If any one of the branches can dominate the latency,
1147           //  that overrides any which cannot.
1148           if(li._canDominateOutputLatency)
1149             can_dominate_lat = true;
1150           if(li._canCorrectOutputLatency)
1151             can_correct_lat = true;
1152         }
1153         else
1154         {
1155           item_found = true;
1156           can_dominate_lat = li._canDominateOutputLatency;
1157           can_correct_lat = li._canCorrectOutputLatency;
1158         }
1159       }
1160     }
1161   }
1162 
1163   // Set the correction of all connected input branches,
1164   //  but ONLY if the track is not off.
1165   if(!off())
1166   {
1167     if(input)
1168     {
1169       _latencyInfo._canDominateInputLatency = can_dominate_lat;
1170     }
1171     else
1172     {
1173       _latencyInfo._canDominateOutputLatency = can_dominate_lat;
1174       // If any of the branches can dominate, then this node cannot correct.
1175       _latencyInfo._canCorrectOutputLatency = can_correct_lat && !can_dominate_lat;
1176     }
1177   }
1178 
1179   if(input)
1180     _latencyInfo._canDominateInputProcessed = true;
1181   else
1182     _latencyInfo._canDominateProcessed = true;
1183 
1184   return _latencyInfo;
1185 }
1186 
1187 //---------------------------------------------------------
1188 //   getDominanceLatencyInfo
1189 //---------------------------------------------------------
1190 
getDominanceLatencyInfo(bool input)1191 TrackLatencyInfo& AudioTrack::getDominanceLatencyInfo(bool input)
1192 {
1193   // Have we been here before during this scan?
1194   // Just return the cached value.
1195   if((input && _latencyInfo._dominanceInputProcessed) ||
1196      (!input && _latencyInfo._dominanceProcessed))
1197     return _latencyInfo;
1198 
1199   float route_worst_latency = 0.0f;
1200 
1201   const bool passthru = canPassThruLatency();
1202 
1203   bool item_found = false;
1204 
1205   float worst_self_latency = 0.0f;
1206   if(!input && !off())
1207     worst_self_latency = getWorstSelfLatencyAudio();
1208 
1209   if(!off() && (passthru || input))
1210   {
1211     RouteList* rl = inRoutes();
1212     for (iRoute ir = rl->begin(); ir != rl->end(); ++ir)
1213     {
1214       switch(ir->type)
1215       {
1216         case Route::TRACK_ROUTE:
1217           if(!ir->track)
1218             continue;
1219           if(ir->track->isMidiTrack())
1220           {
1221             // TODO ?
1222           }
1223           else
1224           {
1225             Track* track = ir->track;
1226 
1227             //if(!off() && !track->off() && (passthru || input))
1228             if(!track->off())
1229             {
1230               const TrackLatencyInfo& li = track->getDominanceLatencyInfo(false);
1231 
1232               // Whether the branch can dominate or correct latency or if we
1233               //  want to allow unterminated input branches to
1234               //  participate in worst branch latency calculations.
1235               const bool participate =
1236                 (li._canCorrectOutputLatency ||
1237                 li._canDominateOutputLatency ||
1238                 MusEGlobal::config.correctUnterminatedInBranchLatency);
1239 
1240               if(participate)
1241               {
1242                 // Is it the first found item?
1243                 if(item_found)
1244                 {
1245                   // If any one of the branches can dominate the latency,
1246                   //  that overrides any which cannot.
1247                   if(li._canDominateOutputLatency)
1248                   {
1249                     // Override the current worst value if the latency is greater,
1250                     //  but ONLY if the branch can dominate.
1251                     //if(li._outputLatency > route_worst_latency)
1252                     //  route_worst_latency = li._outputLatency;
1253                   }
1254                   // Override the current worst value if the latency is greater,
1255                   //  but ONLY if the branch can dominate.
1256                   if(li._outputLatency > route_worst_latency)
1257                     route_worst_latency = li._outputLatency;
1258                 }
1259                 else
1260                 {
1261                   item_found = true;
1262                   // Override the default worst value, but ONLY if the branch can dominate.
1263                   //if(li._canDominateOutputLatency)
1264                     route_worst_latency = li._outputLatency;
1265                 }
1266               }
1267             }
1268           }
1269         break;
1270 
1271         default:
1272         break;
1273       }
1274     }
1275 
1276     // Special for the built-in metronome.
1277     //if(!off() && !MusECore::metronome->off() && (passthru || input) && sendMetronome())
1278     if(!MusECore::metronome->off() && sendMetronome())
1279     {
1280       const TrackLatencyInfo& li = MusECore::metronome->getDominanceLatencyInfo(false);
1281 
1282       // Whether the branch can dominate or correct latency or if we
1283       //  want to allow unterminated input branches to
1284       //  participate in worst branch latency calculations.
1285       const bool participate =
1286         (li._canCorrectOutputLatency ||
1287         li._canDominateOutputLatency ||
1288         MusEGlobal::config.correctUnterminatedInBranchLatency);
1289 
1290       if(participate)
1291       {
1292         // Is it the first found item?
1293         if(item_found)
1294         {
1295           // If any one of the branches can dominate the latency,
1296           //  that overrides any which cannot.
1297           if(li._canDominateOutputLatency)
1298           {
1299             // Override the current worst value if the latency is greater,
1300             //  but ONLY if the branch can dominate.
1301             //if(li._outputLatency > route_worst_latency)
1302             //  route_worst_latency = li._outputLatency;
1303           }
1304           // Override the current worst value if the latency is greater,
1305           //  but ONLY if the branch can dominate.
1306           if(li._outputLatency > route_worst_latency)
1307             route_worst_latency = li._outputLatency;
1308         }
1309         else
1310         {
1311           item_found = true;
1312           // Override the default worst value, but ONLY if the branch can dominate.
1313           //if(li._canDominateOutputLatency)
1314             route_worst_latency = li._outputLatency;
1315         }
1316       }
1317     }
1318   }
1319 
1320   // Set the correction of all connected input branches,
1321   //  but ONLY if the track is not off.
1322   if(!off())
1323   {
1324     if(input)
1325     {
1326       _latencyInfo._inputLatency = route_worst_latency;
1327     }
1328     else
1329     {
1330       if(passthru)
1331       {
1332         _latencyInfo._outputLatency = worst_self_latency + route_worst_latency;
1333         _latencyInfo._inputLatency = route_worst_latency;
1334       }
1335       else
1336       {
1337         _latencyInfo._outputLatency = worst_self_latency + _latencyInfo._sourceCorrectionValue;
1338       }
1339     }
1340   }
1341 
1342   if(input)
1343     _latencyInfo._dominanceInputProcessed = true;
1344   else
1345     _latencyInfo._dominanceProcessed = true;
1346 
1347   return _latencyInfo;
1348 }
1349 
1350 //---------------------------------------------------------
1351 //   getWorstPluginLatencyAudio
1352 //---------------------------------------------------------
1353 
getWorstPluginLatencyAudio()1354 float AudioTrack::getWorstPluginLatencyAudio()
1355 {
1356   // Have we been here before during this scan?
1357   // Just return the cached value.
1358   if(_latencyInfo._worstPluginLatencyProcessed)
1359     return _latencyInfo._worstPluginLatency;
1360 
1361   float worst_lat = 0.0f;
1362   // Include the effects rack latency.
1363   if(_efxPipe)
1364     worst_lat += _efxPipe->latency();
1365 
1366   _latencyInfo._worstPluginLatency = worst_lat;
1367   _latencyInfo._worstPluginLatencyProcessed = true;
1368   return _latencyInfo._worstPluginLatency;
1369 }
1370 
1371 //---------------------------------------------------------
1372 //   getWorstSelfLatencyAudio
1373 //---------------------------------------------------------
1374 
getWorstSelfLatencyAudio()1375 float AudioTrack::getWorstSelfLatencyAudio()
1376 {
1377   // Have we been here before during this scan?
1378   // Just return the cached value.
1379   if(_latencyInfo._worstSelfLatencyProcessed)
1380     return _latencyInfo._worstSelfLatency;
1381 
1382   // Include the effects rack latency and any synth latency and any port latency.
1383   _latencyInfo._worstSelfLatency = getWorstPluginLatencyAudio() + getWorstPortLatencyAudio();
1384 
1385   // The absolute latency of signals leaving this track is the sum of
1386   //  any connected route latencies and this track's latency.
1387   _latencyInfo._worstSelfLatencyProcessed = true;
1388   return _latencyInfo._worstSelfLatency;
1389 }
1390 
1391 //---------------------------------------------------------
1392 //   setCorrectionLatencyInfo
1393 //---------------------------------------------------------
1394 
setCorrectionLatencyInfo(bool input,float finalWorstLatency,float callerBranchLatency)1395 TrackLatencyInfo& AudioTrack::setCorrectionLatencyInfo(bool input, float finalWorstLatency, float callerBranchLatency)
1396 {
1397   const bool passthru = canPassThruLatency();
1398 
1399   float worst_self_latency = 0.0f;
1400   if(!input && !off())
1401     worst_self_latency = getWorstSelfLatencyAudio();
1402 
1403   // The _trackLatency should already be calculated in the dominance scan.
1404   const float branch_lat = callerBranchLatency + worst_self_latency;
1405 
1406   if(!off() && (passthru || input))
1407   {
1408     RouteList* rl = inRoutes();
1409     for (iRoute ir = rl->begin(); ir != rl->end(); ++ir)
1410     {
1411       if(ir->type != Route::TRACK_ROUTE || !ir->track || ir->track->isMidiTrack())
1412         continue;
1413       Track* track = ir->track;
1414       //if(!off() && !track->off() && (passthru || input))
1415       if(!track->off())
1416         track->setCorrectionLatencyInfo(false, finalWorstLatency, branch_lat);
1417     }
1418 
1419     // Special for the built-in metronome.
1420     //if(!off() && !MusECore::metronome->off() && (passthru || input) && sendMetronome())
1421     if(!MusECore::metronome->off() && sendMetronome())
1422     {
1423       MusECore::metronome->setCorrectionLatencyInfo(false, finalWorstLatency, branch_lat);
1424     }
1425   }
1426 
1427   // Set the correction of all connected input branches,
1428   //  but ONLY if the track is not off.
1429   if(!off())
1430   {
1431     if(input)
1432     {
1433     }
1434     else
1435     {
1436       if(canCorrectOutputLatency() && _latencyInfo._canCorrectOutputLatency)
1437       {
1438         float corr = 0.0f;
1439         if(MusEGlobal::config.commonProjectLatency)
1440           corr -= finalWorstLatency;
1441 
1442         corr -= branch_lat;
1443         // The _sourceCorrectionValue is initialized to zero.
1444         // Whichever calling branch needs the most correction gets it.
1445         if(corr < _latencyInfo._sourceCorrectionValue)
1446           _latencyInfo._sourceCorrectionValue = corr;
1447       }
1448     }
1449 
1450     //fprintf(stderr, "AudioTrack::setCorrectionLatencyInfo() name:%s finalWorstLatency:%f branch_lat:%f corr:%f _sourceCorrectionValue:%f\n",
1451     //        name().toLatin1().constData(), finalWorstLatency, branch_lat, corr, _latencyInfo._sourceCorrectionValue);
1452   }
1453 
1454   return _latencyInfo;
1455 }
1456 
1457 //---------------------------------------------------------
1458 //   getLatencyInfo
1459 //---------------------------------------------------------
1460 
getLatencyInfo(bool input)1461 TrackLatencyInfo& AudioTrack::getLatencyInfo(bool input)
1462 {
1463   // Have we been here before during this scan?
1464   // Just return the cached value.
1465   if((input && _latencyInfo._inputProcessed) ||
1466     (!input && _latencyInfo._processed))
1467     return _latencyInfo;
1468 
1469   float route_worst_latency = _latencyInfo._inputLatency;
1470 
1471   const bool passthru = canPassThruLatency();
1472 
1473   if(passthru || input)
1474   {
1475     RouteList* rl = inRoutes();
1476 
1477     // Now that we know the worst-case latency of the connected branches,
1478     //  adjust each of the conveniently stored temporary latency values
1479     //  in the routes according to whether they can dominate...
1480     for (iRoute ir = rl->begin(); ir != rl->end(); ++ir)
1481     {
1482       if(ir->type != Route::TRACK_ROUTE || !ir->track || ir->track->isMidiTrack())
1483         continue;
1484 
1485       Track* track = ir->track;
1486 
1487       // Default to zero.
1488       ir->audioLatencyOut = 0.0f;
1489 
1490       if(!off() && !track->off())
1491       {
1492         const TrackLatencyInfo& li = track->getLatencyInfo(false);
1493         const bool participate =
1494           (li._canCorrectOutputLatency ||
1495           li._canDominateOutputLatency ||
1496           MusEGlobal::config.correctUnterminatedInBranchLatency);
1497 
1498         if(participate)
1499         {
1500           // Prepare the latency value to be passed to the compensator's writer,
1501           //  by adjusting each route latency value. ie. the route with the worst-case
1502           //  latency will get ZERO delay, while routes having smaller latency will get
1503           //  MORE delay, to match all the signal timings together.
1504           // The route's audioLatencyOut should have already been calculated and
1505           //  conveniently stored in the route.
1506           ir->audioLatencyOut = route_worst_latency - li._outputLatency;
1507           // Should not happen, but just in case.
1508           if((long int)ir->audioLatencyOut < 0)
1509             ir->audioLatencyOut = 0.0f;
1510         }
1511       }
1512     }
1513 
1514     // Special for the built-in metronome.
1515     // Default to zero.
1516     _latencyInfo._latencyOutMetronome = 0.0f;
1517     if(!off() && !MusECore::metronome->off() && sendMetronome())
1518     {
1519       TrackLatencyInfo& li = MusECore::metronome->getLatencyInfo(false);
1520 
1521       const bool participate =
1522         li._canCorrectOutputLatency ||
1523         li._canDominateOutputLatency ||
1524         MusEGlobal::config.correctUnterminatedInBranchLatency;
1525 
1526       if(participate)
1527       {
1528         // TODO: FIXME: Where to store? We have no route to store it in.
1529         // Prepare the latency value to be passed to the compensator's writer,
1530         //  by adjusting each route latency value. ie. the route with the worst-case
1531         //  latency will get ZERO delay, while routes having smaller latency will get
1532         //  MORE delay, to match all the signal timings together.
1533         // The route's audioLatencyOut should have already been calculated and
1534         //  conveniently stored in the route.
1535 
1536 //             ir->audioLatencyOut = route_worst_latency - ir->audioLatencyOut;
1537 //             // Should not happen, but just in case.
1538 //             if((long int)ir->audioLatencyOut < 0)
1539 //               ir->audioLatencyOut = 0.0f;
1540 
1541         // Special for metronome: We don't have metronome routes yet.
1542         // So we must store this information here just for the metronome.
1543         li._latencyOutMetronome = route_worst_latency - li._latencyOutMetronome;
1544         // Should not happen, but just in case.
1545         if((long int)li._latencyOutMetronome < 0)
1546           li._latencyOutMetronome = 0.0f;
1547       }
1548     }
1549   }
1550 
1551   if(input)
1552     _latencyInfo._inputProcessed = true;
1553   else
1554     _latencyInfo._processed = true;
1555 
1556   return _latencyInfo;
1557 }
1558 
setLatencyCompWriteOffset(float worstCase)1559 void AudioTrack::setLatencyCompWriteOffset(float worstCase)
1560 {
1561   // If independent branches are NOT to affect project latency,
1562   //  then there should be no need for any extra delay in the branch.
1563   if(!MusEGlobal::config.commonProjectLatency)
1564   {
1565     _latencyInfo._compensatorWriteOffset = 0;
1566     //fprintf(stderr, "AudioTrack::setLatencyCompWriteOffset() name:%s worstCase:%f _outputLatency:%f _compensatorWriteOffset:%lu\n",
1567     //        name().toLatin1().constData(), worstCase, _latencyInfo._outputLatency, _latencyInfo._compensatorWriteOffset);
1568     return;
1569   }
1570 
1571   if(_latencyInfo._canDominateOutputLatency)
1572   {
1573     const long unsigned int wc = worstCase;
1574     const long unsigned int ol = _latencyInfo._outputLatency;
1575     if(ol > wc)
1576       _latencyInfo._compensatorWriteOffset = 0;
1577     else
1578       _latencyInfo._compensatorWriteOffset = wc - ol;
1579   }
1580   else
1581   {
1582 //     if(_latencyInfo._outputLatency < 0)
1583       _latencyInfo._compensatorWriteOffset = 0;
1584 //     else
1585 //       _latencyInfo._compensatorWriteOffset = _latencyInfo._outputLatency;
1586   }
1587 
1588   //fprintf(stderr,
1589   //  "AudioTrack::setLatencyCompWriteOffset() name:%s worstCase:%f"
1590   //  " _outputLatency:%f _canDominateOutputLatency:%d _compensatorWriteOffset:%lu\n",
1591   //      name().toLatin1().constData(), worstCase, _latencyInfo._outputLatency,
1592   //      _latencyInfo._canDominateOutputLatency, _latencyInfo._compensatorWriteOffset);
1593 }
1594 
1595 //---------------------------------------------------------
1596 //   volume
1597 //---------------------------------------------------------
1598 
volume() const1599 double AudioTrack::volume() const
1600       {
1601       return _controller.value(AC_VOLUME, MusEGlobal::audio->curFramePos(),
1602                                !MusEGlobal::automation || automationType() == AUTO_OFF || !_controls[AC_VOLUME].enCtrl);
1603       }
1604 
1605 //---------------------------------------------------------
1606 //   setVolume
1607 //---------------------------------------------------------
1608 
setVolume(double val)1609 void AudioTrack::setVolume(double val)
1610       {
1611       iCtrlList cl = _controller.find(AC_VOLUME);
1612       if (cl == _controller.end()) {
1613             printf("no volume controller %s %zd\n",
1614                name().toLatin1().constData(), _controller.size());
1615             return;
1616             }
1617       cl->second->setCurVal(val);
1618       }
1619 
1620 //---------------------------------------------------------
1621 //   pan
1622 //---------------------------------------------------------
1623 
pan() const1624 double AudioTrack::pan() const
1625       {
1626       return _controller.value(AC_PAN, MusEGlobal::audio->curFramePos(),
1627                                !MusEGlobal::automation || automationType() == AUTO_OFF || !_controls[AC_PAN].enCtrl);
1628       }
1629 
1630 //---------------------------------------------------------
1631 //   setPan
1632 //---------------------------------------------------------
1633 
setPan(double val)1634 void AudioTrack::setPan(double val)
1635       {
1636       iCtrlList cl = _controller.find(AC_PAN);
1637       if (cl == _controller.end()) {
1638             printf("no pan controller\n");
1639             return;
1640             }
1641       cl->second->setCurVal(val);
1642       }
1643 
1644 //---------------------------------------------------------
1645 //   pan
1646 //---------------------------------------------------------
1647 
gain() const1648 double AudioTrack::gain() const
1649       {
1650         return _gain;
1651       }
1652 
1653 //---------------------------------------------------------
1654 //   setPan
1655 //---------------------------------------------------------
1656 
setGain(double val)1657 void AudioTrack::setGain(double val)
1658       {
1659         _gain = val;
1660       }
1661 
1662 //---------------------------------------------------------
1663 //   pluginCtrlVal
1664 //---------------------------------------------------------
1665 
pluginCtrlVal(int ctlID) const1666 double AudioTrack::pluginCtrlVal(int ctlID) const
1667       {
1668       bool en = true;
1669       if(ctlID < AC_PLUGIN_CTL_BASE)
1670       {
1671         if((unsigned long)ctlID < _controlPorts)
1672           en = _controls[ctlID].enCtrl;
1673       }
1674       else
1675       {
1676         if(ctlID < (int)genACnum(MusECore::MAX_PLUGINS, 0))  // The beginning of the special synth controller block.
1677         {
1678           en = _efxPipe->controllerEnabled(ctlID);
1679         }
1680         else
1681         {
1682           if(type() == AUDIO_SOFTSYNTH)
1683           {
1684             const SynthI* synth = static_cast<const SynthI*>(this);
1685             const SynthIF* sif = synth->sif();
1686             if(sif)
1687             {
1688               int in_ctrl_idx = ctlID & AC_PLUGIN_CTL_ID_MASK;
1689               en = sif->controllerEnabled(in_ctrl_idx);
1690             }
1691           }
1692         }
1693       }
1694 
1695       return _controller.value(ctlID, MusEGlobal::audio->curFramePos(),
1696                                !MusEGlobal::automation || automationType() == AUTO_OFF || !en);
1697       }
1698 
1699 //---------------------------------------------------------
1700 //   setPluginCtrlVal
1701 //---------------------------------------------------------
1702 
setPluginCtrlVal(int param,double val)1703 void AudioTrack::setPluginCtrlVal(int param, double val)
1704 {
1705   iCtrlList cl = _controller.find(param);
1706   if (cl == _controller.end())
1707     return;
1708 
1709   cl->second->setCurVal(val);
1710 }
1711 
1712 //---------------------------------------------------------
1713 //   addScheduledControlEvent
1714 //   returns true if event cannot be delivered
1715 //---------------------------------------------------------
1716 
addScheduledControlEvent(int track_ctrl_id,double val,unsigned frame)1717 bool AudioTrack::addScheduledControlEvent(int track_ctrl_id, double val, unsigned frame)
1718 {
1719   if(track_ctrl_id < AC_PLUGIN_CTL_BASE)
1720   {
1721     // Send these controllers directly to the track's own FIFO.
1722     ControlEvent ce;
1723     ce.unique = false;
1724     ce.fromGui = false;
1725     ce.idx = track_ctrl_id;
1726     ce.value = val;
1727     // Time-stamp the event. timestamp() is circular, which is making it impossible to deal with 'modulo' events which
1728     //  slip in 'under the wire' before processing the ring buffers. So try this linear timestamp instead:
1729     ce.frame = frame;
1730     if(_controlFifo.put(ce))
1731     {
1732       fprintf(stderr, "AudioTrack::addScheduledControlEvent: fifo overflow: in control number:%d\n", track_ctrl_id);
1733       return true;
1734     }
1735     return false;
1736   }
1737   else
1738   {
1739     if(track_ctrl_id < (int)genACnum(MusECore::MAX_PLUGINS, 0))  // The beginning of the special synth controller block.
1740       return _efxPipe->addScheduledControlEvent(track_ctrl_id, val, frame);
1741     else
1742     {
1743       if(type() == AUDIO_SOFTSYNTH)
1744       {
1745         const SynthI* synth = static_cast<const SynthI*>(this);
1746         SynthIF* sif = synth->sif();
1747         if(sif)
1748         {
1749           int in_ctrl_idx = track_ctrl_id & AC_PLUGIN_CTL_ID_MASK;
1750           return sif->addScheduledControlEvent(in_ctrl_idx, val, frame);
1751         }
1752       }
1753     }
1754   }
1755   return true;
1756 }
1757 
1758 //---------------------------------------------------------
1759 //   enableController
1760 //   Enable or disable gui controls.
1761 //   Used during automation recording to inhibit gui controls
1762 //    from playback controller stream
1763 //---------------------------------------------------------
1764 
enableController(int track_ctrl_id,bool en)1765 void AudioTrack::enableController(int track_ctrl_id, bool en)
1766 {
1767   if(track_ctrl_id < AC_PLUGIN_CTL_BASE)
1768   {
1769     if((unsigned long)track_ctrl_id < _controlPorts)
1770       _controls[track_ctrl_id].enCtrl = en;
1771   }
1772   else
1773   {
1774     if(track_ctrl_id < (int)genACnum(MusECore::MAX_PLUGINS, 0))  // The beginning of the special synth controller block.
1775       _efxPipe->enableController(track_ctrl_id, en);
1776     else
1777     {
1778       if(type() == AUDIO_SOFTSYNTH)
1779       {
1780         const SynthI* synth = static_cast<const SynthI*>(this);
1781         SynthIF* sif = synth->sif();
1782         if(sif)
1783         {
1784           int in_ctrl_idx = track_ctrl_id & AC_PLUGIN_CTL_ID_MASK;
1785           sif->enableController(in_ctrl_idx, en);
1786         }
1787       }
1788     }
1789   }
1790 }
1791 
1792 //---------------------------------------------------------
1793 //   controllerEnabled
1794 //---------------------------------------------------------
1795 
controllerEnabled(int track_ctrl_id) const1796 bool AudioTrack::controllerEnabled(int track_ctrl_id) const
1797       {
1798       if(track_ctrl_id < AC_PLUGIN_CTL_BASE)
1799       {
1800         if((unsigned long)track_ctrl_id < _controlPorts)
1801           return _controls[track_ctrl_id].enCtrl;
1802         return false;
1803       }
1804       else
1805       {
1806         if(track_ctrl_id < (int)genACnum(MusECore::MAX_PLUGINS, 0))  // The beginning of the special synth controller block.
1807         {
1808           return _efxPipe->controllerEnabled(track_ctrl_id);
1809         }
1810         else
1811         {
1812           if(type() == AUDIO_SOFTSYNTH)
1813           {
1814             const SynthI* synth = static_cast<const SynthI*>(this);
1815             const SynthIF* sif = synth->sif();
1816             if(sif)
1817             {
1818               int in_ctrl_idx = track_ctrl_id & AC_PLUGIN_CTL_ID_MASK;
1819               return sif->controllerEnabled(in_ctrl_idx);
1820             }
1821           }
1822         }
1823       }
1824       return false;
1825       }
1826 
1827 //---------------------------------------------------------
1828 //   enableAllControllers
1829 //   Enable all track and plugin controllers, and synth controllers if applicable.
1830 //---------------------------------------------------------
1831 
enableAllControllers()1832 void AudioTrack::enableAllControllers()
1833 {
1834     // Enable track controllers:
1835     for(unsigned long i = 0; i < _controlPorts; ++i)
1836       _controls[i].enCtrl = true;
1837 
1838     // Enable plugin controllers:
1839     Pipeline *pl = efxPipe();
1840     PluginI *p;
1841     for(iPluginI i = pl->begin(); i != pl->end(); ++i)
1842     {
1843       p = *i;
1844       if(!p)
1845         continue;
1846       p->enableAllControllers(true);
1847     }
1848 
1849     // Enable synth controllers:
1850     if(type() == AUDIO_SOFTSYNTH)
1851     {
1852       const SynthI* synth = static_cast<const SynthI*>(this);
1853       SynthIF* sif = synth->sif();
1854       if(sif)
1855         sif->enableAllControllers(true);
1856     }
1857 }
1858 
recordAutomation(int n,double v)1859 void AudioTrack::recordAutomation(int n, double v)
1860       {
1861         if(!MusEGlobal::automation)
1862           return;
1863         if(MusEGlobal::audio->isPlaying())
1864           _recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v));
1865         else
1866         {
1867           if(automationType() == AUTO_WRITE)
1868             _recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v));
1869           else
1870           if(automationType() == AUTO_TOUCH)
1871           // In touch mode and not playing. Send directly to controller list.
1872           {
1873             iCtrlList cl = _controller.find(n);
1874             if (cl == _controller.end())
1875               return;
1876             // Add will replace if found.
1877             cl->second->add(MusEGlobal::audio->curFramePos(), v);
1878           }
1879         }
1880       }
1881 
startAutoRecord(int n,double v)1882 void AudioTrack::startAutoRecord(int n, double v)
1883       {
1884         if(!MusEGlobal::automation)
1885           return;
1886         if(MusEGlobal::audio->isPlaying())
1887         {
1888           if(automationType() == AUTO_TOUCH)
1889               _recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v, ARVT_START));
1890           else
1891           if(automationType() == AUTO_WRITE)
1892               _recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v));
1893         }
1894         else
1895         {
1896           if(automationType() == AUTO_TOUCH)
1897           // In touch mode and not playing. Send directly to controller list.
1898           {
1899             // FIXME: Unsafe? Should sync by sending a message, but that'll really slow it down with large audio bufs.
1900             iCtrlList cl = _controller.find(n);
1901             if (cl == _controller.end())
1902               return;
1903             // Add will replace if found.
1904             cl->second->add(MusEGlobal::audio->curFramePos(), v);
1905           }
1906           else
1907           if(automationType() == AUTO_WRITE)
1908             _recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v));
1909         }
1910       }
1911 
stopAutoRecord(int n,double v)1912 void AudioTrack::stopAutoRecord(int n, double v)
1913       {
1914         if(!MusEGlobal::automation)
1915           return;
1916         if(MusEGlobal::audio->isPlaying())
1917         {
1918           if(automationType() == AUTO_TOUCH)
1919           {
1920               MusEGlobal::song->applyOperation(UndoOp(UndoOp::AddAudioCtrlVal,
1921                              this, n, MusEGlobal::audio->curFramePos(), v));
1922               _recEvents.push_back(CtrlRecVal(MusEGlobal::audio->curFramePos(), n, v, ARVT_STOP));
1923           }
1924         }
1925       }
1926 
1927 //---------------------------------------------------------
1928 //   AudioTrack::writeProperties
1929 //---------------------------------------------------------
1930 
writeProperties(int level,Xml & xml) const1931 void AudioTrack::writeProperties(int level, Xml& xml) const
1932       {
1933       Track::writeProperties(level, xml);
1934       xml.intTag(level, "prefader", prefader());
1935       xml.intTag(level, "sendMetronome", sendMetronome());
1936       xml.intTag(level, "automation", int(automationType()));
1937       xml.doubleTag(level, "gain", _gain);
1938       if (hasAuxSend()) {
1939             int naux = MusEGlobal::song->auxs()->size();
1940             for (int idx = 0; idx < naux; ++idx) {
1941                   QString s("<auxSend idx=\"%1\">%2</auxSend>\n");  // Aux fix from Remon, thanks.
1942                   xml.nput(level, s.arg(idx).arg(_auxSend[idx]).toLatin1().constData());
1943                   }
1944             }
1945       for (ciPluginI ip = _efxPipe->begin(); ip != _efxPipe->end(); ++ip) {
1946             if (*ip)
1947                   (*ip)->writeConfiguration(level, xml);
1948             }
1949       _controller.write(level, xml);
1950       }
1951 
1952 //---------------------------------------------------------
1953 //   readAuxSend
1954 //---------------------------------------------------------
1955 
readAuxSend(Xml & xml)1956 void AudioTrack::readAuxSend(Xml& xml)
1957       {
1958       unsigned idx = 0;
1959       double val;
1960       for (;;) {
1961             Xml::Token token = xml.parse();
1962             const QString& tag = xml.s1();
1963             switch (token) {
1964                   case Xml::Error:
1965                   case Xml::End:
1966                         return;
1967                   case Xml::Attribut:
1968                         if (tag == "idx")
1969                               idx = xml.s2().toInt();
1970                         break;
1971                   case Xml::Text:
1972                         val = tag.toDouble();
1973                         break;
1974                   case Xml::TagEnd:
1975                         if (xml.s1() == "auxSend") {
1976                               if (_auxSend.size() < idx+1)
1977                                     _auxSend.push_back(val);
1978                               else
1979                                     _auxSend[idx] = val;
1980                               return;
1981                               }
1982                   default:
1983                         break;
1984                   }
1985             }
1986       }
1987 
1988 //---------------------------------------------------------
1989 //   AudioTrack::readProperties
1990 //---------------------------------------------------------
1991 
readProperties(Xml & xml,const QString & tag)1992 bool AudioTrack::readProperties(Xml& xml, const QString& tag)
1993       {
1994       if (tag == "plugin")
1995       {
1996             int rackpos;
1997             for(rackpos = 0; rackpos < MusECore::PipelineDepth; ++rackpos)
1998             {
1999               if(!(*_efxPipe)[rackpos])
2000                 break;
2001             }
2002             if(rackpos < MusECore::PipelineDepth)
2003             {
2004               PluginI* pi = new PluginI();
2005               pi->setTrack(this);
2006               pi->setID(rackpos);
2007               if(pi->readConfiguration(xml, false))
2008                 delete pi;
2009               else
2010                 (*_efxPipe)[rackpos] = pi;
2011             }
2012             else
2013               printf("can't load plugin - plugin rack is already full\n");
2014       }
2015       else if (tag == "auxSend")
2016             readAuxSend(xml);
2017       else if (tag == "prefader")
2018             _prefader = xml.parseInt();
2019       else if (tag == "sendMetronome")
2020             _sendMetronome = xml.parseInt();
2021       else if (tag == "gain")
2022             _gain = xml.parseDouble();
2023       else if (tag == "automation")
2024             setAutomationType(AutomationType(xml.parseInt()));
2025       else if (tag == "controller") {
2026             CtrlList* l = new CtrlList();
2027             l->read(xml);
2028 
2029             // Since (until now) muse wrote a 'zero' for plugin controller current value
2030             //  in the XML file, we can't use that value, now that plugin automation is added.
2031             // We must take the value from the plugin control value.
2032             // Otherwise we break all existing .med files with plugins, because the gui
2033             //  controls would all be set to zero.
2034             // But we will allow for the (unintended, useless) possibility of a controller
2035             //  with no matching plugin control.
2036             const PluginIBase* p = 0;
2037             bool ctlfound = false;
2038             unsigned m = l->id() & AC_PLUGIN_CTL_ID_MASK;
2039             int n = (l->id() >> AC_PLUGIN_CTL_BASE_POW) - 1;
2040             if(n >= 0 && n < MusECore::PipelineDepth)
2041               p = (*_efxPipe)[n];
2042             // Support a special block for synth controllers.
2043             else if(n == MusECore::MAX_PLUGINS && type() == AUDIO_SOFTSYNTH)
2044             {
2045               const SynthI* synti = static_cast < SynthI* > (this);
2046               const SynthIF* sif = synti->sif();
2047               if(sif)
2048                 p = static_cast < const PluginIBase* > (sif);
2049             }
2050 
2051             if(p && m < p->parameters())
2052               ctlfound = true;
2053 
2054             iCtrlList icl = _controller.find(l->id());
2055             if (icl == _controller.end())
2056                   _controller.add(l);
2057             else {
2058                   CtrlList* d = icl->second;
2059                   for (iCtrl i = l->begin(); i != l->end(); ++i)
2060                         d->insert(CtrlListInsertPair_t(i->first, i->second));
2061 
2062                   if(!ctlfound)
2063                         d->setCurVal(l->curVal());
2064                   d->setColor(l->color());
2065                   d->setVisible(l->isVisible());
2066                   d->setDefault(l->getDefault());
2067                   delete l;
2068                   l = d;
2069                   }
2070 
2071               if(ctlfound)
2072                 {
2073                   l->setCurVal(p->param(m));
2074                   l->setValueType(p->ctrlValueType(m));
2075                   l->setMode(p->ctrlMode(m));
2076                 }
2077             }
2078       else if (tag == "midiMapper")
2079             _controller.midiControls()->read(xml);
2080       else
2081             return Track::readProperties(xml, tag);
2082       return false;
2083       }
2084 
2085 //---------------------------------------------------------
2086 //   showPendingPluginNativeGuis
2087 //   This is needed because OSC needs all tracks with plugins to be already
2088 //    added to their track lists so it can find them and show their native guis.
2089 //---------------------------------------------------------
2090 
showPendingPluginNativeGuis()2091 void AudioTrack::showPendingPluginNativeGuis()
2092 {
2093   for(int idx = 0; idx < MusECore::PipelineDepth; ++idx)
2094   {
2095     PluginI* p = (*_efxPipe)[idx];
2096     if(!p)
2097       continue;
2098 
2099     if(p->isShowNativeGuiPending())
2100       p->showNativeGui(true);
2101   }
2102 }
2103 
2104 //---------------------------------------------------------
2105 //   mapRackPluginsToControllers
2106 //---------------------------------------------------------
2107 
mapRackPluginsToControllers()2108 void AudioTrack::mapRackPluginsToControllers()
2109 {
2110   // Iterate all possible plugin controller indexes...
2111   for(int idx = MusECore::PipelineDepth - 1; idx >= 0; idx--)
2112   {
2113     iCtrlList icl = _controller.lower_bound((idx + 1) * AC_PLUGIN_CTL_BASE);
2114     if(icl == _controller.end() || ((icl->second->id() >> AC_PLUGIN_CTL_BASE_POW) - 1) != idx)
2115       continue;
2116 
2117     // We found some controllers with that index. Now iterate the plugin rack...
2118     for(int i = idx; i >= 0; i--)
2119     {
2120       PluginI* p = (*_efxPipe)[i];
2121       if(!p)
2122         continue;
2123 
2124       // We found a plugin at a rack position. If the rack position is not the same as the controller index...
2125       if(i != idx)
2126       {
2127         (*_efxPipe)[i] = 0;
2128         (*_efxPipe)[idx] = p;
2129       }
2130       p->setID(idx);
2131 
2132       // It is now safe to update the controllers.
2133       p->updateControllers();
2134 
2135       break;
2136     }
2137   }
2138 
2139   // No matter of the outcome of the above - rack position is not too critical -
2140   //  making sure that each control has a controller is important. Otherwise they
2141   //  are stuck at zero can't be adjusted.
2142   // Muse med files created before the automation patches (before 0.9pre1) may have broken
2143   //  controller sections, so this will allow more tolerance of them.
2144   for(int idx = 0; idx < MusECore::PipelineDepth; idx++)
2145   {
2146     PluginI* p = (*_efxPipe)[idx];
2147     if(!p)
2148       continue;
2149 
2150     if(p->id() != idx)
2151       p->setID(idx);
2152 
2153     int j = p->parameters();
2154 
2155     for(int i = 0; i < j; i++)
2156     {
2157       int id = genACnum(idx, i);
2158       CtrlList* l = 0;
2159 
2160       ciCtrlList icl = _controller.find(id);
2161       if(icl == _controller.end())
2162       {
2163         l = new CtrlList(id);
2164         addController(l);
2165       }
2166       else
2167         l = icl->second;
2168 
2169       // Force all of these now, even though they may have already been set. With a pre-
2170       //  0.9pre1 med file with broken controller sections they may not be set correct.
2171       float min, max;
2172       p->range(i, &min, &max);
2173       l->setRange(min, max);
2174       l->setName(QString(p->paramName(i)));
2175       l->setValueType(p->ctrlValueType(i));
2176       l->setMode(p->ctrlMode(i));
2177       l->setCurVal(p->param(i));
2178     }
2179   }
2180 
2181   // Delete non-existent controllers.
2182   for(ciCtrlList icl = _controller.cbegin(); icl != _controller.cend(); )
2183   {
2184     CtrlList* l = icl->second;
2185     int id = l->id();
2186     // Ignore volume, pan, mute etc.
2187     if(id < AC_PLUGIN_CTL_BASE)
2188     {
2189       ++icl;
2190       continue;
2191     }
2192 
2193     unsigned param = id & AC_PLUGIN_CTL_ID_MASK;
2194     int idx = (id >> AC_PLUGIN_CTL_BASE_POW) - 1;
2195 
2196     bool do_remove = false;
2197     const PluginIBase* p = 0;
2198     if(idx >= 0 && idx < MusECore::PipelineDepth)
2199     {
2200       p = (*_efxPipe)[idx];
2201       if(!p || (param >= p->parameters()))
2202         do_remove = true;
2203     }
2204     // Support a special block for synth controllers.
2205     else if(idx == MusECore::MAX_PLUGINS && type() == AUDIO_SOFTSYNTH)
2206     {
2207       const SynthI* synti = static_cast < const SynthI* > (this);
2208       SynthIF* sif = synti->sif();
2209       // Special for synths: If no sif could be found or loaded (missing pplugin etc.),
2210       //  do NOT remove the loaded controllers, to preserve data upon re-saving.
2211       if(sif)
2212       {
2213         p = static_cast < const PluginIBase* > (sif);
2214         if(param >= p->parameters())
2215           do_remove = true;
2216       }
2217     }
2218 
2219     // If there's no plugin at that rack position, or the param is out of range of
2220     //  the number of controls in the plugin, then it's a stray controller. Delete it.
2221     // Future: Leave room for possible bypass controller at AC_PLUGIN_CTL_ID_MASK -1.
2222     //if(!p || (param >= p->parameters() && (param != AC_PLUGIN_CTL_ID_MASK -1)))
2223     if(do_remove)
2224     {
2225       // C++11.
2226       icl = _controller.erase(icl);
2227     }
2228     else
2229     {
2230       ++icl;
2231     }
2232   }
2233 }
2234 
routeCapabilities() const2235 RouteCapabilitiesStruct AudioTrack::routeCapabilities() const
2236 {
2237   RouteCapabilitiesStruct s;
2238   s._trackChannels._inChannels = s._trackChannels._outChannels = totalProcessBuffers();
2239   s._trackChannels._inRoutable = s._trackChannels._outRoutable = (s._trackChannels._inChannels != 0);
2240   return s;
2241 }
2242 
2243 //---------------------------------------------------------
2244 //   AudioInput
2245 //---------------------------------------------------------
2246 
AudioInput()2247 AudioInput::AudioInput()
2248    // Default 1 channel for audio inputs.
2249    : AudioTrack(AUDIO_INPUT, 1)
2250       {
2251       for (int i = 0; i < MusECore::MAX_CHANNELS; ++i)
2252             jackPorts[i] = 0;
2253       }
2254 
AudioInput(const AudioInput & t,int flags)2255 AudioInput::AudioInput(const AudioInput& t, int flags)
2256   : AudioTrack(t, flags)
2257 {
2258   for (int i = 0; i < MusECore::MAX_CHANNELS; ++i)
2259         jackPorts[i] = 0;
2260 
2261   // It is pointless to try to register ports right now since the
2262   //  track names are currently the same. The registration will fail
2263   //  due to duplicate port names.
2264   // Therefore the caller MUST set a unique track name afterwards,
2265   //  which does succeed at registering the ports.
2266 
2267   internal_assign(t, flags);
2268 }
2269 
assign(const Track & t,int flags)2270 void AudioInput::assign(const Track& t, int flags)
2271 {
2272   AudioTrack::assign(t, flags);
2273   internal_assign(t, flags);
2274 }
2275 
internal_assign(const Track & t,int flags)2276 void AudioInput::internal_assign(const Track& t, int flags)
2277 {
2278   if(t.type() != AUDIO_INPUT)
2279     return;
2280 
2281   const AudioInput& at = (const AudioInput&)t;
2282 
2283   if(flags & ASSIGN_ROUTES)
2284   {
2285     for(ciRoute ir = at._inRoutes.begin(); ir != at._inRoutes.end(); ++ir)
2286     {
2287       // Defer all Jack routes to these copy constructors or assign !
2288       if(ir->type != Route::JACK_ROUTE)
2289         continue;
2290       // Don't call msgAddRoute. Caller later calls msgAddTrack which 'mirrors' this routing node.
2291       _inRoutes.push_back(*ir);
2292     }
2293   }
2294 }
2295 
2296 //---------------------------------------------------------
2297 //   ~AudioInput
2298 //---------------------------------------------------------
2299 
~AudioInput()2300 AudioInput::~AudioInput()
2301       {
2302       if (!MusEGlobal::checkAudioDevice()) return;
2303       for (int i = 0; i < _channels; ++i)
2304           if(jackPorts[i])
2305               MusEGlobal::audioDevice->unregisterPort(jackPorts[i]);
2306       }
2307 
2308 //---------------------------------------------------------
2309 //   selfLatencyAudio
2310 //---------------------------------------------------------
2311 
selfLatencyAudio(int channel) const2312 float AudioInput::selfLatencyAudio(int channel) const
2313 {
2314   float l = AudioTrack::selfLatencyAudio(channel);
2315 
2316   if(!MusEGlobal::checkAudioDevice())
2317     return l;
2318 
2319   void* jackPort = jackPorts[channel];
2320   if(jackPort)
2321     l += MusEGlobal::audioDevice->portLatency(jackPort, true);
2322   return l;
2323 }
2324 
2325 //---------------------------------------------------------
2326 //   getWorstPortLatencyAudio
2327 //---------------------------------------------------------
2328 
getWorstPortLatencyAudio()2329 float AudioInput::getWorstPortLatencyAudio()
2330 {
2331   // Have we been here before during this scan?
2332   // Just return the cached value.
2333   if(_latencyInfo._worstPortLatencyProcessed)
2334     return _latencyInfo._worstPortLatency;
2335 
2336   float worst_lat = 0.0f;
2337   // Include any port latencies.
2338   if(MusEGlobal::checkAudioDevice())
2339   {
2340     const int track_out_channels = totalProcessBuffers(); // totalOutChannels();
2341     for(int i = 0; i < track_out_channels; ++i)
2342     {
2343       void* jackPort = jackPorts[i];
2344       if(jackPort)
2345       {
2346         // true = we want the capture latency.
2347         const float lat = MusEGlobal::audioDevice->portLatency(jackPort, true);
2348         if(lat > worst_lat)
2349           worst_lat = lat;
2350       }
2351     }
2352   }
2353 
2354   _latencyInfo._worstPortLatency = worst_lat;
2355   _latencyInfo._worstPortLatencyProcessed = true;
2356   return _latencyInfo._worstPortLatency;
2357 }
2358 
canDominateOutputLatency() const2359 bool AudioInput::canDominateOutputLatency() const
2360 {
2361   return !off();
2362 }
2363 
2364 //---------------------------------------------------------
2365 //   write
2366 //---------------------------------------------------------
2367 
write(int level,Xml & xml) const2368 void AudioInput::write(int level, Xml& xml) const
2369       {
2370       xml.tag(level++, "AudioInput");
2371       AudioTrack::writeProperties(level, xml);
2372       xml.etag(level, "AudioInput");
2373       }
2374 
2375 //---------------------------------------------------------
2376 //   read
2377 //---------------------------------------------------------
2378 
read(Xml & xml)2379 void AudioInput::read(Xml& xml)
2380       {
2381       for (;;) {
2382             Xml::Token token = xml.parse();
2383             const QString& tag = xml.s1();
2384             switch (token) {
2385                   case Xml::Error:
2386                   case Xml::End:
2387                         return;
2388                   case Xml::TagStart:
2389                         if (AudioTrack::readProperties(xml, tag))
2390                               xml.unknown("AudioInput");
2391                         break;
2392                   case Xml::Attribut:
2393                         break;
2394                   case Xml::TagEnd:
2395                         if (tag == "AudioInput") {
2396                               registerPorts();  // allocate jack ports
2397                               mapRackPluginsToControllers();
2398                               return;
2399                               }
2400                   default:
2401                         break;
2402                   }
2403             }
2404       }
2405 
routeCapabilities() const2406 RouteCapabilitiesStruct AudioInput::routeCapabilities() const
2407 {
2408   RouteCapabilitiesStruct s = AudioTrack::routeCapabilities();
2409 
2410   // Support Midi Track to Audio Input Track routes (for soloing chain).
2411   s._trackChannels._inRoutable = true;
2412   s._trackChannels._inChannels = 0;
2413 
2414   s._jackChannels._inRoutable = false;
2415   s._jackChannels._inChannels = totalProcessBuffers();
2416   return s;
2417 }
2418 
2419 //---------------------------------------------------------
2420 //   AudioOutput
2421 //---------------------------------------------------------
2422 
AudioOutput()2423 AudioOutput::AudioOutput()
2424    : AudioTrack(AUDIO_OUTPUT)
2425       {
2426       _outputLatencyComp = new LatencyCompensator();
2427 
2428       _nframes = 0;
2429       for (int i = 0; i < MAX_CHANNELS; ++i)
2430             jackPorts[i] = 0;
2431       }
2432 
AudioOutput(const AudioOutput & t,int flags)2433 AudioOutput::AudioOutput(const AudioOutput& t, int flags)
2434   : AudioTrack(t, flags)
2435 {
2436   _outputLatencyComp = new LatencyCompensator();
2437 
2438   for (int i = 0; i < MusECore::MAX_CHANNELS; ++i)
2439         jackPorts[i] = 0;
2440   _nframes = 0;
2441 
2442   // It is pointless to try to register ports right now since the
2443   //  track names are currently the same. The registration will fail
2444   //  due to duplicate port names.
2445   // Therefore the caller MUST set a unique track name afterwards,
2446   //  which does succeed at registering the ports.
2447 
2448   internal_assign(t, flags);
2449 }
2450 
assign(const Track & t,int flags)2451 void AudioOutput::assign(const Track& t, int flags)
2452 {
2453   AudioTrack::assign(t, flags);
2454   internal_assign(t, flags);
2455 }
2456 
internal_assign(const Track & t,int flags)2457 void AudioOutput::internal_assign(const Track& t, int flags)
2458 {
2459   if(t.type() != AUDIO_OUTPUT)
2460     return;
2461 
2462   const AudioOutput& at = (const AudioOutput&)t;
2463 
2464   if(flags & ASSIGN_ROUTES)
2465   {
2466     for(ciRoute ir = at._outRoutes.begin(); ir != at._outRoutes.end(); ++ir)
2467     {
2468       // Defer all Jack routes to these copy constructors or assign !
2469       if(ir->type != Route::JACK_ROUTE)
2470         continue;
2471       // Don't call msgAddRoute. Caller later calls msgAddTrack which 'mirrors' this routing node.
2472       _outRoutes.push_back(*ir);
2473     }
2474   }
2475 }
2476 
2477 //---------------------------------------------------------
2478 //   ~AudioOutput
2479 //---------------------------------------------------------
2480 
~AudioOutput()2481 AudioOutput::~AudioOutput()
2482       {
2483       // FIXME Never runs this on close because device is nulled first.
2484       //       But possibly it's benign because it may already disconnect before it gets here...
2485       if (MusEGlobal::checkAudioDevice())
2486       {
2487         for (int i = 0; i < _channels; ++i)
2488           if(jackPorts[i])
2489             MusEGlobal::audioDevice->unregisterPort(jackPorts[i]);
2490       }
2491 
2492       if(_outputLatencyComp)
2493         delete _outputLatencyComp;
2494       }
2495 
2496 //---------------------------------------------------------
2497 //   setChannels
2498 //---------------------------------------------------------
2499 
setChannels(int n)2500 void AudioOutput::setChannels(int n)
2501       {
2502       AudioTrack::setChannels(n);
2503       if(useLatencyCorrection() && _outputLatencyComp)
2504         _outputLatencyComp->setChannels(totalProcessBuffers());
2505       }
2506 
2507 //---------------------------------------------------------
2508 //   selfLatencyAudio
2509 //---------------------------------------------------------
2510 
selfLatencyAudio(int channel) const2511 float AudioOutput::selfLatencyAudio(int channel) const
2512 {
2513   float l = AudioTrack::selfLatencyAudio(channel);
2514 
2515   if(!MusEGlobal::checkAudioDevice())
2516     return l;
2517 
2518   void* jackPort = jackPorts[channel];
2519   if(jackPort)
2520     l += MusEGlobal::audioDevice->portLatency(jackPort, false);
2521   return l;
2522 }
2523 
2524 //---------------------------------------------------------
2525 //   getWorstPortLatencyAudio
2526 //---------------------------------------------------------
2527 
getWorstPortLatencyAudio()2528 float AudioOutput::getWorstPortLatencyAudio()
2529 {
2530   // Have we been here before during this scan?
2531   // Just return the cached value.
2532   if(_latencyInfo._worstPortLatencyProcessed)
2533     return _latencyInfo._worstPortLatency;
2534 
2535   float worst_lat = 0.0f;
2536   // Include any port latencies.
2537   if(MusEGlobal::checkAudioDevice())
2538   {
2539     const int track_out_channels = totalProcessBuffers(); // totalOutChannels();
2540     for(int i = 0; i < track_out_channels; ++i)
2541     {
2542       void* jackPort = jackPorts[i];
2543       if(jackPort)
2544       {
2545         // false = we want the playback latency.
2546         const float lat = MusEGlobal::audioDevice->portLatency(jackPort, false);
2547         if(lat > worst_lat)
2548           worst_lat = lat;
2549       }
2550     }
2551   }
2552 
2553   _latencyInfo._worstPortLatency = worst_lat;
2554   _latencyInfo._worstPortLatencyProcessed = true;
2555   return _latencyInfo._worstPortLatency;
2556 }
2557 
isLatencyInputTerminal()2558 bool AudioOutput::isLatencyInputTerminal()
2559 {
2560   // Have we been here before during this scan?
2561   // Just return the cached value.
2562   if(_latencyInfo._isLatencyInputTerminalProcessed)
2563     return _latencyInfo._isLatencyInputTerminal;
2564 
2565   _latencyInfo._isLatencyInputTerminal = true;
2566   _latencyInfo._isLatencyInputTerminalProcessed = true;
2567   return true;
2568 }
isLatencyOutputTerminal()2569 bool AudioOutput::isLatencyOutputTerminal()
2570 {
2571   // Have we been here before during this scan?
2572   // Just return the cached value.
2573   if(_latencyInfo._isLatencyOutputTerminalProcessed)
2574     return _latencyInfo._isLatencyOutputTerminal;
2575 
2576   _latencyInfo._isLatencyOutputTerminal = true;
2577   _latencyInfo._isLatencyOutputTerminalProcessed = true;
2578   return true;
2579 }
2580 
2581 //---------------------------------------------------------
2582 //   applyOutputLatencyComp
2583 //---------------------------------------------------------
2584 
applyOutputLatencyComp(unsigned nframes)2585 void AudioOutput::applyOutputLatencyComp(unsigned nframes)
2586 {
2587   if(!useLatencyCorrection() || !_outputLatencyComp)
2588     return;
2589 
2590   // Include any port latencies.
2591   if(MusEGlobal::checkAudioDevice())
2592   {
2593     // We want the audio output track's worst port latency.
2594     //const TrackLatencyInfo& li = getLatencyInfo(false /*output*/);
2595     //const float route_worst_case_latency = li._worstPortLatency;
2596     const float port_worst_case_latency = getWorstPortLatencyAudio();
2597 
2598     // 'buffer' is only MAX_CHANNELS deep, unlike some of our allocated audio buffers.
2599     const int track_out_channels = MusECore::MAX_CHANNELS; //totalProcessBuffers(); // totalOutChannels();
2600     for(int i = 0; i < track_out_channels; ++i)
2601     {
2602       if(!buffer[i])
2603         continue;
2604       // Prepare the latency value to be passed to the compensator's writer,
2605       //  by adjusting each channel latency value. ie. the channel with the worst-case
2606       //  latency will get ZERO delay, while channels having smaller latency will get
2607       //  MORE delay, to match all the signal timings together.
2608       void* jackPort = jackPorts[i];
2609       if(jackPort)
2610       {
2611         // false = we want the playback latency.
2612         const float lat = port_worst_case_latency - MusEGlobal::audioDevice->portLatency(jackPort, false);
2613         unsigned long offset = 0;
2614         if((long int)lat > 0)
2615           offset = lat;
2616 
2617         // Write the channel buffer to the latency compensator.
2618         // It will be read back later, in-place.
2619         _outputLatencyComp->write(i, nframes, offset /* + latencyCompWriteOffset() */, buffer[i]);
2620         // Read back the latency compensated signal, using the channel buffer in-place.
2621         _outputLatencyComp->read(i, nframes, buffer[i]);
2622       }
2623     }
2624   }
2625 }
2626 
2627 //---------------------------------------------------------
2628 //   write
2629 //---------------------------------------------------------
2630 
write(int level,Xml & xml) const2631 void AudioOutput::write(int level, Xml& xml) const
2632       {
2633       xml.tag(level++, "AudioOutput");
2634       AudioTrack::writeProperties(level, xml);
2635       xml.etag(level, "AudioOutput");
2636       }
2637 
2638 //---------------------------------------------------------
2639 //   read
2640 //---------------------------------------------------------
2641 
read(Xml & xml)2642 void AudioOutput::read(Xml& xml)
2643       {
2644       for (;;) {
2645             Xml::Token token = xml.parse();
2646             const QString& tag = xml.s1();
2647             switch (token) {
2648                   case Xml::Error:
2649                   case Xml::End:
2650                         return;
2651                   case Xml::TagStart:
2652                         if (AudioTrack::readProperties(xml, tag))
2653                               xml.unknown("AudioOutput");
2654                         break;
2655                   case Xml::Attribut:
2656                         break;
2657                   case Xml::TagEnd:
2658                         if (tag == "AudioOutput") {
2659                               registerPorts();  // allocate jack ports
2660                               mapRackPluginsToControllers();
2661                               return;
2662                               }
2663                   default:
2664                         break;
2665                   }
2666             }
2667       }
2668 
routeCapabilities() const2669 RouteCapabilitiesStruct AudioOutput::routeCapabilities() const
2670 {
2671   RouteCapabilitiesStruct s = AudioTrack::routeCapabilities();
2672 
2673   // Support Midi Track to Audio Input Track routes (for soloing chain).
2674   s._trackChannels._outRoutable = true;
2675   s._trackChannels._outChannels = 0;
2676 
2677   s._jackChannels._outRoutable = false;
2678   s._jackChannels._outChannels = totalProcessBuffers();
2679   return s;
2680 }
2681 
2682 //---------------------------------------------------------
2683 //   write
2684 //---------------------------------------------------------
2685 
write(int level,Xml & xml) const2686 void AudioGroup::write(int level, Xml& xml) const
2687       {
2688       xml.tag(level++, "AudioGroup");
2689       AudioTrack::writeProperties(level, xml);
2690       xml.etag(level, "AudioGroup");
2691       }
2692 
2693 //---------------------------------------------------------
2694 //   read
2695 //---------------------------------------------------------
2696 
read(Xml & xml)2697 void AudioGroup::read(Xml& xml)
2698       {
2699       for (;;) {
2700             Xml::Token token = xml.parse();
2701             const QString& tag = xml.s1();
2702             switch (token) {
2703                   case Xml::Error:
2704                   case Xml::End:
2705                         return;
2706                   case Xml::TagStart:
2707                         if (AudioTrack::readProperties(xml, tag))
2708                               xml.unknown("AudioGroup");
2709                         break;
2710                   case Xml::Attribut:
2711                         break;
2712                   case Xml::TagEnd:
2713                         if (tag == "AudioGroup")
2714                         {
2715                               mapRackPluginsToControllers();
2716                               return;
2717                         }
2718                   default:
2719                         break;
2720                   }
2721             }
2722       }
2723 
2724 //---------------------------------------------------------
2725 //   write
2726 //---------------------------------------------------------
2727 
write(int level,Xml & xml) const2728 void AudioAux::write(int level, Xml& xml) const
2729       {
2730       xml.tag(level++, "AudioAux");
2731       AudioTrack::writeProperties(level, xml);
2732       xml.intTag(level, "index", _index);
2733       xml.etag(level, "AudioAux");
2734       }
2735 
2736 
2737 //---------------------------------------------------------
2738 //   getNextAuxIndex
2739 //---------------------------------------------------------
getNextAuxIndex()2740 int getNextAuxIndex()
2741 {
2742     int curAux=0;
2743     AuxList * al = MusEGlobal::song->auxs();
2744     for (MusECore::iAudioAux i = al->begin(); i != al->end(); ++i)
2745     {
2746         MusECore::AudioAux* ax = *i;
2747         printf("aux index %d\n", ax->index());
2748         if (ax->index() > curAux)
2749         {
2750             printf("found new index! %d\n", ax->index());
2751             curAux = ax->index();
2752         }
2753     }
2754     return curAux+1;
2755 }
2756 
2757 //---------------------------------------------------------
2758 //   AudioAux
2759 //---------------------------------------------------------
2760 
AudioAux()2761 AudioAux::AudioAux()
2762    : AudioTrack(AUDIO_AUX)
2763 {
2764       _index = getNextAuxIndex();
2765       for(int i = 0; i < MusECore::MAX_CHANNELS; ++i)
2766       {
2767         if(i < channels())
2768         {
2769 #ifdef _WIN32
2770           buffer[i] = (float *) _aligned_malloc(16, sizeof(float) * MusEGlobal::segmentSize);
2771           if(buffer[i] == NULL)
2772           {
2773             fprintf(stderr, "ERROR: AudioAux ctor: _aligned_malloc returned error: NULL. Aborting!\n");
2774             abort();
2775           }
2776 #else
2777           int rv = posix_memalign((void**)(buffer + i), 16, sizeof(float) * MusEGlobal::segmentSize);
2778           if(rv != 0)
2779           {
2780             fprintf(stderr, "ERROR: AudioAux ctor: posix_memalign returned error:%d. Aborting!\n", rv);
2781             abort();
2782           }
2783 #endif
2784           if(MusEGlobal::config.useDenormalBias)
2785           {
2786             for(unsigned q = 0; q < MusEGlobal::segmentSize; ++q)
2787               buffer[i][q] = MusEGlobal::denormalBias;
2788           }
2789           else
2790             memset(buffer[i], 0, sizeof(float) * MusEGlobal::segmentSize);
2791         }
2792         else
2793           buffer[i] = 0;
2794       }
2795 }
2796 
AudioAux(const AudioAux & t,int flags)2797 AudioAux::AudioAux(const AudioAux& t, int flags)
2798    : AudioTrack(t, flags)
2799 {
2800       _index = getNextAuxIndex();
2801       for(int i = 0; i < MusECore::MAX_CHANNELS; ++i)
2802       {
2803         if(i < channels())
2804         {
2805 #ifdef _WIN32
2806           buffer[i] = (float *) _aligned_malloc(16, sizeof(float) * MusEGlobal::segmentSize);
2807           if(buffer[i] == NULL)
2808           {
2809             fprintf(stderr, "ERROR: AudioAux ctor: _aligned_malloc returned error: NULL. Aborting!\n");
2810             abort();
2811           }
2812 #else
2813           int rv = posix_memalign((void**)(buffer + i), 16, sizeof(float) * MusEGlobal::segmentSize);
2814           if(rv != 0)
2815           {
2816             fprintf(stderr, "ERROR: AudioAux ctor: posix_memalign returned error:%d. Aborting!\n", rv);
2817             abort();
2818           }
2819 #endif
2820           if(MusEGlobal::config.useDenormalBias)
2821           {
2822             for(unsigned q = 0; q < MusEGlobal::segmentSize; ++q)
2823               buffer[i][q] = MusEGlobal::denormalBias;
2824           }
2825           else
2826             memset(buffer[i], 0, sizeof(float) * MusEGlobal::segmentSize);
2827         }
2828         else
2829           buffer[i] = 0;
2830       }
2831 }
2832 //---------------------------------------------------------
2833 //   AudioAux
2834 //---------------------------------------------------------
2835 
~AudioAux()2836 AudioAux::~AudioAux()
2837 {
2838       for (int i = 0; i < MusECore::MAX_CHANNELS; ++i) {
2839             if (buffer[i])
2840                 free(buffer[i]);
2841       }
2842 }
2843 
2844 //---------------------------------------------------------
2845 //   read
2846 //---------------------------------------------------------
2847 
read(Xml & xml)2848 void AudioAux::read(Xml& xml)
2849       {
2850       for (;;) {
2851             Xml::Token token = xml.parse();
2852             const QString& tag = xml.s1();
2853             switch (token) {
2854                   case Xml::Error:
2855                   case Xml::End:
2856                         return;
2857                   case Xml::TagStart:
2858                       if (tag == "index")
2859                         _index = xml.parseInt();
2860                       else if (AudioTrack::readProperties(xml, tag))
2861                               xml.unknown("AudioAux");
2862                         break;
2863                   case Xml::Attribut:
2864                         break;
2865                   case Xml::TagEnd:
2866                         if (tag == "AudioAux")
2867                         {
2868                               mapRackPluginsToControllers();
2869                               return;
2870                         }
2871                   default:
2872                         break;
2873                   }
2874             }
2875       }
2876 
2877 //---------------------------------------------------------
2878 //   getData
2879 //---------------------------------------------------------
2880 
getData(unsigned pos,int ch,unsigned samples,float ** data)2881 bool AudioAux::getData(unsigned pos, int ch, unsigned samples, float** data)
2882       {
2883       // Make sure all the aux-supporting tracks are processed first so aux data is gathered.
2884       TrackList* tl = MusEGlobal::song->tracks();
2885       AudioTrack* track;
2886       for(ciTrack it = tl->begin(); it != tl->end(); ++it)
2887       {
2888         if((*it)->isMidiTrack())
2889           continue;
2890         track = (AudioTrack*)(*it);
2891         // If there are any Aux route paths to the track, defer processing until the second main track processing pass.
2892         if(!track->processed() && track->hasAuxSend() && !track->auxRefCount())
2893         {
2894           int chans = track->channels();
2895           // Just a dummy buffer.
2896           float* buff[chans];
2897           float buff_data[samples * chans];
2898           for (int i = 0; i < chans; ++i)
2899                 buff[i] = buff_data + i * samples;
2900 
2901           track->copyData(pos, -1, chans, chans, -1, -1, samples, buff);
2902         }
2903       }
2904 
2905       for (int i = 0; i < ch; ++i)
2906             data[i] = buffer[i % channels()];
2907       return true;
2908       }
2909 
2910 //---------------------------------------------------------
2911 //   setChannels
2912 //---------------------------------------------------------
2913 
setChannels(int n)2914 void AudioAux::setChannels(int n)
2915 {
2916   const int old_chans = channels();
2917   AudioTrack::setChannels(n);
2918   const int new_chans = channels();
2919   if(new_chans > old_chans)
2920   {
2921     for(int i = old_chans; i < new_chans; ++i)
2922     {
2923 #ifdef _WIN32
2924       buffer[i] = (float *) _aligned_malloc(16, sizeof(float) * MusEGlobal::segmentSize);
2925       if(buffer[i] == NULL)
2926       {
2927         fprintf(stderr, "ERROR: AudioTrack::setChannels: _aligned_malloc returned error: NULL. Aborting!\n");
2928         abort();
2929       }
2930 #else
2931       int rv = posix_memalign((void**)(buffer + i), 16, sizeof(float) * MusEGlobal::segmentSize);
2932       if(rv != 0)
2933       {
2934         fprintf(stderr, "ERROR: AudioAux::setChannels: posix_memalign returned error:%d. Aborting!\n", rv);
2935         abort();
2936       }
2937 #endif
2938       if(MusEGlobal::config.useDenormalBias)
2939       {
2940         for(unsigned q = 0; q < MusEGlobal::segmentSize; ++q)
2941           buffer[i][q] = MusEGlobal::denormalBias;
2942       }
2943       else
2944         memset(buffer[i], 0, sizeof(float) * MusEGlobal::segmentSize);
2945     }
2946   }
2947   else if(new_chans < old_chans)
2948   {
2949     for(int i = new_chans; i < old_chans; ++i)
2950     {
2951       if(buffer[i])
2952         free(buffer[i]);
2953     }
2954   }
2955 }
2956 
2957 //---------------------------------------------------------
2958 //   setRecordFlag1
2959 //    gui part (executed in gui thread)
2960 //---------------------------------------------------------
2961 
setRecordFlag1(bool f)2962 bool AudioTrack::setRecordFlag1(bool f)
2963       {
2964       if(!canRecord())
2965             return false;
2966       if (f == _recordFlag)
2967             return true;
2968       if (f) {
2969         if (_recFile.isNull() && MusEGlobal::song->record()) {
2970           // this rec-enables a track if the global arm already was done
2971           // the standard case would be that rec-enable be done there
2972           prepareRecording();
2973         }
2974 
2975       }
2976       else {
2977             if (_recFile) {
2978               // this file has not been processed and can be
2979               // deleted
2980               // We should only arrive here if going from a 'record-armed' state
2981               //  to a non record-armed state. Because otherwise after actually
2982               //  recording, the _recFile pointer is made into an event,
2983               //  then _recFile is made zero before this function is called.
2984               QString s = _recFile->path();
2985               setRecFile(nullptr);
2986 
2987               remove(s.toLatin1().constData());
2988               if(MusEGlobal::debugMsg)
2989                 printf("AudioNode::setRecordFlag1: remove file %s if it exists\n", s.toLatin1().constData());
2990             }
2991           }
2992       return true;
2993       }
2994 
2995 
2996 //---------------------------------------------------------
2997 //   prepareRecording
2998 //     normally called from MusEGlobal::song->setRecord to defer creating
2999 //     wave files until MusE is globally rec-enabled
3000 //     also called from track->setRecordFlag (above)
3001 //     if global rec enable already was done
3002 //---------------------------------------------------------
prepareRecording()3003 bool AudioTrack::prepareRecording()
3004 {
3005       if(MusEGlobal::debugMsg)
3006         printf("prepareRecording for track %s\n", name().toLatin1().constData());
3007 
3008       if (_recFile.isNull()) {
3009             //
3010             // create soundfile for recording
3011             //
3012             const QString fbase = QString("%1/").arg(MusEGlobal::museProject) +
3013                                   QObject::tr("TRACK") +
3014                                   QString("_%1_").arg(name().simplified().replace(" ","_")) +
3015                                   QObject::tr("TAKE");
3016             QFile fil;
3017             for (;;++recFileNumber) {
3018                fil.setFileName(fbase + QString("_%1.wav").arg(recFileNumber));
3019                if (!fil.exists())
3020                   break;
3021                   }
3022             _recFile = new MusECore::SndFile(fil.fileName());
3023 
3024             _recFile->setFormat(
3025                SF_FORMAT_WAV | SF_FORMAT_FLOAT,
3026                _channels, MusEGlobal::sampleRate);
3027       }
3028 
3029       if (MusEGlobal::debugMsg)
3030           printf("AudioTrack::prepareRecording: init internal file %s\n", _recFile->path().toLatin1().constData());
3031 
3032       if(_recFile->openWrite())
3033             {
3034             QMessageBox::critical(NULL, "MusE write error.", "Error creating target wave file\n"
3035                                                             "Check your configuration.");
3036             return false;
3037 
3038             }
3039 
3040       // For bounce operations: Reset these.
3041       _recFilePos = 0;
3042       _previousLatency = 0.0f;
3043 
3044       return true;
3045 }
auxSend(int idx) const3046 double AudioTrack::auxSend(int idx) const
3047       {
3048       if (unsigned(idx) >= _auxSend.size()) {
3049             printf("%s auxSend: bad index: %d >= %zd\n",
3050                name().toLatin1().constData(), idx, _auxSend.size());
3051             return 0.0;
3052             }
3053       return _auxSend[idx];
3054       }
3055 
setAuxSend(int idx,double v)3056 void AudioTrack::setAuxSend(int idx, double v)
3057       {
3058       if (unsigned(idx) >= _auxSend.size()) {
3059             printf("%s setAuxSend: bad index: %d >= %zd\n",
3060                name().toLatin1().constData(), idx, _auxSend.size());
3061             return;
3062             }
3063       _auxSend[idx] = v;
3064       }
3065 
3066 //---------------------------------------------------------
3067 //   height
3068 //---------------------------------------------------------
height() const3069 int AudioOutput::height() const
3070 {
3071   if (_isVisible)
3072     return _height;
3073   return 0;
3074 }
height() const3075 int AudioInput::height() const
3076 {
3077   if (_isVisible)
3078     return _height;
3079   return 0;
3080 }
height() const3081 int AudioAux::height() const
3082 {
3083   if (_isVisible)
3084     return _height;
3085   return 0;
3086 }
height() const3087 int AudioGroup::height() const
3088 {
3089   if (_isVisible)
3090     return _height;
3091   return 0;
3092 }
3093 
height() const3094 int WaveTrack::height() const
3095 {
3096   if (_isVisible)
3097     return _height;
3098   return 0;
3099 }
3100 
3101 } // namespace MusECore
3102