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