diff options
Diffstat (limited to 'attic/muse_qt4_evolution/muse/part.cpp')
-rw-r--r-- | attic/muse_qt4_evolution/muse/part.cpp | 361 |
1 files changed, 361 insertions, 0 deletions
diff --git a/attic/muse_qt4_evolution/muse/part.cpp b/attic/muse_qt4_evolution/muse/part.cpp new file mode 100644 index 00000000..61ba561d --- /dev/null +++ b/attic/muse_qt4_evolution/muse/part.cpp @@ -0,0 +1,361 @@ +//============================================================================= +// 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 "song.h" +#include "part.h" +#include "track.h" +#include "globals.h" +#include "event.h" +#include "audio.h" +#include "al/tempo.h" + +const char* partColorNames[] = { + QT_TR_NOOP("Default"), + QT_TR_NOOP("Refrain"), + QT_TR_NOOP("Bridge"), + QT_TR_NOOP("Intro"), + QT_TR_NOOP("Coda"), + QT_TR_NOOP("Chorus"), + QT_TR_NOOP("Solo"), + QT_TR_NOOP("Brass"), + QT_TR_NOOP("Percussion"), + QT_TR_NOOP("Drums"), + QT_TR_NOOP("Guitar"), + QT_TR_NOOP("Bass"), + QT_TR_NOOP("Flute"), + QT_TR_NOOP("Strings"), + QT_TR_NOOP("Keyboard"), + QT_TR_NOOP("Piano"), + QT_TR_NOOP("Saxophon"), + }; + +CloneList cloneList; + +//--------------------------------------------------------- +// Part +//--------------------------------------------------------- + +Part::Part(Track* t) + { + _selected = false; + _mute = false; + _colorIndex = 0; + _raster = -1; // invalid + _quant = -1; + _xmag = -1.0; + _fillLen = 0; + _track = t; + _events = 0; + if (_track && _track->type() == Track::WAVE) + setType(AL::FRAMES); + } + +//--------------------------------------------------------- +// clone +//--------------------------------------------------------- + +void Part::clone(EventList* e) + { + _events = e; + ref(); + } + +//--------------------------------------------------------- +// addEvent +//--------------------------------------------------------- + +iEvent Part::addEvent(Event& p) + { + return _events->add(p); + } + +iEvent Part::addEvent(Event& p, unsigned t) + { + return _events->add(p, t); + } + +//--------------------------------------------------------- +// index +//--------------------------------------------------------- + +int PartList::index(Part* part) + { + int index = 0; + for (iPart i = begin(); i != end(); ++i, ++index) + if (i->second == part) { + return index; + } + printf("PartList::index(): not found!\n"); + abort(); +// return 0; + } + +//--------------------------------------------------------- +// find +//--------------------------------------------------------- + +Part* PartList::find(int idx) + { + int index = 0; + for (iPart i = begin(); i != end(); ++i, ++index) + if (index == idx) + return i->second; + return 0; + } + +//--------------------------------------------------------- +// findPart +// search for part which contains tick +//--------------------------------------------------------- + +Part* PartList::findPart(unsigned tick) + { + iPart i = lower_bound(tick); + if (i != begin()) + --i; + for (; i != end(); ++i) { + unsigned tick1 = i->second->tick(); + unsigned tick2 = tick1 + i->second->lenTick(); + + if (tick >= tick2) + continue; + if (tick >= tick1) + return i->second; + if (tick < tick1) + break; + } + return 0; + } + +//--------------------------------------------------------- +// add +//--------------------------------------------------------- + +iPart PartList::add(Part* part) + { + return insert(std::pair<const unsigned, Part*> (part->tick(), part)); + } + +//--------------------------------------------------------- +// remove +//--------------------------------------------------------- + +void PartList::remove(Part* part) + { + iPart i; + for (i = begin(); i != end(); ++i) { + if (i->second == part) { + erase(i); + return; + } + } +printf("remove part: not found\n"); + assert(i != end()); + } + +//--------------------------------------------------------- +// dump +//--------------------------------------------------------- + +void Part::dump(int n) const + { + for (int i = 0; i < n; ++i) + putchar(' '); + printf("Part: <%s> ", _name.toLatin1().data()); + for (int i = 0; i < n; ++i) + putchar(' '); + PosLen::dump(); + } + +//--------------------------------------------------------- +// Part::write +//--------------------------------------------------------- + +void Part::write(Xml& xml) + { + int id = -1; + bool dumpEvents = true; + + + if (isClone()) { + // we have to dump the event list only on first + // incarnation of clone + + for (iClone i = cloneList.begin(); i != cloneList.end(); ++i) { + if (i->el == _events) { + id = i->id; + dumpEvents = false; + break; + } + } + if (id == -1) + cloneList.push_back(ClonePart(_events, cloneList.size())); + } + + if (id != -1) + xml.stag(QString("part cloneId=\"%1\"").arg(id)); + else + xml.stag("part"); + if (!_name.isEmpty()) + xml.tag("name", _name); + + PosLen::write(xml, "poslen"); + if (_selected) + xml.tag("selected", _selected); + xml.tag("color", _colorIndex); + if (_raster != -1) + xml.tag("raster", _raster); + if (_quant != -1) + xml.tag("quant", _quant); + if (_xmag != -1.0) + xml.tag("xmag", _xmag); + for (ciCtrlCanvas i = ctrlCanvasList.begin(); i != ctrlCanvasList.end(); ++i) + xml.tagE(QString("CtrlCanvas h=\"%1\" id=\"%2\"").arg(i->height).arg(i->ctrlId)); + if (_fillLen) + xml.tag("fillLen", _fillLen); + if (_mute) + xml.tag("mute", _mute); + if (dumpEvents) { + for (ciEvent e = _events->begin(); e != _events->end(); ++e) + e->second.write(xml, *this); + } + xml.etag("part"); + } + +//--------------------------------------------------------- +// Part::read +//--------------------------------------------------------- + +void Part::read(QDomNode node, bool isMidiPart) + { + QDomElement e = node.toElement(); + int id = e.attribute("cloneId", "-1").toInt(); + + ctrlCanvasList.clear(); + for (node = node.firstChild(); !node.isNull(); node = node.nextSibling()) { + QDomElement e = node.toElement(); + QString tag(e.tagName()); + QString s(e.text()); + int i = s.toInt(); + if (tag == "name") + _name = s; + else if (tag == "poslen") + PosLen::read(node); + else if (tag == "selected") + _selected = i; + else if (tag == "color") + _colorIndex = i; + else if (tag == "raster") + _raster = i; + else if (tag == "quant") + _quant = i; + else if (tag == "xmag") + _xmag = s.toDouble(); + else if (tag == "CtrlCanvas") { + CtrlCanvas c; + c.ctrlId = e.attribute("id","0").toInt(); + c.height = e.attribute("h","50").toInt(); + ctrlCanvasList.push_back(c); + } + else if (tag == "mute") + _mute = i; + else if (tag == "fillLen") + _fillLen = i; + else if (tag == "event") { + EventType type = isMidiPart ? Note : Wave; + Event e(type); + e.read(node); + // tickpos is relative to start of part + // TODO: better handling for wave event + e.move(-tick()); + int tick = e.tick(); + if ((tick < 0) || (tick >= int(lenTick()))) { + printf("ReadEvent: warning: event not in part: %d - %d - %d, discarded\n", + 0, tick, lenTick()); + } + else { +#if 0 + if (e.type() == Controller) { + MidiChannel* mc = ((MidiTrack*)_track)->channel(); + if (mc) { + CVal v; + v.i = e.dataB(); + mc->addControllerVal(e.dataA(), tick, v); + } + else + _events.add(e); + } + else +#endif + _events->add(e); + } + } + else + printf("MusE:read: unknown tag %s\n", e.tagName().toLatin1().data()); + } + + if (id != -1) { + bool found = false; + for (iClone i = cloneList.begin(); i != cloneList.end(); ++i) { + if (i->id == id) { + if (_events->size()) + printf("MusE::internal error: clone part contains events\n"); + clone(i->el); + found = true; + break; + } + } + if (!found) { + // add to cloneList: + ClonePart cp(_events, id); + cloneList.push_back(cp); + } + } + } + +//--------------------------------------------------------- +// isClone +//--------------------------------------------------------- + +bool Part::isClone() const + { + return _events->cloneCount > 1; + } + +//--------------------------------------------------------- +// ref +//--------------------------------------------------------- + +void Part::ref() + { + if (_events == 0) + _events = new EventList; + ++(_events->cloneCount); + } + +//--------------------------------------------------------- +// deref +//--------------------------------------------------------- + +void Part::deref() + { + --(_events->cloneCount); + } + |