From c9f1ce13e1d785191b112d5ef0291cb93f5a6393 Mon Sep 17 00:00:00 2001 From: Robert Jonsson Date: Tue, 15 Feb 2011 21:35:24 +0000 Subject: automation fixes --- muse2/ChangeLog | 2 + muse2/muse/arranger/pcanvas.cpp | 86 ++++++++++++++++++++++++++++++----------- muse2/muse/arranger/pcanvas.h | 2 +- muse2/muse/arranger/tlist.cpp | 2 +- muse2/muse/ctrl.cpp | 69 +++++++++++++++++++++------------ muse2/muse/widgets/view.cpp | 3 +- 6 files changed, 114 insertions(+), 50 deletions(-) (limited to 'muse2') diff --git a/muse2/ChangeLog b/muse2/ChangeLog index eb9ffab2..ab5dbcfb 100644 --- a/muse2/ChangeLog +++ b/muse2/ChangeLog @@ -1,3 +1,5 @@ +15.02.2011: + - Automation fixes, better detection, not perfect (rj) 14.02.2011: - Fixed midi track info panel layout and spacing. Should be much better now. (Tim) - Added patch to remove warnings from WillyFoobar (rj) diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 38941068..479fa78e 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -19,7 +19,9 @@ #include #include #include +#include +#include "fastlog.h" #include "widgets/tools.h" #include "pcanvas.h" #include "midieditor.h" @@ -1056,7 +1058,8 @@ void PartCanvas::mouseMove(QMouseEvent* event) if (x < 0) x = 0; - processAutomationMovements(event); + if (_tool == AutomationTool) + processAutomationMovements(event->pos(), event->modifiers() & Qt::ControlModifier); emit timeChanged(AL::sigmap.raster(x, *_raster)); } @@ -1085,6 +1088,17 @@ Track* PartCanvas::y2Track(int y) const void PartCanvas::keyPress(QKeyEvent* event) { int key = event->key(); + +// if (_tool == AutomationTool) { // can't get the cursor pos to work right, skipping for now +// // clear all the automation parameters +// automation.moveController=false; +// automation.controllerState = doNothing; +// automation.currentCtrl=0; +// automation.currentTrack=0; +// automation.currentCtrlList=0; +// +// processAutomationMovements(mapDev(QCursor::pos()),event->key()& Qt::Key_Control); +// } if (editMode) { if ( key == Qt::Key_Return || key == Qt::Key_Enter ) @@ -2958,6 +2972,8 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& r, AudioTrack *t) int prevPosFrame=cvFirst.frame; prevVal = cvFirst.val; + + // prepare prevVal if (cl->valueType() == VAL_LOG ) { // use db scale for volume //printf("volume cvval=%f\n", cvFirst.val); @@ -2994,6 +3010,7 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& r, AudioTrack *t) leftX=rr.x(); } int currentPixel = mapx(tempomap.frame2tick(cv.frame)); + p.drawLine( leftX, (rr.bottom()-2)-prevVal*height, currentPixel, @@ -3038,7 +3055,6 @@ void PartCanvas::checkAutomation(Track * t, const QPoint &pointer, bool addNewCt int circumference = 5; if (t->isMidiTrack()) return; - //printf("checkAutomation p.x()=%d p.y()=%d\n", mapx(pointer.x()), mapy(pointer.y())); int currX = mapx(pointer.x()); int currY = mapy(pointer.y()); @@ -3094,21 +3110,49 @@ void PartCanvas::checkAutomation(Track * t, const QPoint &pointer, bool addNewCt if (addNewCtrl) { // check if we are reasonably close to a line //printf("xpixel=%d oldX=%d\n", xpixel, oldX); - if ( xpixel == oldX && abs(currX-xpixel) < circumference) - foundIt=true; + double firstX=oldX; + double lastX=xpixel; + double firstY=oldY; + double lastY=ypixel; + + double proportion = (currX-firstX)/(lastX-firstX); + + if ( (currX > lastX && firstY!=lastY) // omit special cases. + || firstX==lastX ) { + oldX = xpixel; + oldY = ypixel; + continue; // not the right region + } - } + //printf("firstX=%f lastX=%f firstY=%f lastY=%f proportion=%f currX=%d\n", firstX,lastX,firstY,lastY,proportion, currX); + + // 10 X(15) 20 + // proportion = 0.5 + // 10 + // / + // Y(5) + // / + // 1 + double calcY = (lastY-firstY)*proportion+firstY; + //printf("calcY=%f currY=%d\n", calcY, currY); + if ( abs(calcY-currY) < circumference*4) + foundIt=true; + + if ( xpixel == oldX && abs(currX-xpixel) < circumference) + foundIt=true; + + } else { + int x1 = abs(currX - xpixel) ; + int y1 = abs(currY - ypixel); + if (x1 < circumference && y1 < circumference && pointer.x() > 0 && pointer.y() > 0) { + foundIt=true; + } + } //printf("point at x=%d xdiff=%d y=%d ydiff=%d\n", mapx(tempomap.frame2tick(cv.frame)), x1, mapx(ypixel), y1); oldX = xpixel; oldY = ypixel; - int x1 = abs(currX - xpixel) ; - int y1 = abs(currY - ypixel); - if (!addNewCtrl && x1 < circumference && y1 < circumference && pointer.x() > 0 && pointer.y() > 0) { - foundIt=true; - } - if (foundIt) { QWidget::setCursor(Qt::CrossCursor); if (addNewCtrl) { @@ -3156,18 +3200,16 @@ void PartCanvas::controllerChanged(Track* /* t */) redraw(); } -void PartCanvas::processAutomationMovements(QMouseEvent *event) +void PartCanvas::processAutomationMovements(QPoint pos, bool addPoint) { + //printf("processAutomationMovements %d %d %d %d %d %d\n", pos.x(), pos.y(),mapx(pos.x()), mapy(pos.y()), xpos, ypos); if (_tool == AutomationTool) { if (!automation.moveController) { // currently nothing going lets's check for some action. - Track * t = y2Track(event->pos().y()); + Track * t = y2Track(pos.y()); if (t) { - bool addNewPoints=false; - if (event->modifiers() & Qt::ControlModifier) - addNewPoints=true; - checkAutomation(t, event->pos(), addNewPoints); + checkAutomation(t, pos, addPoint); } return; } @@ -3180,7 +3222,7 @@ void PartCanvas::processAutomationMovements(QMouseEvent *event) if (automation.controllerState == addNewController) { //printf("adding a new ctrler!\n"); - int frame = tempomap.tick2frame(event->pos().x()); + int frame = tempomap.tick2frame(pos.x()); automation.currentCtrlList->add( frame, 1.0 /*dummy value */); iCtrl ic=automation.currentCtrlList->begin(); @@ -3207,12 +3249,12 @@ void PartCanvas::processAutomationMovements(QMouseEvent *event) CtrlVal &cv = ic->second; nextFrame = cv.frame; } - int currFrame = tempomap.tick2frame(event->pos().x()); + int currFrame = tempomap.tick2frame(pos.x()); if (currFrame < prevFrame) currFrame=prevFrame+1; if (nextFrame!=-1 && currFrame > nextFrame) currFrame=nextFrame-1; automation.currentCtrl->frame = currFrame; - int posy=mapy(event->pos().y()); + int posy=mapy(pos.y()); int tracky = mapy(automation.currentTrack->y()); int trackHeight = automation.currentTrack->height(); //printf("posy=%d tracky=%d trackHeight=%d\n", posy,tracky,trackHeight); @@ -3251,9 +3293,9 @@ void PartCanvas::processAutomationMovements(QMouseEvent *event) double PartCanvas::dbToVal(double inDb) { - return (20.0*log10(inDb)+60) / 70.0; + return (20.0*fast_log10(inDb)+60.0) / 70.0; } double PartCanvas::valToDb(double inV) { - return exp10((inV*70.0-60)/20.0); + return exp10((inV*70.0-60.0)/20.0); } diff --git a/muse2/muse/arranger/pcanvas.h b/muse2/muse/arranger/pcanvas.h index 6a324770..e7fa1fdf 100644 --- a/muse2/muse/arranger/pcanvas.h +++ b/muse2/muse/arranger/pcanvas.h @@ -118,7 +118,7 @@ class PartCanvas : public Canvas { void drawTopItem(QPainter& p, const QRect& rect); void checkAutomation(Track * t, const QPoint& pointer, bool addNewCtrl); - void processAutomationMovements(QMouseEvent *event); + void processAutomationMovements(QPoint pos, bool addPoint); double dbToVal(double inDb); double valToDb(double inV); diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index ab228e3b..a76be9c2 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -1014,7 +1014,7 @@ void TList::mousePressEvent(QMouseEvent* ev) switch (col) { case COL_AUTOMATION: { - if (t->type() != Track::MIDI) { + if (!t->isMidiTrack()) { editAutomation = t; PopupMenu* p = new PopupMenu(); p->disconnect(); diff --git a/muse2/muse/ctrl.cpp b/muse2/muse/ctrl.cpp index bb77e0c5..922da337 100644 --- a/muse2/muse/ctrl.cpp +++ b/muse2/muse/ctrl.cpp @@ -13,6 +13,9 @@ #include //#include +#include "gconfig.h" +#include "fastlog.h" +#include "math.h" #include "globals.h" #include "ctrl.h" #include "xml.h" @@ -79,19 +82,20 @@ CtrlList::CtrlList() //--------------------------------------------------------- double CtrlList::value(int frame) - { +{ if (!automation || empty()) { return _curVal; } - ciCtrl i = upper_bound(frame); - if (i == end()) { + + ciCtrl i = upper_bound(frame); // get the index after current frame + + if (i == end()) { // if we are past all items just return the last value ciCtrl i = end(); --i; const CtrlVal& val = i->second; _curVal = val.val; } - else - if(_mode == DISCRETE) + else if(_mode == DISCRETE) { if(i == begin()) _curVal = _default; @@ -103,28 +107,43 @@ double CtrlList::value(int frame) } } else { - int frame2 = i->second.frame; - double val2 = i->second.val; - int frame1; - double val1; - if (i == begin()) { - frame1 = 0; - val1 = _default; - } - else { - --i; - frame1 = i->second.frame; - val1 = i->second.val; - } - frame -= frame1; - val2 -= val1; - frame2 -= frame1; - val1 += (frame * val2)/frame2; - _curVal = val1; - } + int frame2 = i->second.frame; + double val2 = i->second.val; + int frame1; + double val1; + if (i == begin()) { + frame1 = 0; + val1 = _default; + } + else { + --i; + frame1 = i->second.frame; + val1 = i->second.val; + } + //printf("before val1=%f val2=%f\n", val1,val2); + if (_valueType == VAL_LOG) { + val1 = 20.0*fast_log10(val1); + if (val1 < config.minSlider) + val1=config.minSlider; + val2 = 20.0*fast_log10(val2); + if (val2 < config.minSlider) + val2=config.minSlider; + } + //printf("after val1=%f val2=%f\n", val1,val2); + frame -= frame1; + val2 -= val1; + frame2 -= frame1; + val1 += (double(frame) * val2)/double(frame2); + + if (_valueType == VAL_LOG) { + val1 = exp10(val1/20.0); + } + //printf("after val1=%f\n", val1); + _curVal = val1; + } // printf("autoVal %d %f\n", frame, _curVal); return _curVal; - } +} //--------------------------------------------------------- diff --git a/muse2/muse/widgets/view.cpp b/muse2/muse/widgets/view.cpp index 31cc212e..c5109017 100644 --- a/muse2/muse/widgets/view.cpp +++ b/muse2/muse/widgets/view.cpp @@ -568,6 +568,7 @@ int View::mapyDev(int y) const return (y + ypos + rmapy(yorg) + ymag / 2) / ymag; } +// r == relative conversion int View::rmapx(int x) const { if (xmag < 0) @@ -636,4 +637,4 @@ QRect View::devToVirt(const QRect& r) return QRect(x, y, w, h); } -*/ \ No newline at end of file +*/ -- cgit v1.2.3