diff options
Diffstat (limited to 'muse_qt4_evolution/muse/track.cpp')
-rw-r--r-- | muse_qt4_evolution/muse/track.cpp | 1062 |
1 files changed, 1062 insertions, 0 deletions
diff --git a/muse_qt4_evolution/muse/track.cpp b/muse_qt4_evolution/muse/track.cpp new file mode 100644 index 00000000..93d92ac1 --- /dev/null +++ b/muse_qt4_evolution/muse/track.cpp @@ -0,0 +1,1062 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "track.h" +#include "song.h" +#include "al/tempo.h" +#include "al/xml.h" +#include "icons.h" +#include "audio.h" +#include "gconfig.h" +#include "midictrl.h" +#include "part.h" +#include "gui.h" +#include "audiodev.h" + +// synchronize with TrackType!: + +const char* Track::_cname[] = { + "AudioOut", "Group", "Wave", "AudioIn", + "Synth", "Midi", "MidiOut", "MidiIn", "M-Synth" + }; + +const char* Track::_clname[] = { + "Audio Output", "Audio Group", "Wave Track", "Audio Input", + "Synti", "Midi Track", "Midi Output", "Midi Input", + "Midi Synth" + }; + +//--------------------------------------------------------- +// ArrangerTrack +//--------------------------------------------------------- + +ArrangerTrack::ArrangerTrack() + { + tw = 0; + ctrl = -1; // first ctrl in list + controller = 0; + h = defaultTrackHeight; + } + +//--------------------------------------------------------- +// ccolor +// return track specific track background color +//--------------------------------------------------------- + +QColor Track::ccolor() const + { + return config.trackBg[type()]; + } + +//--------------------------------------------------------- +// pixmap +//--------------------------------------------------------- + +QPixmap* Track::pixmap(TrackType t) + { + switch(t) { + case AUDIO_OUTPUT: return addtrack_audiooutputIcon; + case AUDIO_GROUP: return addtrack_audiogroupIcon; + case WAVE: return addtrack_wavetrackIcon; + case AUDIO_INPUT: return addtrack_audioinputIcon; + case AUDIO_SOFTSYNTH: return addtrack_audioinputIcon; // DEBUG + default: + case MIDI: return addtrack_addmiditrackIcon; + case MIDI_OUT: return addtrack_addmiditrackIcon; + case MIDI_IN: return addtrack_addmiditrackIcon; + } + } + +//--------------------------------------------------------- +// Track +//--------------------------------------------------------- + +Track::Track() + { + _tt = AL::TICKS; + _recordFlag = false; + _monitor = false; + _mute = false; + _solo = false; + _off = false; + _channels = 0; // 1 - mono, 2 - stereo + _selected = false; + _locked = false; + _autoRead = autoReadDefault(); + _autoWrite = autoWriteDefault(); + + for (int i = 0; i < MAX_CHANNELS; ++i) { + _meter[i] = 0.0f; + _peak[i] = 0.0f; + _peakTimer[i] = 0; + } + _sendSync = false; + _deviceId = 127; + _parts = new PartList; + } + +//--------------------------------------------------------- +// ~Track +//--------------------------------------------------------- + +Track::~Track() + { + delete _parts; + + for (int i = 0; i < MAX_CHANNELS; ++i) { +// if (!_alsaPort[i].isZero()) +// midiDriver->unregisterPort(_alsaPort[i]); + if (!_jackPort[i].isZero()) + audioDriver->unregisterPort(_jackPort[i]); + } + + } + +//--------------------------------------------------------- +// setDefaultName +// generate unique name for track +//--------------------------------------------------------- + +void Track::setDefaultName() + { + QString base; + switch(type()) { + case MIDI: + case WAVE: + base = QString("Track"); + break; + case AUDIO_GROUP: + base = QString("Group"); + break; + case AUDIO_SOFTSYNTH: + // base = QString("Synth"); + return; + case AUDIO_OUTPUT: + case AUDIO_INPUT: + case MIDI_OUT: + case MIDI_IN: + case MIDI_SYNTI: + case TRACK_TYPES: + base = cname(); + break; + }; + // + // create unique name + // + for (int i = 1;; ++i) { + QString s; + if (i == 1) + s = base; + else + s = QString("%1 %2").arg(base).arg(i); + bool found = false; + TrackList* tl = song->tracks(); + for (iTrack it = tl->begin(); it != tl->end(); ++it) { + Track* track = *it; + if (track->name() == s) { + found = true; + break; + } + } + if (!found) { + setName(s); + break; + } + } + } + +//--------------------------------------------------------- +// dump +//--------------------------------------------------------- + +void Track::dump() const + { + printf("Track <%s>: typ %d, parts %zd sel %d\n", + _name.toLatin1().data(), type(), _parts->size(), _selected); + } + +//--------------------------------------------------------- +// addPart +//--------------------------------------------------------- + +void Track::addPart(Part* p) + { + p->setTrack(this); + _parts->add(p); + } + +//--------------------------------------------------------- +// findPart +//--------------------------------------------------------- + +Part* Track::findPart(unsigned tick) + { + for (iPart i = _parts->begin(); i != _parts->end(); ++i) { + Part* part = i->second; + if (tick >= part->tick() && tick < (part->tick()+part->lenTick())) + return part; + } + return 0; + } + +//--------------------------------------------------------- +// Track::writeProperties +//--------------------------------------------------------- + +void Track::writeProperties(Xml& xml) const + { + xml.tag("name", _name); + if (!_comment.isEmpty()) + xml.tag("comment", _comment); + if (_recordFlag) + xml.tag("record", _recordFlag); + if (mute() != muteDefault()) + xml.tag("mute", mute()); + if (solo()) + xml.tag("solo", solo()); + if (off()) + xml.tag("off", off()); + if (_channels) + xml.tag("channels", _channels); + if (_locked) + xml.tag("locked", _locked); + if (_monitor) + xml.tag("monitor", _monitor); + if (_autoRead != autoReadDefault()) + xml.tag("autoRead", _autoRead); + if (_autoWrite != autoWriteDefault()) + xml.tag("autoWrite", _autoWrite); + if (_selected) + xml.tag("selected", _selected); + for (ciCtrl icl = controller()->begin(); icl != controller()->end(); ++icl) + icl->second->write(xml); + if (arrangerTrack.tw) + xml.tag("height", arrangerTrack.tw->height()); + for (ciArrangerTrack i = subtracks.begin(); i != subtracks.end(); ++i) { + xml.stag("subtrack"); + xml.tag("height", (*i)->tw->height()); + xml.tag("ctrl", (*i)->ctrl); + xml.etag("subtrack"); + } + } + +//--------------------------------------------------------- +// Track::readProperties +//--------------------------------------------------------- + +bool Track::readProperties(QDomNode node) + { + QDomElement e = node.toElement(); + QString tag(e.tagName()); + QString s(e.text()); + int i = s.toInt(); + + if (tag == "name") + setName(s); + else if (tag == "comment") + _comment = s; + else if (tag == "record") { + bool recordFlag = i; + setRecordFlag(recordFlag); + } + else if (tag == "mute") + _mute = i; + else if (tag == "solo") + _solo = i; + else if (tag == "off") + _off = i; + else if (tag == "channels") + _channels = i; + else if (tag == "locked") + _locked = i; + else if (tag == "monitor") + _monitor = i; + else if (tag == "selected") + _selected = i; + else if (tag == "autoRead") + _autoRead = i; + else if (tag == "autoWrite") + _autoWrite = i; + else if (tag == "controller") { + Ctrl* l = new Ctrl(); + l->read(node, false); + + iCtrl icl = controller()->find(l->id()); + if (icl == controller()->end()) + controller()->add(l); + else { //??? + Ctrl* d = icl->second; + for (iCtrlVal i = l->begin(); i != l->end(); ++i) + d->insert(i.key(), i.value()); + d->setCurVal(l->curVal()); + d->setDefault(l->getDefault()); + delete l; + } + } + else if (tag == "height") + arrangerTrack.h = i < minTrackHeight ? minTrackHeight : i; + else if (tag == "subtrack") { + ArrangerTrack* st = new ArrangerTrack; + for (QDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling()) { + QDomElement e = n.toElement(); + QString tag = e.tagName(); + QString s = e.text(); + int i = s.toInt(); + if (tag == "height") + st->h = i; + else if (tag == "ctrl") { + st->ctrl = i; + } + else + printf("Track::subtrack: unknown tag <%s>\n", tag.toLatin1().data()); + } + subtracks.push_back(st); + } + else + return true; + return false; + } + +//--------------------------------------------------------- +// addController +//--------------------------------------------------------- + +void Track::addController(Ctrl* list) + { + iCtrl i = controller()->find(list->id()); + if (i != controller()->end()) { + // printf("%s(%s)::addController(%s): already there 0x%x\n", + // cname().toLatin1().data(), name().toLatin1().data(), list->name().toLatin1().data(), list->id()); + // abort(); + return; + } + controller()->add(list); + emit clChanged(); + } + +//--------------------------------------------------------- +// addMidiController +//--------------------------------------------------------- + +void Track::addMidiController(MidiInstrument* mi, int ctrl) + { + iCtrl cl = _controller.find(ctrl); + if (cl != _controller.end()) + return; + + MidiController* mc = mi->midiController(ctrl); + Ctrl* pvl; + if (mc) { + pvl = new Ctrl(mc); + } + else { + printf("unknown midi controller %x\n", ctrl); + pvl = new Ctrl(ctrl, QString("unknown")); + pvl->setCurVal(CTRL_VAL_UNKNOWN); + pvl->setType(Ctrl::DISCRETE | Ctrl::INT); + } + addController(pvl); + } + +//--------------------------------------------------------- +// removeController +//--------------------------------------------------------- + +void Track::removeController(int id) + { + iCtrl i = controller()->find(id); + if (i == controller()->end()) { + printf("Track::removeController id 0x%x not found, listsize %zd\n", + id, controller()->size()); + return; + } + controller()->erase(i); + emit clChanged(); + } + +//--------------------------------------------------------- +// changeCtrlName +//--------------------------------------------------------- + +void Track::changeCtrlName(Ctrl* c, const QString& s) + { + c->setName(s); + emit clChanged(); + } + +//--------------------------------------------------------- +// addControllerVal +// return true if new controller value added +//--------------------------------------------------------- + +bool Track::addControllerVal(int id, unsigned time, CVal val) + { + iCtrl i = controller()->find(id); + if (i == controller()->end()) { + if ((id & 0xf0000) == CTRL_NRPN_OFFSET) { + int msb = id & 0xff00; + // int lsb = id & 0xff; + int nid = CTRL_NRPN_OFFSET + msb + 0xff; + i = controller()->find(nid); + if (i != controller()->end()) { + Ctrl* c = new Ctrl(*(i->second)); + c->setId(id); + addController(c); +// printf("add pitch ctrl %x\n", id); + return c->add(time, val); + } + } + printf("Track::addControllerVal(): id 0x%x not found, listsize %zd\n", + id, controller()->size()); + return false; + } + return i->second->add(time, val); + } + +//--------------------------------------------------------- +// removeControllerVal +//--------------------------------------------------------- + +void Track::removeControllerVal(int id, unsigned time) + { + iCtrl i = controller()->find(id); + if (i == controller()->end()) { + printf("Track::removeControllerVal(): id 0x%x not found, listsize %zd\n", + id, controller()->size()); + return; + } + i->second->del(time); + } + +//--------------------------------------------------------- +// getController +//--------------------------------------------------------- + +Ctrl* Track::getController(int id) const + { + ciCtrl i = controller()->find(id); + if (i == controller()->end()) { +// printf("%s(%s)::getController(%d) size %d: not found\n", +// cname().toLatin1().data(), name().toLatin1().data(), id, controller()->size()); +// const CtrlList* cl = controller(); +// for (ciCtrl i = cl->begin(); i != cl->end(); ++i) +// printf(" Ctrl %d\n", i->first); + return 0; + } + return i->second; + } + +//--------------------------------------------------------- +// controllerNames +//--------------------------------------------------------- + +ControllerNameList* Track::controllerNames() const + { + ControllerNameList* l = new ControllerNameList; + for (ciCtrl i = controller()->begin(); i != controller()->end(); ++i) + l->push_back(ControllerName(i->second->name(), i->second->id())); + return l; + } + +//--------------------------------------------------------- +// setRecordFlag +//--------------------------------------------------------- + +void Track::setRecordFlag(bool f) + { + if (_recordFlag != f) { + _recordFlag = f; + emit recordChanged(_recordFlag); + } + } + +//--------------------------------------------------------- +// setMonitor +//--------------------------------------------------------- + +void Track::setMonitor(bool f) + { + if (_monitor != f) { + _monitor = f; + emit monitorChanged(_monitor); + } + } + +//--------------------------------------------------------- +// setSelected +//--------------------------------------------------------- + +void Track::setSelected(bool f) + { + if (f != _selected) { + _selected = f; + emit selectionChanged(_selected); +// muse->selectionChanged(); + } + } + +//--------------------------------------------------------- +// setController +// called from GUI +//--------------------------------------------------------- + +#if 0 +void Track::setController(Pos pos, int id, int v) + { + CVal val; + val.i = v; + setController(pos, id, val); + } + +void Track::setController(Pos pos, int id, double v) + { + CVal val; + val.f = v; + setController(pos, id, val); + } + +void Track::setController(Pos pos, int id, CVal val) + { + Ctrl* c = getController(id); + if (c == 0) { + printf("no controller 0x%x %s\n", id, name().toLatin1().data()); + return; + } + if (isMidiTrack()) { + int port = ((MidiTrack*)this)->outPort(); + int channel = ((MidiTrack*)this)->outChannel(); + MidiEvent ev(0, port, channel, ME_CONTROLLER, id, val.i); + audio->msgPlayMidiEvent(&ev); + } + else { + // non midi controller are current once set + c->setCurVal(val); + } + c->setSchedVal(val); + if (autoWrite()) { + unsigned time = _tt == AL::FRAMES ? pos.frame() : pos.tick(); + if (audio->isPlaying()) + _recEvents.push_back(CtrlRecVal(time, id, val)); + else + song->addControllerVal(this, c, id, time, val); + } + emit controllerChanged(id); + } +#endif + +//--------------------------------------------------------- +// startAutoRecord +// slider/knob touched +//--------------------------------------------------------- + +void Track::startAutoRecord(int n) + { + Ctrl* ctrl = getController(n); + if (ctrl) { + ctrl->setTouched(true); + if (audio->isPlaying() && autoWrite()) + _recEvents.push_back(CtrlRecVal(song->cPos().frame(), n, 1)); + } + else + printf("no ctrl 0x%x\n", n); + } + +//--------------------------------------------------------- +// stopAutoRecord +// slider/knob released +//--------------------------------------------------------- + +void Track::stopAutoRecord(int n) + { + Ctrl* ctrl = getController(n); + if (ctrl) { + ctrl->setTouched(false); + if (audio->isPlaying() && autoWrite()) + _recEvents.push_back(CtrlRecVal(song->cPos().frame(), n, 2)); + } + else + printf("no ctrl 0x%x\n", n); + } + +//--------------------------------------------------------- +// setName +//--------------------------------------------------------- + +void Track::setName(const QString& s) + { + _name = s; + emit nameChanged(_name); + } + +//--------------------------------------------------------- +// setAutoRead +//--------------------------------------------------------- + +void Track::setAutoRead(bool val) + { + if (_autoRead != val) { + _autoRead = val; + emit autoReadChanged(_autoRead); + } + } + +//--------------------------------------------------------- +// setAutoWrite +//--------------------------------------------------------- + +void Track::setAutoWrite(bool val) + { + if (_autoWrite != val) { + _autoWrite = val; + emit autoWriteChanged(_autoWrite); + } + } + +//--------------------------------------------------------- +// cpos +//--------------------------------------------------------- + +unsigned Track::cpos() const + { + return timeType() == AL::TICKS ? song->cPos().tick() : song->cPos().frame(); + } + +//--------------------------------------------------------- +// updateController +//--------------------------------------------------------- + +void Track::updateController() + { + CtrlList* cl = controller(); + for (iCtrl i = cl->begin(); i != cl->end(); ++i) { + Ctrl* c = i->second; + if (c->changed()) { + c->setChanged(false); + emit controllerChanged(c->id()); + } + } + } + +//--------------------------------------------------------- +// writeRouting +//--------------------------------------------------------- + +void Track::writeRouting(Xml& xml) const + { + if (type() == AUDIO_INPUT || type() == MIDI_IN) { + foreach(Route r, _inRoutes) { + xml.stag("Route"); + r.src.write(xml, "src"); + r.dst.write(xml, "dst"); + xml.etag("Route"); + } + } + foreach(Route r, _outRoutes) { + xml.stag("Route"); + r.src.write(xml, "src"); + r.dst.write(xml, "dst"); + xml.etag("Route"); + } + } + +//--------------------------------------------------------- +// hwCtrlState +//--------------------------------------------------------- + +int Track::hwCtrlState(int ctrl) const + { + ciCtrl cl = _controller.find(ctrl); + if (cl == _controller.end()) { + if (debugMsg) + printf("hwCtrlState: ctrl 0x%x not found\n", ctrl); + return CTRL_VAL_UNKNOWN; + } + Ctrl* vl = cl->second; + return vl->curVal().i; + } + +//--------------------------------------------------------- +// setHwCtrlState +//--------------------------------------------------------- + +void Track::setHwCtrlState(int ctrl, int val) + { + iCtrl cl = _controller.find(ctrl); + if (cl == _controller.end()) { + // try to add new controller + if (debugMsg) + printf("setHwCtrlState(0x%x,0x%x): not found\n", ctrl, val); + return; + } + Ctrl* vl = cl->second; +// printf("setHwCtrlState ctrl %x val %x\n", ctrl, val); + vl->setChanged(true); + return vl->setCurVal(val); + } + +//--------------------------------------------------------- +// getCtrl +//--------------------------------------------------------- + +int Track::getCtrl(int tick, int ctrl) const + { + ciCtrl cl = _controller.find(ctrl); + if (cl == _controller.end()) { + if (debugMsg) + printf("getCtrl: controller %d(0x%x) not found %zd\n", + ctrl, ctrl, _controller.size()); + return CTRL_VAL_UNKNOWN; + } + return cl->second->value(tick).i; + } + +//--------------------------------------------------------- +// setSolo +//--------------------------------------------------------- + +bool Track::setSolo(bool val) + { + if (_solo != val) { + _solo = val; + emit soloChanged(_solo); + return true; + } + return false; + } + +//--------------------------------------------------------- +// setMute +// return true if mute changed +//--------------------------------------------------------- + +bool Track::setMute(bool val) + { + if (_mute != val) { + _mute = val; + emit muteChanged(_mute); + return true; + } + return false; + } + +//--------------------------------------------------------- +// setOff +// return true if state changed +//--------------------------------------------------------- + +bool Track::setOff(bool val) + { + if (_off != val) { + _off = val; + emit offChanged(_off); + return true; + } + return false; + } + +//--------------------------------------------------------- +// setChannels +//--------------------------------------------------------- + +void Track::setChannels(int n) + { + _channels = n; + for (int i = 0; i < _channels; ++i) { + _meter[i] = 0.0f; + _peak[i] = 0.0f; + } + } + +//--------------------------------------------------------- +// resetMeter +//--------------------------------------------------------- + +void Track::resetMeter() + { + for (int i = 0; i < _channels; ++i) + _meter[i] = 0.0f; + } + +//--------------------------------------------------------- +// resetPeaks +//--------------------------------------------------------- + +void Track::resetPeaks() + { + for (int i = 0; i < _channels; ++i) + _peak[i] = 0; + } + +//--------------------------------------------------------- +// resetAllMeter +//--------------------------------------------------------- + +void Track::resetAllMeter() + { + TrackList* tl = song->tracks(); + for (iTrack i = tl->begin(); i != tl->end(); ++i) + (*i)->resetMeter(); + } + +//--------------------------------------------------------- +// activate1 +// register JACK and ALSA ports +//--------------------------------------------------------- + +void Track::activate1() + { + if (isMidiTrack()) { + if (!jackPort(0).isZero()) + printf("Track::activate1() midi: jack port already active!\n"); + if (type() == MIDI_OUT) { + _jackPort[0] = audioDriver->registerOutPort(_name, true); + } + else if (type() == MIDI_IN) { + _jackPort[0] = audioDriver->registerInPort(_name, true); + } + return; + } + + for (int i = 0; i < channels(); ++i) { + if (!jackPort(i).isZero()) + printf("Track<%s>::activate1(): channel %d already active!\n", + name().toLatin1().data(), i); + else { + QString s(QString("%1-%2").arg(_name).arg(i)); + if (type() == AUDIO_OUTPUT) + _jackPort[i] = audioDriver->registerOutPort(s, false); + else if (type() == AUDIO_INPUT) + _jackPort[i] = audioDriver->registerInPort(s, false); + } + } + } + +//--------------------------------------------------------- +// activate2 +// connect all JACK/ALSA in/out routes +// connect to JACK only works if JACK is running +//--------------------------------------------------------- + +void Track::activate2() + { + if (audioState != AUDIO_RUNNING) { + printf("Track::activate2(): no audio running !\n"); + abort(); + } + foreach(Route r, _outRoutes) { + if (r.dst.type == RouteNode::JACKMIDIPORT) { + audioDriver->connect(_jackPort[0], r.dst.port); + r.disconnected = false; + } + else if (r.dst.type == RouteNode::AUDIOPORT) { + audioDriver->connect(_jackPort[r.src.channel], r.dst.port); + r.disconnected = false; + } + } + foreach(Route r, _inRoutes) { + if (r.src.type == RouteNode::JACKMIDIPORT) { + audioDriver->connect(r.src.port, _jackPort[0]); + r.disconnected = false; + } + else if (r.src.type == RouteNode::AUDIOPORT) { + audioDriver->connect(r.src.port, _jackPort[r.dst.channel]); + r.disconnected = false; + } + } + } + +//--------------------------------------------------------- +// deactivate +// disconnect and unregister JACK and ALSA ports +//--------------------------------------------------------- + +void Track::deactivate() + { +// printf("deactivate<%s>\n", name().toLatin1().data()); + foreach(Route r, _outRoutes) { + if (r.dst.type == RouteNode::JACKMIDIPORT) { + r.disconnected = true; + audioDriver->disconnect(_jackPort[0], r.dst.port); + } + else if (r.dst.type == RouteNode::AUDIOPORT) { + audioDriver->disconnect(_jackPort[r.src.channel], r.dst.port); + r.disconnected = true; + } + } + foreach(Route r, _inRoutes) { + if (r.src.type == RouteNode::JACKMIDIPORT) { + r.disconnected = true; + audioDriver->disconnect(r.src.port, _jackPort[0]); + } + else if (r.src.type == RouteNode::AUDIOPORT) { + r.disconnected = true; + audioDriver->disconnect(r.src.port, _jackPort[r.dst.channel]); + } + } + for (int i = 0; i < channels(); ++i) { + if (!_jackPort[i].isZero()) { + audioDriver->unregisterPort(_jackPort[i]); + _jackPort[i].setZero(); + } + } + } + +//--------------------------------------------------------- +// setSendSync +//--------------------------------------------------------- + +void Track::setSendSync(bool val) + { + _sendSync = val; + emit sendSyncChanged(val); + } + +//--------------------------------------------------------- +// splitPart +// split part "part" at "tick" position +// create two new parts p1 and p2 +//--------------------------------------------------------- + +void Track::splitPart(Part* part, int tickpos, Part*& p1, Part*& p2) + { + int l1 = 0; // len of first new part (ticks or samples) + int l2 = 0; // len of second new part + + int samplepos = AL::tempomap.tick2frame(tickpos); + + switch (type()) { + case WAVE: + l1 = samplepos - part->frame(); + l2 = part->lenFrame() - l1; + break; + case MIDI: + l1 = tickpos - part->tick(); + l2 = part->lenTick() - l1; + break; + default: + return; + } + + if (l1 <= 0 || l2 <= 0) + return; + + p1 = newPart(part); // new left part + p2 = newPart(part); // new right part + + switch (type()) { + case WAVE: + p1->setLenFrame(l1); + p2->setFrame(samplepos); + p2->setLenFrame(l2); + break; + case MIDI: + p1->setLenTick(l1); + p2->setTick(tickpos); + p2->setLenTick(l2); + break; + default: + break; + } + + EventList* se = part->events(); + EventList* de1 = p1->events(); + EventList* de2 = p2->events(); + + if (type() == WAVE) { + int ps = part->frame(); + int d1p1 = p1->frame(); + int d2p1 = p1->endFrame(); + int d1p2 = p2->frame(); + int d2p2 = p2->endFrame(); + for (iEvent ie = se->begin(); ie != se->end(); ++ie) { + Event event = ie->second; + int s1 = event.frame() + ps; + int s2 = event.endFrame() + ps; + + if ((s2 > d1p1) && (s1 < d2p1)) { + Event si = event.mid(d1p1 - ps, d2p1 - ps); + de1->add(si); + } + if ((s2 > d1p2) && (s1 < d2p2)) { + Event si = event.mid(d1p2 - ps, d2p2 - ps); + si.setFrame(si.frame() - l1); //?? + si.setFrame(0); //?? + de2->add(si); + } + } + } + else { + for (iEvent ie = se->begin(); ie != se->end(); ++ie) { + Event event = ie->second.clone(); + int t = event.tick(); + if (t >= l1) { + event.move(-l1); + de2->add(event); + } + else + de1->add(event); + } + } + } + +//--------------------------------------------------------- +// addInRoute +//--------------------------------------------------------- + +void Track::addInRoute(const Route& r) + { + if (_inRoutes.indexOf(r) != -1) { + printf("Track::addInRoute: route already there\n"); + return; + } + _inRoutes.push_back(r); + } + +//--------------------------------------------------------- +// addOutRoute +//--------------------------------------------------------- + +void Track::addOutRoute(const Route& r) + { + if (_outRoutes.indexOf(r) != -1) { + printf("Track::addOutRoute: route already there\n"); + return; + } + _outRoutes.push_back(r); + } + +//--------------------------------------------------------- +// inRouteExists +//--------------------------------------------------------- + +bool Track::inRouteExists(const Route& r) const + { + return _inRoutes.indexOf(r) != -1; + } + +//--------------------------------------------------------- +// outRouteExists +//--------------------------------------------------------- + +bool Track::outRouteExists(const Route& r) const + { + return _outRoutes.indexOf(r) != -1; + } + |