diff options
Diffstat (limited to 'muse_qt4_evolution/muse/ctrl.cpp')
-rw-r--r-- | muse_qt4_evolution/muse/ctrl.cpp | 450 |
1 files changed, 450 insertions, 0 deletions
diff --git a/muse_qt4_evolution/muse/ctrl.cpp b/muse_qt4_evolution/muse/ctrl.cpp new file mode 100644 index 00000000..82e8efef --- /dev/null +++ b/muse_qt4_evolution/muse/ctrl.cpp @@ -0,0 +1,450 @@ +//============================================================================= +// 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 "fastlog.h" +#include "globals.h" +#include "ctrl.h" +#include "al/xml.h" +#include "midictrl.h" + +//--------------------------------------------------------- +// Ctrl +//--------------------------------------------------------- + +Ctrl::Ctrl(int id, const QString& s, int t) + : _id(id), _name(s), _type(t) + { + setRange(.0f, 1.f); + _default.f = 0.0f; + _curVal.f = 0.0f; + _touched = false; + _changed = false; + _moveWithPart = false; + } + +Ctrl::Ctrl(int id, const QString& s, int t, float a, float b) + : _id(id), _name(s), _type(t) + { + if (_type & INT) + setRange(int(a), int(b)); + else + setRange(a, b); + _default.f = 0.0f; + _curVal.f = 0.0f; + _touched = false; + _changed = false; + _moveWithPart = false; + } + +Ctrl::Ctrl() + { + _type = INTERPOLATE; + setRange(0.0f, 1.0f); + _id = 0; + _default.f = 0.0f; + _curVal.f = 0.0f; + _touched = false; + _changed = false; + _moveWithPart = false; + } + +Ctrl::Ctrl(const MidiController* mc) + { + _type = DISCRETE | INT; + setRange(mc->minVal(), mc->maxVal()); + _id = mc->num(); + _default.i = mc->initVal(); + _curVal.i = CTRL_VAL_UNKNOWN; + _name = mc->name(); + _touched = false; + _changed = false; + _moveWithPart = false; + } + +//--------------------------------------------------------- +// value +//--------------------------------------------------------- + +CVal Ctrl::value(unsigned time) + { + CVal rv; + + if (empty() || _touched) + return _curVal; + if (_type & DISCRETE) { + // + // midi controller + // + ciCtrlVal i = upperBound(time); + if (i == end()) { + --i; + rv = i.value(); + } + else if (i == begin()) { + if (i.key() == time) + rv = i.value(); + else + return _curVal; + } + else { + --i; + rv = i.value(); + } + } + else { + // + // linear interpolated audio + // controller + // + ciCtrlVal i = upperBound(time); + if (i == end()) { + --i; + rv = i.value(); + } + else { + int frame2 = i.key(); + CVal val2 = i.value(); + int frame1; + CVal val1; + if (i == begin()) { + rv = val2; + } + else { + --i; + frame1 = i.key(); + val1 = i.value(); + time -= frame1; + frame2 -= frame1; + if (_type & INT) { + val2.i -= val1.i; + rv.i = val1.i + (time * val2.i)/frame2; + } + else { + val2.f -= val1.f; + rv.f = val1.f + (time * val2.f)/frame2; + } + } + } + } + if (_type & LOG) { + if (rv.f <= -1000.0f) + rv.f = 0.0f; + else + rv.f = pow(10.0f, rv.f); + } + return rv; + } + +//--------------------------------------------------------- +// add +// return true if new value added +//--------------------------------------------------------- + +bool Ctrl::add(unsigned frame, CVal val) + { + if (_type & LOG) { + if (val.f <= 0.0) + val.f = -1001.0f; + else + val.f = log10(val.f); + } + bool rv = find(frame) == end(); + insert(frame, val); + return rv; + } + +//--------------------------------------------------------- +// del +//--------------------------------------------------------- + +void Ctrl::del(unsigned frame) + { + iCtrlVal e = find(frame); + erase(e); + } + +//--------------------------------------------------------- +// read +//--------------------------------------------------------- + +void Ctrl::read(QDomNode node, bool) + { + QDomElement e = node.toElement(); + _id = e.attribute("id").toInt(); + _name = e.attribute("name"); + _type = e.attribute("type","0").toInt(); + + const char* minS = "0.0f"; + const char* maxS = "1.0f"; + + if (_type & INT) { + minS = "0"; + maxS = "127"; + _curVal.i = e.attribute("cur","-1").toInt(); + _default.i = e.attribute("default","-1").toInt(); + } + else { + if (_id == AC_PAN) { + minS = "-1.0f"; + maxS = "+1.0f"; + } + _curVal.f = e.attribute("cur","0.0").toFloat(); + _default.f = e.attribute("default","0.0").toFloat(); + } + setCurVal(_curVal); + if (_type & INT) { + min.i = e.attribute("min", minS).toInt(); + max.i = e.attribute("max", maxS).toInt(); + } + else { + min.f = e.attribute("min", minS).toFloat(); + max.f = e.attribute("max", maxS).toFloat(); + } + + QStringList vp = e.text().simplified().split(",", QString::SkipEmptyParts); + int n = vp.size(); + for (int i = 0; i < n; ++i) { + QStringList sl = vp.at(i).simplified().split(" "); + bool ok; + int frame = sl.at(0).toInt(&ok, 0); + if (!ok) { + printf("Ctrl::read(1): conversion <%s><%s> to int failed\n", + vp.at(i).simplified().toAscii().data(), + sl.at(0).toAscii().data()); + break; + } + CVal val; + if (_type & INT) + val.i = sl.at(1).toInt(&ok, 0); + else + val.f = sl.at(1).toDouble(&ok); + if (!ok) { + printf("Ctrl::read(2): conversion <%s><%s> failed\n", + vp.at(i).simplified().toAscii().data(), + sl.at(1).toAscii().data()); + break; + } + add(frame, val); + } + } + +//--------------------------------------------------------- +// add +//--------------------------------------------------------- + +void CtrlList::add(Ctrl* vl) + { + insert(std::pair<const int, Ctrl*>(vl->id(), vl)); + } + +//--------------------------------------------------------- +// write +//--------------------------------------------------------- + +void Ctrl::write(Xml& xml) + { + QString s("controller id=\"%1\" name=\"%2\" cur=\"%3\" type=\"%4\" min=\"%5\" max=\"%6\" default=\"%7\""); + + QString cn = Xml::xmlString(_name); + + if (empty()) { + if (_type & INT) + xml.tagE(s.arg(id()).arg(cn).arg(curVal().i).arg(_type).arg(min.i).arg(max.i).arg(_default.i).toAscii().data()); + else + xml.tagE(s.arg(id()).arg(cn).arg(curVal().f).arg(_type).arg(min.f).arg(max.f).arg(_default.f).toAscii().data()); + return; + } + if (_type & INT) + xml.stag(s.arg(id()).arg(cn).arg(curVal().i).arg(_type).arg(min.i).arg(max.i).arg(_default.i).toAscii().data()); + else + xml.stag(s.arg(id()).arg(cn).arg(curVal().f).arg(_type).arg(min.f).arg(max.f).arg(_default.f).toAscii().data()); + + int i = 0; + for (ciCtrlVal ic = begin(); ic != end(); ++ic) { + if (i == 0) + xml.putLevel(); + int time = ic.key(); + CVal val = ic.value(); + if (_type & LOG) + val.f = (val.f <= -1000.0) ? 0.0f : pow(10.0f, val.f); + if (_type & INT) { + xml << time << ' ' << val.i << ','; + } + else + xml << time << ' ' << val.f << ','; + ++i; + if (i >= 4) { + xml << endl; + i = 0; + } + } + if (i) + xml << endl; + xml.etag("controller"); + } + +//--------------------------------------------------------- +// val2pixelR +// input val is "raw" data +//--------------------------------------------------------- + +int Ctrl::val2pixelR(CVal val, int maxpixel) + { + maxpixel -= 1; + if (_type & INT) + return maxpixel - ((maxpixel * (val.i - min.i) + (max.i-min.i)/2) / (max.i - min.i)); + else { + if ((_type & LOG) && (val.f <= -1000.0f)) + return maxpixel; + int pixel = maxpixel - lrint(double(maxpixel) * (val.f - min.f) / (max.f-min.f)); + if (pixel < 0) { + printf("%d - lrint(double(%d) * (%f - %f)/(%f-%f)\n", + maxpixel, maxpixel, val.f, min.f, max.f, min.f); + printf(" %f/%f = %f\n", + val.f-min.f, max.f-min.f, (val.f-min.f)/(max.f-min.f)); + } + return pixel; +// return maxpixel - lrint(double(maxpixel) * (val.f - min.f) / (max.f-min.f)); + } + } + +int Ctrl::val2pixelR(int val, int maxpixel) + { + maxpixel -= 1; + int range = max.i - min.i; + return maxpixel - ((maxpixel * (val - min.i) + range / 2) / range); + } + +//--------------------------------------------------------- +// cur2pixel +//--------------------------------------------------------- + +int Ctrl::cur2pixel(int maxpixel) + { +#if 0 + return val2pixelR(_curVal, maxpixel); +#else + maxpixel -= 1; + + if (_type & INT) + return maxpixel - ((maxpixel * (_curVal.i - min.i) + (max.i-min.i)/2) / (max.i - min.i)); + float f = _curVal.f; + if (_type & LOG) { + if (f <= 0.0) + return maxpixel; + else + f = fast_log10(f); + } + return maxpixel - lrint(double(maxpixel) * (f - min.f) / (max.f-min.f)); +#endif + } + +//--------------------------------------------------------- +// pixel2val +//--------------------------------------------------------- + +CVal Ctrl::pixel2val(int pixel, int maxpixel) + { + maxpixel -= 1; + pixel = maxpixel - pixel; + +// printf("pixel2val %d(%d) int %d, min %d, max %d\n", +// pixel, maxpixel, _type & INT, min.i, max.i); + CVal rv; + if (_type & INT) { + rv.i = (pixel * (max.i - min.i) + (maxpixel+min.i)/2) / maxpixel + min.i; + if (rv.i < min.i) + rv.i = min.i; + else if (rv.i > max.i) + rv.i = max.i; + } + else { + rv.f = double(pixel) * (max.f - min.f) / double(maxpixel) + min.f; + if (rv.f < min.f) + rv.f = min.f; + else if (rv.f > max.f) + rv.f = max.f; + if (_type & LOG) + rv.f = pow(10.0f, rv.f); + } + return rv; + } + +//--------------------------------------------------------- +// pixel2valR +//--------------------------------------------------------- + +CVal Ctrl::pixel2valR(int pixel, int maxpixel) + { + maxpixel -= 1; + pixel = maxpixel - pixel; + +// printf("pixel2val %d(%d) int %d, min %d, max %d\n", +// pixel, maxpixel, _type & INT, min.i, max.i); + CVal rv; + if (_type & INT) { + rv.i = (pixel * (max.i - min.i) + (maxpixel+min.i)/2) / maxpixel + min.i; + if (rv.i < min.i) + rv.i = min.i; + else if (rv.i > max.i) + rv.i = max.i; + } + else { + rv.f = double(pixel) * (max.f - min.f) / double(maxpixel) + min.f; + if (rv.f < min.f) + rv.f = min.f; + else if (rv.f > max.f) + rv.f = max.f; + } + return rv; + } + +//--------------------------------------------------------- +// setRange +//--------------------------------------------------------- + +void Ctrl::setRange(double _min, double _max) + { + if (_type & LOG) { + min.f = log10(_min); + max.f = log10(_max); + } + else { + min.f = _min; + max.f = _max; + } + } + +void Ctrl::setRange(int _min, int _max) + { + min.i = _min; + max.i = _max; + } + +//--------------------------------------------------------- +// setRange +//--------------------------------------------------------- + +void Ctrl::setRange(CVal mi, CVal ma) + { + min = mi; + max = ma; + } + |