1
//=========================================================
4
// $Id: audiotrack.cpp,v 1.14 2004/07/14 15:27:26 wschweer Exp $
6
// (C) Copyright 2004 Werner Schweer (ws@seh.de)
7
//=========================================================
20
//---------------------------------------------------------
22
//---------------------------------------------------------
24
AudioTrack::AudioTrack(TrackType t)
28
_efxPipe = new Pipeline();
31
_automationType = AUTO_READ;
33
addController(new CtrlList(AC_VOLUME));
34
addController(new CtrlList(AC_PAN));
35
outBuffers = new float*[2];
36
for (int i = 0; i < MAX_CHANNELS; ++i)
37
outBuffers[i] = new float[segmentSize];
41
AudioTrack::AudioTrack(const AudioTrack& t)
44
_controller = t._controller;
45
_prefader = t._prefader;
46
_auxSend = t._auxSend;
47
_efxPipe = new Pipeline(*(t._efxPipe));
48
_automationType = t._automationType;
49
_inRoutes = t._inRoutes;
50
_outRoutes = t._outRoutes;
51
outBuffers = new float*[MAX_CHANNELS];
52
for (int i = 0; i < MAX_CHANNELS; ++i)
53
outBuffers[i] = new float[segmentSize];
55
_recFile = t._recFile;
58
AudioTrack::~AudioTrack()
61
for (int i = 0; i < MAX_CHANNELS; ++i)
62
delete[] outBuffers[i];
66
//---------------------------------------------------------
68
//---------------------------------------------------------
70
Part* AudioTrack::newPart(Part*, bool /*clone*/)
75
//---------------------------------------------------------
77
//---------------------------------------------------------
79
void AudioTrack::addPlugin(PluginI* plugin, int idx)
82
PluginI* oldPlugin = (*_efxPipe)[idx];
84
int controller = oldPlugin->parameters();
85
for (int i = 0; i < controller; ++i) {
86
int id = (idx + 1) * 0x1000 + i;
91
efxPipe()->insert(plugin, idx);
93
int controller = plugin->parameters();
94
for (int i = 0; i < controller; ++i) {
95
int id = (idx + 1) * 0x1000 + i;
96
const char* name = plugin->paramName(i);
98
plugin->range(i, &min, &max);
99
CtrlValueType t = plugin->valueType();
100
CtrlList* cl = new CtrlList(id);
101
cl->setRange(min, max);
102
cl->setName(QString(name));
109
//---------------------------------------------------------
111
//---------------------------------------------------------
113
void AudioTrack::addAuxSend(int n)
115
int nn = _auxSend.size();
116
for (int i = nn; i < n; ++i) {
117
_auxSend.push_back(0.0);
118
_auxSend[i] = 0.0; //??
122
//---------------------------------------------------------
124
//---------------------------------------------------------
126
void AudioTrack::addController(CtrlList* list)
128
_controller.add(list);
131
//---------------------------------------------------------
133
//---------------------------------------------------------
135
void AudioTrack::removeController(int id)
137
iCtrlList i = _controller.find(id);
138
if (i == _controller.end()) {
139
printf("AudioTrack::removeController id %d not found\n", id);
142
_controller.erase(i);
145
//---------------------------------------------------------
147
//---------------------------------------------------------
149
double AudioTrack::volume() const
151
ciCtrlList cl = _controller.find(AC_VOLUME);
152
if (cl == _controller.end())
154
if (automation && (automationType() == AUTO_READ
155
|| automationType() == AUTO_TOUCH))
156
return cl->second->value(song->cPos().frame());
158
return cl->second->curVal();
161
//---------------------------------------------------------
163
//---------------------------------------------------------
165
void AudioTrack::setVolume(double val)
167
iCtrlList cl = _controller.find(AC_VOLUME);
168
if (cl == _controller.end()) {
169
printf("no volume controller %s %d\n",
170
name().latin1(), _controller.size());
173
cl->second->setCurVal(val);
176
//---------------------------------------------------------
178
//---------------------------------------------------------
180
double AudioTrack::pan() const
182
ciCtrlList cl = _controller.find(AC_PAN);
183
if (cl == _controller.end())
185
return cl->second->value(song->cPos().frame());
188
//---------------------------------------------------------
190
//---------------------------------------------------------
192
void AudioTrack::setPan(double val)
194
iCtrlList cl = _controller.find(AC_PAN);
195
if (cl == _controller.end()) {
196
printf("no pan controller\n");
199
cl->second->setCurVal(val);
202
void AudioTrack::recordAutomation(int n, float v)
204
if (audio->isPlaying() && automation && automationType() == AUTO_TOUCH || automationType() == AUTO_WRITE)
205
_recEvents.push_back(CtrlRecVal(song->cPos().frame(), n, v));
208
void AudioTrack::startAutoRecord(int n)
210
if (audio->isPlaying() && automation && automationType() == AUTO_TOUCH)
211
_recEvents.push_back(CtrlRecVal(song->cPos().frame(), n, 1));
214
void AudioTrack::stopAutoRecord(int n)
216
if (audio->isPlaying() && automation && automationType() == AUTO_TOUCH)
217
_recEvents.push_back(CtrlRecVal(song->cPos().frame(), n, 2));
220
//---------------------------------------------------------
221
// AudioTrack::writeProperties
222
//---------------------------------------------------------
224
void AudioTrack::writeProperties(int level, Xml& xml) const
226
Track::writeProperties(level, xml);
227
xml.intTag(level, "prefader", prefader());
228
xml.intTag(level, "automation", int(automationType()));
230
int naux = song->auxs()->size();
231
for (int idx = 0; idx < naux; ++idx) {
232
QString s("<auxSend idx=%1>%2</auxSend>\n");
233
xml.nput(level, s.arg(idx).arg(_auxSend[idx]));
236
for (ciPluginI ip = _efxPipe->begin(); ip != _efxPipe->end(); ++ip) {
238
(*ip)->writeConfiguration(level, xml);
240
for (ciCtrlList icl = _controller.begin(); icl != _controller.end(); ++icl) {
241
const CtrlList* cl = icl->second;
242
QString s("controller id=\"%1\" cur=\"%2\"");
243
xml.tag(level++, s.arg(cl->id()).arg(cl->curVal()));
245
for (ciCtrl ic = cl->begin(); ic != cl->end(); ++ic) {
246
QString s("%1 %2, ");
247
xml.nput(level, s.arg(ic->second.frame).arg(ic->second.val));
256
xml.etag(level--, "controller");
260
//---------------------------------------------------------
262
//---------------------------------------------------------
264
void AudioTrack::readAuxSend(Xml& xml)
269
Xml::Token token = xml.parse();
270
const QString& tag = xml.s1();
277
idx = xml.s2().toInt();
280
val = tag.toDouble();
283
if (xml.s1() == "auxSend") {
284
if (_auxSend.size() < idx+1)
285
_auxSend.push_back(val);
296
//---------------------------------------------------------
297
// AudioTrack::readProperties
298
//---------------------------------------------------------
300
bool AudioTrack::readProperties(Xml& xml, const QString& tag)
302
if (tag == "plugin") {
303
PluginI* pi = new PluginI;
304
if (pi->readConfiguration(xml, false)) {
308
// insert plugin into first free slot
311
for (i = 0; i < 4; ++i) {
312
if ((*_efxPipe)[i] == 0) {
318
printf("internal error: too many plugins\n");
322
else if (tag == "auxSend")
324
else if (tag == "prefader")
325
_prefader = xml.parseInt();
326
else if (tag == "automation")
327
setAutomationType(AutomationType(xml.parseInt()));
328
else if (tag == "recfile")
330
else if (tag == "controller") {
331
CtrlList* l = new CtrlList();
333
iCtrlList icl = _controller.find(l->id());
334
if (icl == _controller.end())
337
CtrlList* d = icl->second;
338
for (iCtrl i = l->begin(); i != l->end(); ++i)
339
d->insert(std::pair<const int, CtrlVal> (i->first, i->second));
340
d->setCurVal(l->curVal());
341
d->setDefault(l->getDefault());
346
return Track::readProperties(xml, tag);
350
//---------------------------------------------------------
352
//---------------------------------------------------------
354
void AudioTrack::writeRouting(int level, Xml& xml) const
356
if (type() == Track::AUDIO_INPUT) {
357
const RouteList* rl = &_inRoutes;
358
for (ciRoute r = rl->begin(); r != rl->end(); ++r) {
359
Route dst(name(), true, r->channel);
360
xml.tag(level++, "Route");
361
xml.strTag(level, "srcNode", r->name());
362
xml.strTag(level, "dstNode", dst.name());
363
xml.etag(level--, "Route");
366
const RouteList* rl = &_outRoutes;
367
for (ciRoute r = rl->begin(); r != rl->end(); ++r) {
369
if (type() == Track::AUDIO_OUTPUT) {
370
Route s(src, false, r->channel);
373
xml.tag(level++, "Route");
374
xml.strTag(level, "srcNode", src);
375
xml.strTag(level, "dstNode", r->name());
376
xml.etag(level--, "Route");
380
//---------------------------------------------------------
382
//---------------------------------------------------------
384
AudioInput::AudioInput()
385
: AudioTrack(AUDIO_INPUT)
387
// set Default for Input Ports:
390
for (int i = 0; i < MAX_CHANNELS; ++i)
396
AudioInput::AudioInput(const AudioInput& t)
399
for (int i = 0; i < MAX_CHANNELS; ++i)
400
jackPorts[i] = t.jackPorts[i];
403
//---------------------------------------------------------
405
//---------------------------------------------------------
407
AudioInput::~AudioInput()
409
for (int i = 0; i < _channels; ++i)
410
audioDevice->unregisterPort(jackPorts[i]);
413
//---------------------------------------------------------
415
//---------------------------------------------------------
417
void AudioInput::write(int level, Xml& xml) const
419
xml.tag(level++, "AudioInput");
420
AudioTrack::writeProperties(level, xml);
421
xml.etag(level, "AudioInput");
424
//---------------------------------------------------------
426
//---------------------------------------------------------
428
void AudioInput::read(Xml& xml)
431
Xml::Token token = xml.parse();
432
const QString& tag = xml.s1();
438
if (AudioTrack::readProperties(xml, tag))
439
xml.unknown("AudioInput");
444
if (tag == "AudioInput") {
445
setName(name()); // allocate jack ports
454
//---------------------------------------------------------
456
//---------------------------------------------------------
458
AudioOutput::AudioOutput()
459
: AudioTrack(AUDIO_OUTPUT)
461
for (int i = 0; i < MAX_CHANNELS; ++i)
467
AudioOutput::AudioOutput(const AudioOutput& t)
470
for (int i = 0; i < MAX_CHANNELS; ++i)
471
jackPorts[i] = t.jackPorts[i];
472
_nframes = t._nframes;
475
//---------------------------------------------------------
477
//---------------------------------------------------------
479
AudioOutput::~AudioOutput()
481
for (int i = 0; i < _channels; ++i)
482
audioDevice->unregisterPort(jackPorts[i]);
485
//---------------------------------------------------------
487
//---------------------------------------------------------
489
void AudioOutput::write(int level, Xml& xml) const
491
xml.tag(level++, "AudioOutput");
492
AudioTrack::writeProperties(level, xml);
493
xml.etag(level, "AudioOutput");
496
//---------------------------------------------------------
498
//---------------------------------------------------------
500
void AudioOutput::read(Xml& xml)
503
Xml::Token token = xml.parse();
504
const QString& tag = xml.s1();
510
if (AudioTrack::readProperties(xml, tag))
511
xml.unknown("AudioOutput");
516
if (tag == "AudioOutput") {
517
setName(name()); // allocate jack ports
526
//---------------------------------------------------------
528
//---------------------------------------------------------
530
void AudioGroup::write(int level, Xml& xml) const
532
xml.tag(level++, "AudioGroup");
533
AudioTrack::writeProperties(level, xml);
534
xml.etag(level, "AudioGroup");
537
//---------------------------------------------------------
539
//---------------------------------------------------------
541
void AudioGroup::read(Xml& xml)
544
Xml::Token token = xml.parse();
545
const QString& tag = xml.s1();
551
if (AudioTrack::readProperties(xml, tag))
552
xml.unknown("AudioGroup");
557
if (tag == "AudioGroup")
565
//---------------------------------------------------------
567
//---------------------------------------------------------
569
void AudioAux::write(int level, Xml& xml) const
571
xml.tag(level++, "AudioAux");
572
AudioTrack::writeProperties(level, xml);
573
xml.etag(level, "AudioAux");
576
//---------------------------------------------------------
578
//---------------------------------------------------------
581
: AudioTrack(AUDIO_AUX)
585
for (int i = 0; i < MAX_CHANNELS; ++i)
586
buffer[i] = (i < channels()) ? new float[segmentSize] : 0;
589
//---------------------------------------------------------
591
//---------------------------------------------------------
593
AudioAux::~AudioAux()
595
for (int i = 0; i < channels(); ++i)
599
//---------------------------------------------------------
601
//---------------------------------------------------------
603
void AudioAux::read(Xml& xml)
606
Xml::Token token = xml.parse();
607
const QString& tag = xml.s1();
613
if (AudioTrack::readProperties(xml, tag))
614
xml.unknown("AudioAux");
619
if (tag == "AudioAux")
627
//---------------------------------------------------------
629
//---------------------------------------------------------
631
bool AudioAux::getData(unsigned /*pos*/, int ch, unsigned /*samples*/, float** data)
633
for (int i = 0; i < ch; ++i)
634
data[i] = buffer[i % channels()];
638
//---------------------------------------------------------
640
//---------------------------------------------------------
642
void AudioAux::setChannels(int n)
644
if (n > channels()) {
645
for (int i = channels(); i < n; ++i)
646
buffer[i] = new float[segmentSize];
648
else if (n < channels()) {
649
for (int i = n; i < channels(); ++i)
652
AudioTrack::setChannels(n);
655
//---------------------------------------------------------
657
// gui part (executed in gui thread)
658
//---------------------------------------------------------
660
void AudioTrack::setRecordFlag1(bool f)
662
if (f == _recordFlag)
667
// create soundfile for recording
671
for (;;++recFileNumber) {
672
sprintf(buffer, "%s/rec%d.wav",
673
museProject.latin1(),
675
fil.setName(QString(buffer));
679
_recFile = new SndFile(QString(buffer));
681
SF_FORMAT_WAV | SF_FORMAT_FLOAT,
682
_channels, sampleRate);
684
_recFile->openWrite();
686
printf("AudioNode::setRecordFlag1: create internal file %s\n",
687
_recFile->path().latin1());
691
// this file has not been processed and can be
693
QString s = _recFile->path();
696
printf("AudioNode::setRecordFlag1: remove file %s\n", s.latin1());
701
double AudioTrack::auxSend(int idx) const
703
if (unsigned(idx) >= _auxSend.size()) {
704
printf("%s auxSend: bad index: %d >= %d\n",
705
name().latin1(), idx, _auxSend.size());
708
return _auxSend[idx];
711
void AudioTrack::setAuxSend(int idx, double v)
713
if (unsigned(idx) >= _auxSend.size()) {
714
printf("%s setAuxSend: bad index: %d >= %d\n",
715
name().latin1(), idx, _auxSend.size());