From ed5aec7376ab2f4c68750c07ca4187d8b17c349d Mon Sep 17 00:00:00 2001 From: Robert Jonsson Date: Sat, 27 Aug 2011 18:30:50 +0000 Subject: mouse wheel behaviour changed --- muse2/ChangeLog | 2 ++ muse2/muse/midieditor.cpp | 2 -- muse2/muse/waveedit/waveview.cpp | 40 ++++++++++++++-------------- muse2/muse/widgets/canvas.cpp | 57 ++++++++++++++++++++-------------------- 4 files changed, 50 insertions(+), 51 deletions(-) diff --git a/muse2/ChangeLog b/muse2/ChangeLog index d5dd93ce..aa7b65d1 100644 --- a/muse2/ChangeLog +++ b/muse2/ChangeLog @@ -1,3 +1,5 @@ +28.08.2011: + - Changed mousewheel behaviour, vertical scrolling is default and horizontal scrolling (shift) is reversed (rj) 17.08.2011: - Convert some Qt3 style coding in ComboBox to Qt4 in terms of menu entry handling. (Orcan) - Add mouse wheel support to ComboBox. (Orcan) diff --git a/muse2/muse/midieditor.cpp b/muse2/muse/midieditor.cpp index f4d21320..ce6c52f8 100644 --- a/muse2/muse/midieditor.cpp +++ b/muse2/muse/midieditor.cpp @@ -228,7 +228,6 @@ void MidiEditor::setCurCanvasPart(Part* part) void MidiEditor::horizontalZoomIn() { - printf("zoom in \n"); int mag = hscroll->mag(); int zoomlvl = ScrollScale::getQuickZoomLevel(mag); if (zoomlvl < 23) @@ -242,7 +241,6 @@ void MidiEditor::horizontalZoomIn() void MidiEditor::horizontalZoomOut() { - printf("zoom out \n"); int mag = hscroll->mag(); int zoomlvl = ScrollScale::getQuickZoomLevel(mag); if (zoomlvl > 1) diff --git a/muse2/muse/waveedit/waveview.cpp b/muse2/muse/waveedit/waveview.cpp index cd798c40..236e2588 100644 --- a/muse2/muse/waveedit/waveview.cpp +++ b/muse2/muse/waveedit/waveview.cpp @@ -396,35 +396,35 @@ void WaveView::wheelEvent(QWheelEvent* ev) bool ctrl = keyState & Qt::ControlModifier; if (shift) { // scroll vertically - emit mouseWheelMoved(ev->delta() / 10); + int delta = -ev->delta() / WHEEL_DELTA; + int xpixelscale = 5*fast_log10(rmapxDev(1)); - } else if (ctrl) { // zoom horizontally - if (ev->delta()>0) - emit horizontalZoomIn(); - else - emit horizontalZoomOut(); - } else { // scroll horizontally - int delta = ev->delta() / WHEEL_DELTA; - int xpixelscale = 5*fast_log10(rmapxDev(1)); + if (xpixelscale <= 0) + xpixelscale = 1; + int scrollstep = WHEEL_STEPSIZE * (delta); + ///if (ev->state() == Qt::ShiftModifier) + // if (((QInputEvent*)ev)->modifiers() == Qt::ShiftModifier) + scrollstep = scrollstep / 10; - if (xpixelscale <= 0) - xpixelscale = 1; + int newXpos = xpos + xpixelscale * scrollstep; - int scrollstep = WHEEL_STEPSIZE * (delta); - ///if (ev->state() == Qt::ShiftModifier) -// if (((QInputEvent*)ev)->modifiers() == Qt::ShiftModifier) - scrollstep = scrollstep / 10; + if (newXpos < 0) + newXpos = 0; - int newXpos = xpos + xpixelscale * scrollstep; + //setYPos(newYpos); + emit horizontalScroll((unsigned)newXpos); - if (newXpos < 0) - newXpos = 0; - //setYPos(newYpos); - emit horizontalScroll((unsigned)newXpos); + } else if (ctrl) { // zoom horizontally + if (ev->delta()>0) + emit horizontalZoomIn(); + else + emit horizontalZoomOut(); + } else { // scroll horizontally + emit mouseWheelMoved(ev->delta() / 10); } } diff --git a/muse2/muse/widgets/canvas.cpp b/muse2/muse/widgets/canvas.cpp index c7186a2d..6491b585 100644 --- a/muse2/muse/widgets/canvas.cpp +++ b/muse2/muse/widgets/canvas.cpp @@ -465,25 +465,25 @@ void Canvas::wheelEvent(QWheelEvent* ev) bool shift = keyState & Qt::ShiftModifier; bool ctrl = keyState & Qt::ControlModifier; - if (shift) { // scroll vertically - int delta = ev->delta() / WHEEL_DELTA; - int ypixelscale = rmapyDev(1); + if (shift) { // scroll horizontally + int delta = -ev->delta() / WHEEL_DELTA; + int xpixelscale = 5*fast_log10(rmapxDev(1)); - if (ypixelscale <= 0) - ypixelscale = 1; + if (xpixelscale <= 0) + xpixelscale = 1; - int scrollstep = WHEEL_STEPSIZE * (-delta); - ///if (ev->state() == Qt::ShiftModifier) -// if (((QInputEvent*)ev)->modifiers() == Qt::ShiftModifier) - scrollstep = scrollstep / 2; + int scrollstep = WHEEL_STEPSIZE * (delta); + ///if (ev->state() == Qt::ShiftModifier) + // if (((QInputEvent*)ev)->modifiers() == Qt::ShiftModifier) + scrollstep = scrollstep / 10; - int newYpos = ypos + ypixelscale * scrollstep; + int newXpos = xpos + xpixelscale * scrollstep; - if (newYpos < 0) - newYpos = 0; + if (newXpos < 0) + newXpos = 0; - //setYPos(newYpos); - emit verticalScroll((unsigned)newYpos); + //setYPos(newYpos); + emit horizontalScroll((unsigned)newXpos); } else if (ctrl) { // zoom horizontally if (ev->delta()>0) @@ -491,26 +491,25 @@ void Canvas::wheelEvent(QWheelEvent* ev) else emit horizontalZoomOut(); - } else { // scroll horizontally - int delta = ev->delta() / WHEEL_DELTA; - int xpixelscale = 5*fast_log10(rmapxDev(1)); + } else { // scroll vertically + int delta = ev->delta() / WHEEL_DELTA; + int ypixelscale = rmapyDev(1); + if (ypixelscale <= 0) + ypixelscale = 1; - if (xpixelscale <= 0) - xpixelscale = 1; + int scrollstep = WHEEL_STEPSIZE * (-delta); + ///if (ev->state() == Qt::ShiftModifier) + // if (((QInputEvent*)ev)->modifiers() == Qt::ShiftModifier) + scrollstep = scrollstep / 2; - int scrollstep = WHEEL_STEPSIZE * (delta); - ///if (ev->state() == Qt::ShiftModifier) -// if (((QInputEvent*)ev)->modifiers() == Qt::ShiftModifier) - scrollstep = scrollstep / 10; + int newYpos = ypos + ypixelscale * scrollstep; - int newXpos = xpos + xpixelscale * scrollstep; + if (newYpos < 0) + newYpos = 0; - if (newXpos < 0) - newXpos = 0; - - //setYPos(newYpos); - emit horizontalScroll((unsigned)newXpos); + //setYPos(newYpos); + emit verticalScroll((unsigned)newYpos); } -- cgit v1.2.3 From 21e75f0c2d14010d060693c77fd3e22e1fccd65d Mon Sep 17 00:00:00 2001 From: Robert Jonsson Date: Sun, 28 Aug 2011 17:07:56 +0000 Subject: fixed REC column too large --- muse2/ChangeLog | 3 +++ muse2/muse/widgets/header.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/muse2/ChangeLog b/muse2/ChangeLog index aa7b65d1..9eee3e8b 100644 --- a/muse2/ChangeLog +++ b/muse2/ChangeLog @@ -1,4 +1,7 @@ 28.08.2011: + - Fixed wierd column expansion for [rec] column by removing autoexpand of the last column. Still + something fishy with moving columns (rj) +27.08.2011: - Changed mousewheel behaviour, vertical scrolling is default and horizontal scrolling (shift) is reversed (rj) 17.08.2011: - Convert some Qt3 style coding in ComboBox to Qt4 in terms of menu entry handling. (Orcan) diff --git a/muse2/muse/widgets/header.cpp b/muse2/muse/widgets/header.cpp index c12c8eaf..ef874fc4 100644 --- a/muse2/muse/widgets/header.cpp +++ b/muse2/muse/widgets/header.cpp @@ -101,7 +101,6 @@ Header::Header(QWidget* parent, const char* name) itemModel = new QStandardItemModel; setModel(itemModel); setDefaultSectionSize(30); - setStretchLastSection(true); } @@ -111,6 +110,7 @@ Header::Header(QWidget* parent, const char* name) void Header::setColumnLabel(const QString & text, int col, int width ) { + //printf("column set to %s %d %d \n", text.toLatin1().data(), col, width); QStandardItem *sitem = new QStandardItem(text ); itemModel->setHorizontalHeaderItem(col, sitem); if (width > -1) -- cgit v1.2.3 From d505c378bdf55445babb73e0ba4085702be35870 Mon Sep 17 00:00:00 2001 From: "Tim E. Real" Date: Mon, 29 Aug 2011 22:44:24 +0000 Subject: Fixed audio automation graph editing. And now 'snaps' to discrete integer or bool types. All control movements should update display now. Also slightly changed behaviour of Ctrl class. TODO: Fix some painting corruption, improve discrete display, add transparency etc. etc. Applied compilation patch to rhythmbase.ui by Jean-Damien Durand. --- muse2/ChangeLog | 5 + muse2/awl/posedit.cpp | 3 +- muse2/muse/arranger/arranger.cpp | 1 + muse2/muse/arranger/pcanvas.cpp | 393 +++++++++++++++++++++----------------- muse2/muse/arranger/pcanvas.h | 10 +- muse2/muse/audio.cpp | 4 + muse2/muse/audio.h | 2 + muse2/muse/audiotrack.cpp | 41 ++-- muse2/muse/cliplist/cliplist.cpp | 8 +- muse2/muse/ctrl.cpp | 110 ++++++----- muse2/muse/ctrl.h | 5 +- muse2/muse/dssihost.cpp | 15 +- muse2/muse/dssihost.h | 2 + muse2/muse/mixer/astrip.cpp | 43 +++-- muse2/muse/mixer/panknob.cpp | 4 +- muse2/muse/mplugins/rhythmbase.ui | 8 +- muse2/muse/plugin.cpp | 92 ++++++--- muse2/muse/plugin.h | 10 +- muse2/muse/seqmsg.cpp | 27 +++ muse2/muse/song.cpp | 17 ++ muse2/muse/song.h | 7 +- muse2/muse/track.cpp | 4 +- muse2/muse/track.h | 1 + 23 files changed, 506 insertions(+), 306 deletions(-) diff --git a/muse2/ChangeLog b/muse2/ChangeLog index 9eee3e8b..2505f901 100644 --- a/muse2/ChangeLog +++ b/muse2/ChangeLog @@ -1,3 +1,8 @@ +29.08.2011: + - Fixed audio automation graph editing. And now 'snaps' to discrete integer or bool types. (Tim p4.0.32) + All control movements should update display now. Also slightly changed behaviour of Ctrl class. + TODO: Fix some painting corruption, improve discrete display, add transparency etc. etc. + - Applied compilation patch to rhythmbase.ui by Jean-Damien Durand. (Tim) 28.08.2011: - Fixed wierd column expansion for [rec] column by removing autoexpand of the last column. Still something fishy with moving columns (rj) diff --git a/muse2/awl/posedit.cpp b/muse2/awl/posedit.cpp index 6ca49566..07741e58 100644 --- a/muse2/awl/posedit.cpp +++ b/muse2/awl/posedit.cpp @@ -70,7 +70,8 @@ PosEdit::~PosEdit() QSize PosEdit::sizeHint() const { - QFontMetrics fm(font()); + //QFontMetrics fm(font()); + QFontMetrics fm = fontMetrics(); int fw = style()->pixelMetric(QStyle::PM_SpinBoxFrameWidth); int h = fm.height() + fw * 2; int w = fw * 4 + 10; // HACK: 10 = spinbox up/down arrows diff --git a/muse2/muse/arranger/arranger.cpp b/muse2/muse/arranger/arranger.cpp index e1205d6f..65a705e2 100644 --- a/muse2/muse/arranger/arranger.cpp +++ b/muse2/muse/arranger/arranger.cpp @@ -427,6 +427,7 @@ Arranger::Arranger(QMainWindow* parent, const char* name) connect(canvas, SIGNAL(dropMidiFile(const QString&)), SIGNAL(dropMidiFile(const QString&))); connect(canvas, SIGNAL(toolChanged(int)), SIGNAL(toolChanged(int))); + connect(song, SIGNAL(controllerChanged(Track*)), SLOT(controllerChanged(Track*))); // connect(song, SIGNAL(posChanged(int, unsigned, bool)), SLOT(seek())); // Removed p3.3.43 diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 82f2de45..57bf71ba 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -44,6 +44,10 @@ #include "midictrl.h" #include "utils.h" +//#define ABS(x) ((x) < 0) ? -(x) : (x)) +//#define ABS(x) (x>=0?x:-x) +#define ABS(x) (abs(x)) + //--------------------------------------------------------- // colorRect // paints a rectangular icon with a given color @@ -94,7 +98,8 @@ PartCanvas::PartCanvas(int* r, QWidget* parent, int sx, int sy) setMouseTracking(true); drag = DRAG_OFF; curColorIndex = 0; - automation.currentCtrl = 0; + //automation.currentCtrl = 0; + automation.currentCtrlValid = false; automation.controllerState = doNothing; automation.moveController = false; partsChanged(); @@ -862,7 +867,8 @@ void PartCanvas::mouseRelease(const QPoint&) // clear all the automation parameters automation.moveController=false; automation.controllerState = doNothing; - automation.currentCtrl=0; + //automation.currentCtrl=0; + automation.currentCtrlValid = false; automation.currentTrack=0; automation.currentCtrlList=0; } @@ -3436,107 +3442,104 @@ void PartCanvas::drawAudioTrack(QPainter& p, const QRect& r, const QRect& bbox, void PartCanvas::drawAutomation(QPainter& p, const QRect& rr, AudioTrack *t) { - ///QRect rr = p.worldMatrix().mapRect(r); - - ///p.save(); - ///p.resetTransform(); - - int height=rr.bottom()-rr.top()-4; // limit height - - //printf("PartCanvas::drawAutomation x:%d y:%d w:%d h:%d height:%d\n", rr.x(), rr.y(), rr.width(), rr.height(), height); - - p.setBrush(Qt::NoBrush); - - CtrlListList* cll = t->controller(); - ///bool firstRun=true; - for(CtrlListList::iterator icll =cll->begin();icll!=cll->end();++icll) - { - //iCtrlList *icl = icll->second; - CtrlList *cl = icll->second; - if (cl->dontShow()) - continue; - double prevVal; - iCtrl ic=cl->begin(); - if (!cl->isVisible()) - continue; // skip this iteration if this controller isn't in the visible list - ///p.setPen(QPen(cl->color(),1,Qt::SolidLine)); - p.setPen(QPen(cl->color(), 0, Qt::SolidLine)); - - // First check that there ARE automation, ic == cl->end means no automation - if (ic != cl->end()) { - CtrlVal cvFirst = ic->second; - ic++; - int prevPosFrame=cvFirst.frame; - prevVal = cvFirst.val; - ///bool discrete = cl->valueType() == VAL_BOOL || cl->mode() == CtrlList::DISCRETE; // Tim - - // prepare prevVal - if (cl->valueType() == VAL_LOG ) { // use db scale for volume - prevVal = dbToVal(cvFirst.val); // represent volume between 0 and 1 - if (prevVal < 0) prevVal = 0.0; - } - else { - // we need to set curVal between 0 and 1 - double min, max; - cl->range(&min,&max); - prevVal = (prevVal- min)/(max-min); - } + //QRect rr = p.worldMatrix().mapRect(r); + //p.save(); + //p.resetTransform(); - // draw a square around the point - p.drawRect(mapx(tempomap.frame2tick(prevPosFrame))-1, (rr.bottom()-2)-prevVal*height-1, 3, 3); - p.drawRect(mapx(tempomap.frame2tick(prevPosFrame))-2, (rr.bottom()-2)-prevVal*height-2, 5, 5); + int bottom = rr.bottom() - 2; + int height = bottom - rr.top() - 2; // limit height - bool firstRun=true; - for (; ic !=cl->end(); ++ic) - { - CtrlVal cv = ic->second; - double nextVal = cv.val; // was curVal + //printf("PartCanvas::drawAutomation x:%d y:%d w:%d h:%d height:%d\n", rr.x(), rr.y(), rr.width(), rr.height(), height); + + p.setBrush(Qt::NoBrush); + + CtrlListList* cll = t->controller(); + for(CtrlListList::iterator icll =cll->begin();icll!=cll->end();++icll) + { + CtrlList *cl = icll->second; + if (cl->dontShow() || !cl->isVisible()) + continue; + iCtrl ic=cl->begin(); + int oldX = mapx(0); + if(rr.right() < oldX) + { + //p.restore(); + return; + } + int xpixel = oldX; + int oldY = -1; + int ypixel = oldY; + double min, max; + cl->range(&min,&max); + //bool discrete = cl->valueType() == VAL_BOOL || cl->mode() == CtrlList::DISCRETE; + bool discrete = cl->mode() == CtrlList::DISCRETE; + QPen pen1(cl->color(), 0); + QPen pen2(cl->color(), 2); + pen2.setCosmetic(true); + + // First check that there ARE automation, ic == cl->end means no automation + if (ic == cl->end()) + { + double y; + if (cl->valueType() == VAL_LOG ) { // use db scale for volume + y = dbToVal(cl->curVal()); // represent volume between 0 and 1 + if (y < 0) y = 0.0; + } + else + y = (cl->curVal() - min)/(max-min); // we need to set curVal between 0 and 1 + ypixel = oldY = bottom - rmapy_f(y) * height; + } + else + { + for (; ic !=cl->end(); ++ic) + { + double y = ic->second.val; if (cl->valueType() == VAL_LOG ) { // use db scale for volume - nextVal = dbToVal(cv.val); // represent volume between 0 and 1 - if (nextVal < 0) nextVal = 0.0; - } - else { - // we need to set curVal between 0 and 1 - double min, max; - cl->range(&min,&max); - nextVal = (nextVal- min)/(max-min); + y = dbToVal(y); // represent volume between 0 and 1 + if (y < 0) y = 0.0; } - int leftX=mapx(tempomap.frame2tick(prevPosFrame)); - if (firstRun && leftX>rr.x()) { - leftX=rr.x(); - } - int currentPixel = mapx(tempomap.frame2tick(cv.frame)); + else + y = (y-min)/(max-min); // we need to set curVal between 0 and 1 + + ypixel = bottom - rmapy_f(y) * height; + xpixel = mapx(tempomap.frame2tick(ic->second.frame)); + + if (oldY==-1) oldY = ypixel; //printf(" line x1:%d x2:%d prevVal:%f nextVal:%f\n", leftX, currentPixel, prevVal, nextVal); - p.drawLine( leftX, - (rr.bottom()-2)-prevVal*height, - currentPixel, - (rr.bottom()-2)-nextVal*height); - - ///if(discrete) - /// p.drawLine( currentPixel, (rr.bottom()-2)-prevVal*height, currentPixel, (rr.bottom()-2)-nextVal*height ); // Tim - - firstRun=false; - prevPosFrame=cv.frame; - prevVal=nextVal; - if (currentPixel > rr.x()+ rr.width()) - ///goto quitDrawing; - break; + p.setPen(pen1); + if(discrete) + { + p.drawLine(oldX, oldY, xpixel, oldY); + p.drawLine(xpixel, oldY, xpixel, ypixel); + } + else + p.drawLine(oldX, oldY, xpixel, ypixel); + + if (xpixel > rr.right()) + break; // draw a square around the point - p.drawRect(mapx(tempomap.frame2tick(prevPosFrame))-2, (rr.bottom()-2)-prevVal*height-2, 5, 5); - p.drawRect(mapx(tempomap.frame2tick(prevPosFrame))-1, (rr.bottom()-1)-prevVal*height-2, 3, 3); - } - //printf(" endline prevVal:%f\n", prevVal); - p.drawLine(mapx(tempomap.frame2tick(prevPosFrame)), - (rr.bottom()-2)-prevVal*height, - rr.x()+rr.width(), - (rr.bottom()-2)-prevVal*height); - } - } -///quitDrawing: - ///p.restore(); - return; + //p.drawRect(mapx(tempomap.frame2tick(prevPosFrame))-2, (rr.bottom()-2)-prevVal*height-2, 5, 5); + //p.drawRect(mapx(tempomap.frame2tick(prevPosFrame))-1, (rr.bottom()-1)-prevVal*height-2, 3, 3); + pen2.setColor((automation.currentCtrlValid && automation.currentCtrlList == cl && + automation.currentCtrlFrame == ic->second.frame) ? + Qt::white : cl->color()); + + p.setPen(pen2); + p.drawRect(xpixel-2, ypixel-2, 5, 5); + oldX = xpixel; + oldY = ypixel; + } + } + if (xpixel <= rr.right()) + { + //printf(" endline prevVal:%f\n", prevVal); + p.setPen(pen1); + p.drawLine(xpixel, ypixel, rr.right(), ypixel); + } + } + //p.restore(); } @@ -3553,60 +3556,68 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& rr, AudioTrack *t) void PartCanvas::checkAutomation(Track * t, const QPoint &pointer, bool addNewCtrl) { - int circumference = 5; if (t->isMidiTrack()) return; + int currY; + int trackY = t->y(); + int trackH = t->height(); + + { int y = pointer.y(); + if(y < trackY || y >= (trackY + trackH)) + return; + currY = mapy(y); } + int currX = mapx(pointer.x()); - int currY = mapy(pointer.y()); - + int circumference = 5; + CtrlListList* cll = ((AudioTrack*) t)->controller(); for(CtrlListList::iterator icll =cll->begin();icll!=cll->end();++icll) { - //iCtrlList *icl = icll->second; CtrlList *cl = icll->second; if (cl->dontShow() || !cl->isVisible()) { continue; } iCtrl ic=cl->begin(); - int oldX=-1; - int oldY=-1; - int ypixel=0; - int xpixel=-1; + int oldX = mapx(0); + int xpixel = oldX; + int oldY = -1; + int ypixel = oldY; + double min, max; + cl->range(&min,&max); + //bool discrete = cl->valueType() == VAL_BOOL || cl->mode() == CtrlList::DISCRETE; // Tim // First check that there IS automation, ic == cl->end means no automation - if (ic != cl->end()) { + if (ic == cl->end()) + { + double y; + if (cl->valueType() == VAL_LOG ) { // use db scale for volume + y = dbToVal(cl->curVal()); // represent volume between 0 and 1 + if (y < 0) y = 0.0; + } + else + y = (cl->curVal() - min)/(max-min); // we need to set curVal between 0 and 1 + ypixel = oldY = mapy(trackY+trackH-1 - 2 - y * trackH); + } + else + { for (; ic !=cl->end(); ic++) { - CtrlVal &cv = ic->second; - double y; + double y = ic->second.val; if (cl->valueType() == VAL_LOG ) { // use db scale for volume - y = dbToVal(cv.val); // represent volume between 0 and 1 + y = dbToVal(y); // represent volume between 0 and 1 if (y < 0) y = 0; } - else { - // we need to set curVal between 0 and 1 - double min, max; - cl->range(&min,&max); - y = ( cv.val - min)/(max-min); - } - - TrackList* tl = song->tracks(); - int yy = 0; - for (iTrack it = tl->begin(); it != tl->end(); ++it) { - Track* track = *it; - yy += track->height(); - if (track == t) - break; - } + else + y = (y-min)/(max-min); // we need to set curVal between 0 and 1 - ypixel = mapy(yy-2-y*t->height()); - xpixel = mapx(tempomap.frame2tick(cv.frame)); + ypixel = mapy(trackY + trackH - 2 - y * trackH); + xpixel = mapx(tempomap.frame2tick(ic->second.frame)); - if (oldX==-1) oldX = xpixel; if (oldY==-1) oldY = ypixel; - + //printf(" oldX:%d oldY:%d xpixel:%d ypixel:%d\n", oldX, oldY, xpixel, ypixel); + bool foundIt=false; if (addNewCtrl) { // check if we are reasonably close to a line @@ -3618,14 +3629,15 @@ void PartCanvas::checkAutomation(Track * t, const QPoint &pointer, bool addNewCt double proportion = (currX-firstX)/(lastX-firstX); - if ( (currX > lastX && firstY!=lastY) // omit special cases. - || firstX==lastX ) { + //if ( (currX > lastX && firstY!=lastY) // omit special cases. + // || firstX==lastX ) { + if((currX < oldX) || (currX > lastX) || (firstX==lastX) ) + { oldX = xpixel; oldY = ypixel; continue; // not the right region } - // 10 X(15) 20 // proportion = 0.5 // 10 @@ -3635,15 +3647,12 @@ void PartCanvas::checkAutomation(Track * t, const QPoint &pointer, bool addNewCt // 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) + if(ABS(calcY-currY) < circumference || (xpixel == oldX && ABS(currX-xpixel) < circumference)) foundIt=true; - + } else { - int x1 = abs(currX - xpixel) ; - int y1 = abs(currY - ypixel); + int x1 = ABS(currX - xpixel) ; + int y1 = ABS(currY - ypixel); if (x1 < circumference && y1 < circumference && pointer.x() > 0 && pointer.y() > 0) { foundIt=true; } @@ -3655,10 +3664,14 @@ void PartCanvas::checkAutomation(Track * t, const QPoint &pointer, bool addNewCt if (foundIt) { QWidget::setCursor(Qt::CrossCursor); if (addNewCtrl) { - automation.currentCtrl = 0; + //automation.currentCtrl = 0; + automation.currentCtrlValid = false; automation.controllerState = addNewController; }else { - automation.currentCtrl=&cv; + //automation.currentCtrl=&ic->second; + automation.currentCtrlFrame = ic->second.frame; + //automation.currentCtrlVal = ic->second.val; + automation.currentCtrlValid = true; automation.controllerState = movingController; } automation.currentCtrlList = cl; @@ -3666,37 +3679,36 @@ void PartCanvas::checkAutomation(Track * t, const QPoint &pointer, bool addNewCt return; } } - } // if + } if (addNewCtrl) { - // check if we are reasonably close to a line, we only need to check Y - // as the line is straight after the last controller - bool foundIt=false; - if ( ypixel == oldY && abs(currY-ypixel) < circumference) { - foundIt=true; - } - - if (foundIt) { + // check if we are reasonably close to a line, we only need to check Y + // as the line is straight after the last controller + //printf("post oldX:%d oldY:%d xpixel:%d ypixel:%d currX:%d currY:%d\n", oldX, oldY, xpixel, ypixel, currX, currY); + if(currX >= xpixel && ypixel == oldY && ABS(currY-ypixel) < circumference) { QWidget::setCursor(Qt::CrossCursor); automation.controllerState = addNewController; automation.currentCtrlList = cl; automation.currentTrack = t; - automation.currentCtrl = 0; + //automation.currentCtrl = 0; + automation.currentCtrlValid = false; return; } } } // if there are no hits we default to clearing all the data automation.controllerState = doNothing; - automation.currentCtrl = 0; + //automation.currentCtrl = 0; + automation.currentCtrlValid = false; automation.currentCtrlList = 0; automation.currentTrack = 0; setCursor(); } -void PartCanvas::controllerChanged(Track* /* t */) +void PartCanvas::controllerChanged(Track* t) { - redraw(); + //redraw(); + redraw((QRect(0, mapy(t->y()), width(), rmapy(t->height())))); // TODO Check this - correct? } void PartCanvas::processAutomationMovements(QPoint pos, bool addPoint) @@ -3716,18 +3728,24 @@ void PartCanvas::processAutomationMovements(QPoint pos, bool addPoint) int prevFrame = 0; int nextFrame = -1; + int currFrame = 0; if (automation.controllerState == addNewController) { //printf("adding a new ctrler!\n"); int frame = tempomap.tick2frame(pos.x()); - automation.currentCtrlList->add( frame, 1.0 /*dummy value */); + // FIXME Inefficient to add with wait here, then remove and add with wait again below. Tim. + audio->msgAddACEvent((AudioTrack*)automation.currentTrack, automation.currentCtrlList->id(), frame, 1.0 /*dummy value */); + //song->addACEvent((AudioTrack*)automation.currentTrack, automation.currentCtrlList->id(), frame, 1.0 /*dummy value */); iCtrl ic=automation.currentCtrlList->begin(); - for (; ic !=automation.currentCtrlList->end(); ic++) { + for (; ic !=automation.currentCtrlList->end(); ++ic) { CtrlVal &cv = ic->second; if (cv.frame == frame) { - automation.currentCtrl = &cv; + //automation.currentCtrl = &cv; + automation.currentCtrlFrame = cv.frame; + //automation.currentCtrlVal = cv.val; + automation.currentCtrlValid = true; automation.controllerState = movingController; break; } @@ -3736,22 +3754,38 @@ void PartCanvas::processAutomationMovements(QPoint pos, bool addPoint) // get previous and next frame position to give x bounds for this event. iCtrl ic=automation.currentCtrlList->begin(); - for (; ic !=automation.currentCtrlList->end(); ic++) + iCtrl iprev = ic; + for (; ic !=automation.currentCtrlList->end(); ++ic) { CtrlVal &cv = ic->second; - if (&cv == automation.currentCtrl) + //if (&cv == automation.currentCtrl) + if (cv.frame == automation.currentCtrlFrame) + { + currFrame = cv.frame; break; + } prevFrame = cv.frame; + iprev = ic; } + + iCtrl icc = ic; + if ( ++ic != automation.currentCtrlList->end()) { CtrlVal &cv = ic->second; nextFrame = cv.frame; } - int currFrame = tempomap.tick2frame(pos.x()); - if (currFrame < prevFrame) currFrame=prevFrame+1; - if (nextFrame!=-1 && currFrame > nextFrame) currFrame=nextFrame-1; - automation.currentCtrl->frame = currFrame; - + + // A perfectly straight vertical line (two points with same frame) is impossible: + // there is only one value at t, and the next value at t+1, and so on. + // Also these are maps, not multimaps. p4.0.32 Tim. + int newFrame = tempomap.tick2frame(pos.x()); + //if(currFrame == 0) + // newFrame = 0; // Force first item to stay at x = 0. + //else + if (newFrame <= prevFrame) + newFrame=prevFrame + (icc == automation.currentCtrlList->begin() ? 0: 1); // Only first item is allowed to go to zero x. + if (nextFrame!=-1 && newFrame >= nextFrame) newFrame=nextFrame-1; + int posy=mapy(pos.y()); int tracky = mapy(automation.currentTrack->y()); int trackHeight = automation.currentTrack->height(); @@ -3760,29 +3794,38 @@ void PartCanvas::processAutomationMovements(QPoint pos, bool addPoint) int mouseY = trackHeight - (posy - tracky)-2; double yfraction = ((double)mouseY)/automation.currentTrack->height(); + double min, max; + automation.currentCtrlList->range(&min,&max); + double cvval; if (automation.currentCtrlList->valueType() == VAL_LOG ) { // use db scale for volume - - double cvval = valToDb(yfraction); + cvval = valToDb(yfraction); //printf("calc yfraction = %f v=%f ",yfraction,cvval); - double min, max; - automation.currentCtrlList->range(&min,&max); if (cvval< min) cvval=min; if (cvval>max) cvval=max; - automation.currentCtrl->val=cvval; - } else { - // we need to set curVal between 0 and 1 - double min, max; - automation.currentCtrlList->range(&min,&max); - double cvval = yfraction * (max-min) + min; - + // we need to set val between 0 and 1 (unless integer) + cvval = yfraction * (max-min) + min; + // 'Snap' to integer or boolean + if (automation.currentCtrlList->valueType() == VAL_INT || automation.currentCtrlList->valueType() == VAL_BOOL) + cvval = rint(cvval + 0.1); // LADSPA docs say add a slight bias to avoid rounding errors. Try this. if (cvval< min) cvval=min; if (cvval>max) cvval=max; - automation.currentCtrl->val = cvval; } - controllerChanged(automation.currentTrack); - + + automation.currentCtrlFrame = newFrame; + //automation.currentCtrlVal = cvval; + automation.currentCtrlValid = true; + + if(icc != automation.currentCtrlList->end()) + audio->msgChangeACEvent((AudioTrack*)automation.currentTrack, automation.currentCtrlList->id(), icc->second.frame, newFrame, cvval); + //song->changeACEvent((AudioTrack*)automation.currentTrack, automation.currentCtrlList->id(), icc->second.frame, newFrame, cvval); + else + audio->msgAddACEvent((AudioTrack*)automation.currentTrack, automation.currentCtrlList->id(), newFrame, cvval); + //song->addACEvent((AudioTrack*)automation.currentTrack, automation.currentCtrlList->id(), newFrame, cvval); + + // Not needed. Redraw is now handled by msgXXX(). + //controllerChanged(automation.currentTrack); } } diff --git a/muse2/muse/arranger/pcanvas.h b/muse2/muse/arranger/pcanvas.h index 05f380e6..210557dc 100644 --- a/muse2/muse/arranger/pcanvas.h +++ b/muse2/muse/arranger/pcanvas.h @@ -43,7 +43,9 @@ class NPart : public CItem { enum ControllerVals { doNothing, movingController, addNewController }; struct AutomationObject { - CtrlVal *currentCtrl; + //CtrlVal *currentCtrl; + int currentCtrlFrame; + bool currentCtrlValid; CtrlList *currentCtrlList; Track *currentTrack; bool moveController; @@ -154,8 +156,10 @@ class PartCanvas : public Canvas { PartCanvas(int* raster, QWidget* parent, int, int); void partsChanged(); void cmd(int); - void controllerChanged(Track *t); public slots: void redirKeypress(QKeyEvent* e) { keyPress(e); } - }; + void controllerChanged(Track *t); +}; + #endif + diff --git a/muse2/muse/audio.cpp b/muse2/muse/audio.cpp index 975054b0..668c2a30 100644 --- a/muse2/muse/audio.cpp +++ b/muse2/muse/audio.cpp @@ -80,6 +80,7 @@ const char* seqMsgList[] = { "AUDIO_ERASE_AC_EVENT", "AUDIO_ERASE_RANGE_AC_EVENTS", "AUDIO_ADD_AC_EVENT", + "AUDIO_CHANGE_AC_EVENT", "AUDIO_SET_SOLO", "AUDIO_SET_SEND_METRONOME", "MS_PROCESS", "MS_STOP", "MS_SET_RTC", "MS_UPDATE_POLL_FD", "SEQM_IDLE", "SEQM_SEEK" @@ -675,6 +676,9 @@ void Audio::processMsg(AudioMsg* msg) case AUDIO_ADD_AC_EVENT: msg->snode->addACEvent(msg->ival, msg->a, msg->dval); break; + case AUDIO_CHANGE_AC_EVENT: + msg->snode->changeACEvent(msg->ival, msg->a, msg->b, msg->dval); + break; case AUDIO_SET_SOLO: msg->track->setSolo((bool)msg->ival); break; diff --git a/muse2/muse/audio.h b/muse2/muse/audio.h index e332f516..ea9986c3 100644 --- a/muse2/muse/audio.h +++ b/muse2/muse/audio.h @@ -74,6 +74,7 @@ enum { AUDIO_ERASE_AC_EVENT, AUDIO_ERASE_RANGE_AC_EVENTS, AUDIO_ADD_AC_EVENT, + AUDIO_CHANGE_AC_EVENT, AUDIO_SET_SOLO, AUDIO_SET_SEND_METRONOME, MS_PROCESS, MS_STOP, MS_SET_RTC, MS_UPDATE_POLL_FD, SEQM_IDLE, SEQM_SEEK, @@ -253,6 +254,7 @@ class Audio { void msgEraseACEvent(AudioTrack*, int, int); void msgEraseRangeACEvents(AudioTrack*, int, int, int); void msgAddACEvent(AudioTrack*, int, int, double); + void msgChangeACEvent(AudioTrack* node, int acid, int frame, int newFrame, double val); void msgSetSolo(Track*, bool); void msgSetHwCtrlState(MidiPort*, int, int, int); void msgSetHwCtrlStates(MidiPort*, int, int, int, int); diff --git a/muse2/muse/audiotrack.cpp b/muse2/muse/audiotrack.cpp index b004638f..42229111 100644 --- a/muse2/muse/audiotrack.cpp +++ b/muse2/muse/audiotrack.cpp @@ -253,16 +253,11 @@ void AudioTrack::addPlugin(PluginI* plugin, int idx) const char* name = plugin->paramName(i); float min, max; plugin->range(i, &min, &max); - CtrlValueType t = plugin->valueType(); CtrlList* cl = new CtrlList(id); cl->setRange(min, max); cl->setName(QString(name)); - cl->setValueType(t); - LADSPA_PortRangeHint range = plugin->range(i); - if(LADSPA_IS_HINT_TOGGLED(range.HintDescriptor)) - cl->setMode(CtrlList::DISCRETE); - else - cl->setMode(CtrlList::INTERPOLATE); + cl->setValueType(plugin->ctrlValueType(i)); + cl->setMode(plugin->ctrlMode(i)); cl->setCurVal(plugin->param(i)); addController(cl); } @@ -699,6 +694,22 @@ void AudioTrack::addACEvent(int id, int frame, double val) return; } +//--------------------------------------------------------- +// changeACEvent +//--------------------------------------------------------- + +void AudioTrack::changeACEvent(int id, int frame, int newframe, double newval) +{ + ciCtrlList icl = _controller.find(id); + if(icl == _controller.end()) + return; + CtrlList* cl = icl->second; + iCtrl ic = cl->find(frame); + if(ic != cl->end()) + cl->erase(ic); + cl->insert(std::pair (newframe, CtrlVal(newframe, newval))); +} + //--------------------------------------------------------- // volume //--------------------------------------------------------- @@ -1039,11 +1050,8 @@ bool AudioTrack::readProperties(Xml& xml, const QString& tag) if(ctlfound) { l->setCurVal(p->param(m)); - LADSPA_PortRangeHint range = p->range(m); - if(LADSPA_IS_HINT_TOGGLED(range.HintDescriptor)) - l->setMode(CtrlList::DISCRETE); - else - l->setMode(CtrlList::INTERPOLATE); + l->setValueType(p->ctrlValueType(m)); + l->setMode(p->ctrlMode(m)); } } else @@ -1139,15 +1147,10 @@ void AudioTrack::mapRackPluginsToControllers() // 0.9pre1 med file with broken controller sections they may not be set correct. float min, max; p->range(i, &min, &max); - CtrlValueType t = p->valueType(); l->setRange(min, max); l->setName(QString(p->paramName(i))); - l->setValueType(t); - LADSPA_PortRangeHint rh = p->range(i); - if(LADSPA_IS_HINT_TOGGLED(rh.HintDescriptor)) - l->setMode(CtrlList::DISCRETE); - else - l->setMode(CtrlList::INTERPOLATE); + l->setValueType(p->ctrlValueType(i)); + l->setMode(p->ctrlMode(i)); l->setCurVal(p->param(i)); //l->setDefault(p->defaultValue(i)); } diff --git a/muse2/muse/cliplist/cliplist.cpp b/muse2/muse/cliplist/cliplist.cpp index 96636463..5a5796aa 100644 --- a/muse2/muse/cliplist/cliplist.cpp +++ b/muse2/muse/cliplist/cliplist.cpp @@ -26,7 +26,7 @@ enum { COL_NAME=0, COL_REFS, COL_POS, COL_LEN }; class ClipItem : public QTreeWidgetItem { SndFileR _wf; - virtual QString text(int) const; + //virtual QString text(int) const; public: ClipItem(QTreeWidget*, const SndFileR&); @@ -36,6 +36,10 @@ class ClipItem : public QTreeWidgetItem { ClipItem::ClipItem(QTreeWidget* parent, const SndFileR& w) : QTreeWidgetItem(parent), _wf(w) { + setText(COL_NAME, _wf.name()); + setText(COL_REFS, QString().setNum(_wf.getRefCount())); + setText(COL_POS, QString().setNum(_wf.samplerate())); + setText(COL_LEN, QString().setNum(_wf.samples())); } //--------------------------------------------------------- @@ -71,6 +75,7 @@ static QString samples2smpte(int samples) } #endif +/* //--------------------------------------------------------- // text //--------------------------------------------------------- @@ -91,6 +96,7 @@ QString ClipItem::text(int col) const } return s; } +*/ //--------------------------------------------------------- // ClipListEdit diff --git a/muse2/muse/ctrl.cpp b/muse2/muse/ctrl.cpp index 65a04ba1..0a863423 100644 --- a/muse2/muse/ctrl.cpp +++ b/muse2/muse/ctrl.cpp @@ -6,6 +6,7 @@ // controller handling for mixer automation // // (C) Copyright 2003 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Time E. Real (terminator356 on users dot sourceforge dot net) //========================================================= @@ -83,66 +84,86 @@ CtrlList::CtrlList() double CtrlList::value(int frame) { - if (!automation || empty()) { - return _curVal; - } + // Changed by Tim. p4.0.32... + + ///if (!automation || empty()) + /// return _curVal; + if(empty()) + return _curVal; + double rv; 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(); + ///ciCtrl i = end(); --i; - const CtrlVal& val = i->second; - _curVal = val.val; + ///const CtrlVal& val = i->second; + ///_curVal = val.val; + rv = i->second.val; } else if(_mode == DISCRETE) { if(i == begin()) - _curVal = _default; + { + ///_curVal = _default; + //if(i->second.frame == frame) + rv = i->second.val; + //else + // rv = _default; + } else { --i; - const CtrlVal& val = i->second; - _curVal = val.val; + ///const CtrlVal& val = i->second; + ///_curVal = val.val; + rv = i->second.val; } } else { - int frame2 = i->second.frame; - double val2 = i->second.val; - int frame1; - double val1; + ///int frame2 = i->second.frame; + ///double val2 = i->second.val; + ///int frame1; + ///double val1; if (i == begin()) { - frame1 = 0; - val1 = _default; + ///frame1 = 0; + ///val1 = _default; + rv = i->second.val; } else { + int frame2 = i->second.frame; + double val2 = i->second.val; --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; + ///frame1 = i->second.frame; + ///val1 = i->second.val; + int frame1 = i->second.frame; + double 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; + rv = val1; + } } // printf("autoVal %d %f\n", frame, _curVal); - return _curVal; + ///return _curVal; + return rv; } @@ -152,9 +173,8 @@ double CtrlList::value(int frame) void CtrlList::setCurVal(double val) { _curVal = val; - if (size() < 2) { - add(0,val); - } + //if (size() < 2) // Removed p4.0.32 + // add(0,val); } //--------------------------------------------------------- @@ -175,16 +195,14 @@ void CtrlList::add(int frame, double val) // del //--------------------------------------------------------- -void CtrlList::del(int /* frame*/) +void CtrlList::del(int frame) { - /* iCtrl e = find(frame); if (e == end()) { - printf("CtrlList::del(%d): not found\n", frame); + //printf("CtrlList::del(%d): not found\n", frame); return; } erase(e); - */ } //--------------------------------------------------------- diff --git a/muse2/muse/ctrl.h b/muse2/muse/ctrl.h index 34a31211..14f23643 100644 --- a/muse2/muse/ctrl.h +++ b/muse2/muse/ctrl.h @@ -6,6 +6,7 @@ // controller for mixer automation // // (C) Copyright 2003-2004 Werner Schweer (ws@seh.de) +// (C) Copyright 2011 Time E. Real (terminator356 on users dot sourceforge dot net) //========================================================= #ifndef __CTRL_H__ @@ -120,8 +121,8 @@ class CtrlList : public std::map > { void setValueType(CtrlValueType t) { _valueType = t; } double value(int frame); - void add(int tick, double value); - void del(int tick); + void add(int frame, double value); + void del(int frame); void read(Xml& xml); void setColor( QColor c ) { _displayColor = c;} diff --git a/muse2/muse/dssihost.cpp b/muse2/muse/dssihost.cpp index 850fc8b8..72456dd1 100644 --- a/muse2/muse/dssihost.cpp +++ b/muse2/muse/dssihost.cpp @@ -1092,17 +1092,8 @@ bool DssiSynthIF::init(DssiSynth* s) } cl->setRange(min, max); cl->setName(QString(name)); - LADSPA_PortRangeHint range = ld->PortRangeHints[k]; - if(LADSPA_IS_HINT_TOGGLED(range.HintDescriptor)) - { - cl->setMode(CtrlList::DISCRETE); - cl->setValueType(VAL_BOOL); - } - else - { - cl->setMode(CtrlList::INTERPOLATE); - cl->setValueType(VAL_LINEAR); - } + cl->setValueType(ladspaCtrlValueType(ld, k)); + cl->setMode(ladspaCtrlMode(ld, k)); ld->connect_port(handle, k, &controls[cip].val); @@ -3627,6 +3618,8 @@ const char* DssiSynthIF::paramOutName(unsigned long i) { return (synth && //LADSPA_PortRangeHint DssiSynthIF::range(unsigned long i) { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->PortRangeHints[i] : 0; } LADSPA_PortRangeHint DssiSynthIF::range(unsigned long i) { return synth->dssi->LADSPA_Plugin->PortRangeHints[controls[i].idx]; } LADSPA_PortRangeHint DssiSynthIF::rangeOut(unsigned long i) { return synth->dssi->LADSPA_Plugin->PortRangeHints[controlsOut[i].idx]; } +CtrlValueType DssiSynthIF::ctrlValueType(unsigned long i) const { return ladspaCtrlValueType(synth->dssi->LADSPA_Plugin, controls[i].idx); } +CtrlList::Mode DssiSynthIF::ctrlMode(unsigned long i) const { return ladspaCtrlMode(synth->dssi->LADSPA_Plugin, controls[i].idx); }; #else //DSSI_SUPPORT diff --git a/muse2/muse/dssihost.h b/muse2/muse/dssihost.h index d46cb570..12be7b50 100644 --- a/muse2/muse/dssihost.h +++ b/muse2/muse/dssihost.h @@ -282,6 +282,8 @@ class DssiSynthIF : public SynthIF, public PluginIBase const char* paramOutName(unsigned long /*i*/); LADSPA_PortRangeHint range(unsigned long /*i*/); LADSPA_PortRangeHint rangeOut(unsigned long /*i*/); + CtrlValueType ctrlValueType(unsigned long /*i*/) const; + CtrlList::Mode ctrlMode(unsigned long /*i*/) const; friend class DssiSynth; }; diff --git a/muse2/muse/mixer/astrip.cpp b/muse2/muse/mixer/astrip.cpp index 658a4970..97ddc98c 100644 --- a/muse2/muse/mixer/astrip.cpp +++ b/muse2/muse/mixer/astrip.cpp @@ -209,15 +209,19 @@ void AudioStrip::songChanged(int val) if (autoType && (val & SC_AUTOMATION)) { autoType->blockSignals(true); autoType->setCurrentItem(track->automationType()); + QPalette palette; if(track->automationType() == AUTO_TOUCH || track->automationType() == AUTO_WRITE) { - QPalette palette; palette.setColor(QPalette::Button, QColor(Qt::red)); autoType->setPalette(palette); } + else if(track->automationType() == AUTO_READ) + { + palette.setColor(QPalette::Button, QColor(Qt::green)); + autoType->setPalette(palette); + } else { - QPalette palette; palette.setColor(QPalette::Button, qApp->palette().color(QPalette::Active, QPalette::Background)); autoType->setPalette(palette); } @@ -394,13 +398,14 @@ void AudioStrip::volumeChanged(double val) else vol = pow(10.0, val/20.0); volume = vol; - //audio->msgSetVolume((AudioTrack*)track, vol); + audio->msgSetVolume((AudioTrack*)track, vol); // p4.0.21 audio->msgXXX waits. Do we really need to? - ((AudioTrack*)track)->setVolume(vol); + //((AudioTrack*)track)->setVolume(vol); ((AudioTrack*)track)->recordAutomation(AC_VOLUME, vol); - song->update(SC_TRACK_MODIFIED); // for graphical automation update + //song->update(SC_TRACK_MODIFIED); // for graphical automation update + //song->controllerChange(track); } //--------------------------------------------------------- @@ -422,9 +427,9 @@ void AudioStrip::volumePressed() else vol = pow(10.0, val/20.0); volume = vol; - //audio->msgSetVolume((AudioTrack*)track, volume); + audio->msgSetVolume((AudioTrack*)track, volume); // p4.0.21 audio->msgXXX waits. Do we really need to? - ((AudioTrack*)track)->setVolume(volume); + //((AudioTrack*)track)->setVolume(volume); ((AudioTrack*)track)->startAutoRecord(AC_VOLUME, volume); } @@ -468,9 +473,9 @@ void AudioStrip::volLabelChanged(double val) vol = pow(10.0, val/20.0); volume = vol; slider->setValue(val); - //audio->msgSetVolume((AudioTrack*)track, vol); + audio->msgSetVolume((AudioTrack*)track, vol); // p4.0.21 audio->msgXXX waits. Do we really need to? - ((AudioTrack*)track)->setVolume(vol); + //((AudioTrack*)track)->setVolume(vol); ((AudioTrack*)track)->startAutoRecord(AC_VOLUME, vol); } @@ -486,9 +491,9 @@ void AudioStrip::panChanged(double val) track->enablePanController(false); panVal = val; - //audio->msgSetPan(((AudioTrack*)track), val); + audio->msgSetPan(((AudioTrack*)track), val); // p4.0.21 audio->msgXXX waits. Do we really need to? - ((AudioTrack*)track)->setPan(val); + //((AudioTrack*)track)->setPan(val); ((AudioTrack*)track)->recordAutomation(AC_PAN, val); } @@ -504,9 +509,9 @@ void AudioStrip::panPressed() track->enablePanController(false); panVal = pan->value(); - //audio->msgSetPan(((AudioTrack*)track), panVal); + audio->msgSetPan(((AudioTrack*)track), panVal); // p4.0.21 audio->msgXXX waits. Do we really need to? - ((AudioTrack*)track)->setPan(panVal); + //((AudioTrack*)track)->setPan(panVal); ((AudioTrack*)track)->startAutoRecord(AC_PAN, panVal); } @@ -541,9 +546,9 @@ void AudioStrip::panLabelChanged(double val) panVal = val; pan->setValue(val); - //audio->msgSetPan((AudioTrack*)track, val); + audio->msgSetPan((AudioTrack*)track, val); // p4.0.21 audio->msgXXX waits. Do we really need to? - ((AudioTrack*)track)->setPan(val); + //((AudioTrack*)track)->setPan(val); ((AudioTrack*)track)->startAutoRecord(AC_PAN, val); } @@ -935,15 +940,19 @@ AudioStrip::AudioStrip(QWidget* parent, AudioTrack* at) autoType->addAction(tr("Write"), AUTO_WRITE); autoType->setCurrentItem(t->automationType()); + QPalette palette; if(t->automationType() == AUTO_TOUCH || t->automationType() == AUTO_WRITE) { - QPalette palette; palette.setColor(QPalette::Button, QColor(Qt::red)); autoType->setPalette(palette); } + else if(t->automationType() == AUTO_READ) + { + palette.setColor(QPalette::Button, QColor(Qt::green)); + autoType->setPalette(palette); + } else { - QPalette palette; palette.setColor(QPalette::Button, qApp->palette().color(QPalette::Active, QPalette::Background)); autoType->setPalette(palette); } diff --git a/muse2/muse/mixer/panknob.cpp b/muse2/muse/mixer/panknob.cpp index c99f0bd5..598bf5bf 100644 --- a/muse2/muse/mixer/panknob.cpp +++ b/muse2/muse/mixer/panknob.cpp @@ -27,9 +27,9 @@ PanKnob::PanKnob(QWidget* parent, AudioTrack* s) void PanKnob::valueChanged(double val) { - //audio->msgSetPan(src, val); + audio->msgSetPan(src, val); // p4.0.21 audio->msgXXX waits. Do we really need to? - src->setPan(val); + //src->setPan(val); } diff --git a/muse2/muse/mplugins/rhythmbase.ui b/muse2/muse/mplugins/rhythmbase.ui index 21373690..7d3458d1 100644 --- a/muse2/muse/mplugins/rhythmbase.ui +++ b/muse2/muse/mplugins/rhythmbase.ui @@ -542,9 +542,11 @@ Random Rhythm Generator is not enabled yet! 38 - - Tools - + + + Tools + + diff --git a/muse2/muse/plugin.cpp b/muse2/muse/plugin.cpp index 215a7844..e6027c6f 100644 --- a/muse2/muse/plugin.cpp +++ b/muse2/muse/plugin.cpp @@ -445,7 +445,44 @@ float midi2LadspaValue(const LADSPA_Descriptor* plugin, unsigned long port, int return ret; } +//--------------------------------------------------------- +// ladspaCtrlValueType +//--------------------------------------------------------- +CtrlValueType ladspaCtrlValueType(const LADSPA_Descriptor* plugin, int port) +{ + LADSPA_PortRangeHint range = plugin->PortRangeHints[port]; + LADSPA_PortRangeHintDescriptor desc = range.HintDescriptor; + + if(desc & LADSPA_HINT_INTEGER) + return VAL_INT; + else if(desc & LADSPA_HINT_LOGARITHMIC) + return VAL_LOG; + else if(desc & LADSPA_HINT_TOGGLED) + return VAL_BOOL; + else + return VAL_LINEAR; +} + +//--------------------------------------------------------- +// ladspaCtrlMode +//--------------------------------------------------------- + +CtrlList::Mode ladspaCtrlMode(const LADSPA_Descriptor* plugin, int port) +{ + LADSPA_PortRangeHint range = plugin->PortRangeHints[port]; + LADSPA_PortRangeHintDescriptor desc = range.HintDescriptor; + + if(desc & LADSPA_HINT_INTEGER) + return CtrlList::DISCRETE; + else if(desc & LADSPA_HINT_LOGARITHMIC) + return CtrlList::INTERPOLATE; + else if(desc & LADSPA_HINT_TOGGLED) + return CtrlList::DISCRETE; + else + return CtrlList::INTERPOLATE; +} + // Works but not needed. /* //--------------------------------------------------------- @@ -1002,6 +1039,24 @@ float Plugin::defaultValue(unsigned long port) const */ } +//--------------------------------------------------------- +// ctrlValueType +//--------------------------------------------------------- + +CtrlValueType Plugin::ctrlValueType(unsigned long i) const + { + return ladspaCtrlValueType(plugin, i); + } + +//--------------------------------------------------------- +// ctrlMode +//--------------------------------------------------------- + +CtrlList::Mode Plugin::ctrlMode(unsigned long i) const + { + return ladspaCtrlMode(plugin, i); + } + //--------------------------------------------------------- // loadPluginLib //--------------------------------------------------------- @@ -1699,20 +1754,11 @@ void PluginI::updateControllers() for(unsigned long i = 0; i < controlPorts; ++i) //audio->msgSetPluginCtrlVal(this, genACnum(_id, i), controls[i].val); // p3.3.43 - //audio->msgSetPluginCtrlVal(_track, genACnum(_id, i), controls[i].val); + audio->msgSetPluginCtrlVal(_track, genACnum(_id, i), controls[i].val); // p4.0.21 audio->msgXXX waits. Do we really need to? - _track->setPluginCtrlVal(genACnum(_id, i), controls[i].val); + //_track->setPluginCtrlVal(genACnum(_id, i), controls[i].val); // TODO A faster bulk message } -//--------------------------------------------------------- -// valueType -//--------------------------------------------------------- - -CtrlValueType PluginI::valueType() const - { - return VAL_LINEAR; - } - //--------------------------------------------------------- // setChannel //--------------------------------------------------------- @@ -3718,9 +3764,9 @@ void PluginGui::ctrlPressed(int param) if(track) { // p3.3.43 - //audio->msgSetPluginCtrlVal(track, id, val); + audio->msgSetPluginCtrlVal(track, id, val); // p4.0.21 audio->msgXXX waits. Do we really need to? - track->setPluginCtrlVal(id, val); + //track->setPluginCtrlVal(id, val); track->startAutoRecord(id, val); } @@ -3737,9 +3783,9 @@ void PluginGui::ctrlPressed(int param) if(track) { // p3.3.43 - //audio->msgSetPluginCtrlVal(track, id, val); + audio->msgSetPluginCtrlVal(track, id, val); // p4.0.21 audio->msgXXX waits. Do we really need to? - track->setPluginCtrlVal(id, val); + //track->setPluginCtrlVal(id, val); track->startAutoRecord(id, val); } @@ -3831,9 +3877,9 @@ void PluginGui::sliderChanged(double val, int param) if(track) { // p3.3.43 - //audio->msgSetPluginCtrlVal(track, id, val); + audio->msgSetPluginCtrlVal(track, id, val); // p4.0.21 audio->msgXXX waits. Do we really need to? - track->setPluginCtrlVal(id, val); + //track->setPluginCtrlVal(id, val); track->recordAutomation(id, val); } @@ -3875,9 +3921,9 @@ void PluginGui::labelChanged(double val, int param) if(track) { // p3.3.43 - //audio->msgSetPluginCtrlVal(track, id, val); + audio->msgSetPluginCtrlVal(track, id, val); // p4.0.21 audio->msgXXX waits. Do we really need to? - track->setPluginCtrlVal(id, val); + //track->setPluginCtrlVal(id, val); track->startAutoRecord(id, val); } @@ -4277,9 +4323,9 @@ void PluginGui::guiParamChanged(int idx) //if(track) //{ // p3.3.43 - //audio->msgSetPluginCtrlVal(track, id, val); + audio->msgSetPluginCtrlVal(track, id, val); // p4.0.21 audio->msgXXX waits. Do we really need to? - track->setPluginCtrlVal(id, val); + //track->setPluginCtrlVal(id, val); switch(type) { @@ -4413,9 +4459,9 @@ void PluginGui::guiSliderPressed(int idx) //audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); // p3.3.43 - //audio->msgSetPluginCtrlVal(track, id, val); + audio->msgSetPluginCtrlVal(track, id, val); // p4.0.21 audio->msgXXX waits. Do we really need to? - track->setPluginCtrlVal(id, val); + //track->setPluginCtrlVal(id, val); track->startAutoRecord(id, val); diff --git a/muse2/muse/plugin.h b/muse2/muse/plugin.h index 30cc5912..dec77d2f 100644 --- a/muse2/muse/plugin.h +++ b/muse2/muse/plugin.h @@ -177,6 +177,8 @@ class Plugin { //double defaultValue(unsigned long port) const; float defaultValue(unsigned long port) const; // p4.0.21 void range(unsigned long i, float*, float*) const; + CtrlValueType ctrlValueType(unsigned long /*i*/) const; + CtrlList::Mode ctrlMode(unsigned long /*i*/) const; const char* portName(unsigned long i) { return plugin ? plugin->PortNames[i] : 0; @@ -354,6 +356,9 @@ class PluginIBase virtual const char* paramOutName(unsigned long /*i*/) = 0; virtual LADSPA_PortRangeHint range(unsigned long /*i*/) = 0; virtual LADSPA_PortRangeHint rangeOut(unsigned long /*i*/) = 0; + + virtual CtrlValueType ctrlValueType(unsigned long /*i*/) const = 0; + virtual CtrlList::Mode ctrlMode(unsigned long /*i*/) const = 0; QString dssi_ui_filename() const; //virtual void showGui(bool) = 0; // p4.0.20 @@ -499,7 +504,6 @@ class PluginI : public PluginIBase { QString pluginLabel() const { return _plugin->label(); } QString label() const { return _label; } QString name() const { return _name; } - CtrlValueType valueType() const; QString lib() const { return _plugin->lib(); } QString dirPath() const { return _plugin->dirPath(); } QString fileName() const { return _plugin->fileName(); } @@ -560,6 +564,8 @@ class PluginI : public PluginIBase { LADSPA_PortRangeHint range(unsigned long i) { return _plugin->range(controls[i].idx); } LADSPA_PortRangeHint rangeOut(unsigned long i) { return _plugin->range(controlsOut[i].idx); } bool inPlaceCapable() const { return _plugin->inPlaceCapable(); } + CtrlValueType ctrlValueType(unsigned long i) const { return _plugin->ctrlValueType(controls[i].idx); } + CtrlList::Mode ctrlMode(unsigned long i) const { return _plugin->ctrlMode(controls[i].idx); }; }; //--------------------------------------------------------- @@ -650,6 +656,8 @@ extern bool ladspaDefaultValue(const LADSPA_Descriptor* plugin, unsigned long po extern void ladspaControlRange(const LADSPA_Descriptor* plugin, unsigned long port, float* min, float* max); extern bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, unsigned long port, int ctlnum, int* min, int* max, int* def); extern float midi2LadspaValue(const LADSPA_Descriptor* plugin, unsigned long port, int ctlnum, int val); +extern CtrlValueType ladspaCtrlValueType(const LADSPA_Descriptor* plugin, int port); +extern CtrlList::Mode ladspaCtrlMode(const LADSPA_Descriptor* plugin, int port); //extern MidiController* ladspa2MidiController(const LADSPA_Descriptor* plugin, unsigned long port, int ctlnum); #endif diff --git a/muse2/muse/seqmsg.cpp b/muse2/muse/seqmsg.cpp index 57aadc18..035ee949 100644 --- a/muse2/muse/seqmsg.cpp +++ b/muse2/muse/seqmsg.cpp @@ -338,6 +338,7 @@ void Audio::msgSetVolume(AudioTrack* src, double val) msg.dval = val; sendMsg(&msg); //muse->arranger->controllerChanged(src); + song->controllerChange(src); } //--------------------------------------------------------- @@ -352,6 +353,7 @@ void Audio::msgSetPan(AudioTrack* node, double val) msg.dval = val; sendMsg(&msg); //muse->arranger->controllerChanged(node); + song->controllerChange(node); } //--------------------------------------------------------- @@ -513,6 +515,7 @@ void Audio::msgSetPluginCtrlVal(AudioTrack* track, int param, double val) msg.snode = track; sendMsg(&msg); //muse->arranger->controllerChanged(track); + song->controllerChange(track); } //--------------------------------------------------------- @@ -529,6 +532,7 @@ void Audio::msgSwapControllerIDX(AudioTrack* node, int idx1, int idx2) msg.b = idx2; sendMsg(&msg); //muse->arranger->controllerChanged(node); + song->controllerChange(node); } //--------------------------------------------------------- @@ -544,6 +548,7 @@ void Audio::msgClearControllerEvents(AudioTrack* node, int acid) msg.ival = acid; sendMsg(&msg); //muse->arranger->controllerChanged(node); + song->controllerChange(node); } //--------------------------------------------------------- @@ -588,6 +593,7 @@ void Audio::msgEraseACEvent(AudioTrack* node, int acid, int frame) msg.a = frame; sendMsg(&msg); //muse->arranger->controllerChanged(node); + song->controllerChange(node); } //--------------------------------------------------------- @@ -605,6 +611,7 @@ void Audio::msgEraseRangeACEvents(AudioTrack* node, int acid, int frame1, int fr msg.b = frame2; sendMsg(&msg); //muse->arranger->controllerChanged(node); + song->controllerChange(node); } //--------------------------------------------------------- @@ -622,6 +629,26 @@ void Audio::msgAddACEvent(AudioTrack* node, int acid, int frame, double val) msg.dval = val; sendMsg(&msg); //muse->arranger->controllerChanged(node); + song->controllerChange(node); +} + +//--------------------------------------------------------- +// msgChangeACEvent +//--------------------------------------------------------- + +void Audio::msgChangeACEvent(AudioTrack* node, int acid, int frame, int newFrame, double val) +{ + AudioMsg msg; + + msg.id = AUDIO_CHANGE_AC_EVENT; + msg.snode = node; + msg.ival = acid; + msg.a = frame; + msg.b = newFrame; + msg.dval = val; + sendMsg(&msg); + //muse->arranger->controllerChanged(node); + song->controllerChange(node); } //--------------------------------------------------------- diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index 6d0541a3..9d1c3afb 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -714,6 +714,23 @@ void Song::changeAllPortDrumCtrlEvents(bool add, bool drumonly) } } +void Song::addACEvent(AudioTrack* t, int acid, int frame, double val) +{ + audio->msgAddACEvent(t, acid, frame, val); + emit controllerChanged(t); +} + +void Song::changeACEvent(AudioTrack* t, int acid, int frame, int newFrame, double val) +{ + audio->msgChangeACEvent(t, acid, frame, newFrame, val); + emit controllerChanged(t); +} + +void Song::controllerChange(Track* t) +{ + emit controllerChanged(t); +} + //--------------------------------------------------------- // cmdAddRecordedEvents // add recorded Events into part diff --git a/muse2/muse/song.h b/muse2/muse/song.h index 45751418..bb96b619 100644 --- a/muse2/muse/song.h +++ b/muse2/muse/song.h @@ -248,6 +248,10 @@ class Song : public QObject { void cmdChangeWave(QString original, QString tmpfile, unsigned sx, unsigned ex); void remapPortDrumCtrlEvents(int mapidx, int newnote, int newchan, int newport); void changeAllPortDrumCtrlEvents(bool add, bool drumonly = false); + + void addACEvent(AudioTrack* t, int acid, int frame, double val); + void changeACEvent(AudioTrack* t, int acid, int frame, int newFrame, double val); + void controllerChange(Track* t); //----------------------------------------- // part manipulations @@ -400,7 +404,8 @@ class Song : public QObject { void quantizeChanged(bool); void markerChanged(int); void midiPortsChanged(); - void midiNote(int pitch, int velo); + void midiNote(int pitch, int velo); + void controllerChanged(Track* t); }; extern Song* song; diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index 5f358375..eae74ccf 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -139,7 +139,9 @@ int Track::y() const return yy; yy += (*it)->height(); } - printf("Track::y(%s): track not in tracklist\n", name().toLatin1().constData()); + // FIXME Get this when loading a song with automation graphs showing. Benign. Likely song not fully loaded yet. p4.0.32 + if(debugMsg) + printf("Track::y(%s): track not in tracklist\n", name().toLatin1().constData()); return -1; } diff --git a/muse2/muse/track.h b/muse2/muse/track.h index 50870166..de766e32 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -428,6 +428,7 @@ class AudioTrack : public Track { void eraseACEvent(int, int); void eraseRangeACEvents(int, int, int); void addACEvent(int, int, double); + void changeACEvent(int id, int frame, int newframe, double newval); }; //--------------------------------------------------------- -- cgit v1.2.3 From fe843e9d861971a7053e26570d7854f048e3eb7e Mon Sep 17 00:00:00 2001 From: "Tim E. Real" Date: Mon, 29 Aug 2011 23:16:40 +0000 Subject: Changed template songs to reflect new audio controller behaviour. --- muse2/share/templates/audio.med | 20 -------------------- muse2/share/templates/default.med | 3 --- muse2/share/templates/monorecord.med | 6 ------ muse2/share/templates/synti.med | 8 -------- 4 files changed, 37 deletions(-) diff --git a/muse2/share/templates/audio.med b/muse2/share/templates/audio.med index 35f5d8f5..6c9dad29 100644 --- a/muse2/share/templates/audio.med +++ b/muse2/share/templates/audio.med @@ -399,10 +399,8 @@ 0 0 - 0 0, - 0 0, @@ -422,10 +420,8 @@ 0 0 - 0 0, - 0 0, @@ -445,10 +441,8 @@ 0 0 - 0 0, - 0 0, @@ -468,10 +462,8 @@ 0 0 - 0 0, - 0 0, @@ -491,10 +483,8 @@ 0 0 - 0 0, - 0 0, @@ -514,10 +504,8 @@ 0 0 - 0 0, - 0 0, @@ -535,10 +523,8 @@ 0 1 - 0 0, - 0 0, @@ -556,10 +542,8 @@ 0 1 - 0 0, - 0 0, @@ -579,10 +563,8 @@ 0 0 - 0 0, - 0 0, @@ -600,10 +582,8 @@ 0 1 - 0 0, - 0 0, diff --git a/muse2/share/templates/default.med b/muse2/share/templates/default.med index 11d2f33a..db22ffc2 100644 --- a/muse2/share/templates/default.med +++ b/muse2/share/templates/default.med @@ -397,13 +397,10 @@ 0 0 - 0 1, - 0 0, - 0 0, diff --git a/muse2/share/templates/monorecord.med b/muse2/share/templates/monorecord.med index bcb469f5..5bbb48dd 100644 --- a/muse2/share/templates/monorecord.med +++ b/muse2/share/templates/monorecord.med @@ -396,10 +396,8 @@ 0 0 - 0 1.02164, - 0 0, @@ -418,10 +416,8 @@ 0 0 - 0 1.02164, - 0 0, @@ -439,10 +435,8 @@ 0 0 - 0 1.30152, - 0 0, diff --git a/muse2/share/templates/synti.med b/muse2/share/templates/synti.med index da39fee0..c2efb6b5 100644 --- a/muse2/share/templates/synti.med +++ b/muse2/share/templates/synti.med @@ -826,10 +826,8 @@ 0 0 - 0 1.02164, - 0 0, @@ -847,10 +845,8 @@ 0 0 - 0 1.41091, - 0 0, @@ -873,10 +869,8 @@ 0 0 - 0 1.02164, - 0 -0.04, @@ -909,10 +903,8 @@ 0 0 - 0 0, - 0 0, -- cgit v1.2.3 From 0f08cac5b167b989ccf3607a231ee5e992cdee05 Mon Sep 17 00:00:00 2001 From: "Tim E. Real" Date: Tue, 30 Aug 2011 01:14:15 +0000 Subject: Small fix - could not add new points to discrete automation graphs. --- muse2/muse/arranger/pcanvas.cpp | 8 +++++--- muse2/muse/song.cpp | 8 ++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 57bf71ba..ef45c9df 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -3587,6 +3587,7 @@ void PartCanvas::checkAutomation(Track * t, const QPoint &pointer, bool addNewCt double min, max; cl->range(&min,&max); //bool discrete = cl->valueType() == VAL_BOOL || cl->mode() == CtrlList::DISCRETE; // Tim + bool discrete = cl->mode() == CtrlList::DISCRETE; // First check that there IS automation, ic == cl->end means no automation if (ic == cl->end()) @@ -3611,7 +3612,7 @@ void PartCanvas::checkAutomation(Track * t, const QPoint &pointer, bool addNewCt } else y = (y-min)/(max-min); // we need to set curVal between 0 and 1 - + ypixel = mapy(trackY + trackH - 2 - y * trackH); xpixel = mapx(tempomap.frame2tick(ic->second.frame)); @@ -3625,7 +3626,7 @@ void PartCanvas::checkAutomation(Track * t, const QPoint &pointer, bool addNewCt double firstX=oldX; double lastX=xpixel; double firstY=oldY; - double lastY=ypixel; + double lastY = discrete ? oldY : ypixel; double proportion = (currX-firstX)/(lastX-firstX); @@ -3807,7 +3808,8 @@ void PartCanvas::processAutomationMovements(QPoint pos, bool addPoint) // we need to set val between 0 and 1 (unless integer) cvval = yfraction * (max-min) + min; // 'Snap' to integer or boolean - if (automation.currentCtrlList->valueType() == VAL_INT || automation.currentCtrlList->valueType() == VAL_BOOL) + //if (automation.currentCtrlList->valueType() == VAL_INT || automation.currentCtrlList->valueType() == VAL_BOOL) + if (automation.currentCtrlList->mode() == CtrlList::DISCRETE) cvval = rint(cvval + 0.1); // LADSPA docs say add a slight bias to avoid rounding errors. Try this. if (cvval< min) cvval=min; if (cvval>max) cvval=max; diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index 9d1c3afb..e4749d19 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -2517,13 +2517,13 @@ int Song::execAutomationCtlPopup(AudioTrack* track, const QPoint& menupos, int a if(icl != track->controller()->end()) { CtrlList *cl = icl->second; - canAdd = true; - ctlval = cl->curVal(); + canAdd = true; + int frame = pos[0].frame(); + ctlval = cl->curVal(); + //ctlval = cl->value(frame); // p4.0.32 count = cl->size(); if(count) { - int frame = pos[0].frame(); - iCtrl s = cl->lower_bound(frame); iCtrl e = cl->upper_bound(frame); -- cgit v1.2.3 From 1414d8185ca9bc0b078cff7512482f013e28bde3 Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Thu, 1 Sep 2011 16:55:20 +0000 Subject: fixed "THIS SHOULD NEVER HAPPEN" in score editor --- muse2/muse/midiedit/scoreedit.cpp | 37 ++++++++++++++++++++++--------------- muse2/muse/midiedit/scoreedit.h | 2 +- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 4b2db2fc..fcac6463 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -111,6 +111,12 @@ QString IntToQStr(int i); //which exceed their staves' y-boundaries, so that these boundaries //must be expanded. + + +#define MAX_QUANT_POWER 5 + + + QString create_random_string(int len=8) { string result; @@ -313,10 +319,10 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos) quant_toolbar->setObjectName("Quantisation settings"); quant_toolbar->addWidget(new QLabel(tr("Quantisation:"), quant_toolbar)); quant_combobox = new QComboBox(this); - quant_combobox->addItem("2"); // if you add or remove items from - quant_combobox->addItem("4"); // here, also change quant_mapper[] - quant_combobox->addItem("8"); // in ScoreCanvas::set_quant()! - quant_combobox->addItem("16"); + quant_combobox->addItem("2"); // if you add or remove items from + quant_combobox->addItem("4"); // here, also change quant_mapper[] + quant_combobox->addItem("8"); // in ScoreCanvas::set_quant()! + quant_combobox->addItem("16"); // and MAX_QUANT_POWER (must be log2(largest_value)) quant_combobox->addItem("32"); connect(quant_combobox, SIGNAL(currentIndexChanged(int)), score_canvas, SLOT(set_quant(int))); quant_toolbar->addWidget(quant_combobox); @@ -1963,7 +1969,7 @@ vector create_emphasize_list(int num, int denom) //whole, half, quarter, eighth = 0,1,2,3 //NOT: 1,2,4,8! (think of 2^foo) //len is in ticks -list parse_note_len(int len_ticks, int begin_tick, vector& foo, int quant_power2, bool allow_dots, bool allow_normal) +list parse_note_len(int len_ticks, int begin_tick, vector& foo, bool allow_dots, bool allow_normal) { list retval; @@ -1974,9 +1980,9 @@ list parse_note_len(int len_ticks, int begin_tick, vector& foo, if (allow_normal) { - int dot_max = allow_dots ? quant_power2 : 0; + int dot_max = allow_dots ? MAX_QUANT_POWER : 0; - for (int i=0;i<=quant_power2;i++) + for (int i=0;i<=MAX_QUANT_POWER;i++) for (int j=0;j<=dot_max-i;j++) if (calc_len(i,j) == len_ticks) { @@ -2005,8 +2011,8 @@ list parse_note_len(int len_ticks, int begin_tick, vector& foo, if (heavyDebugMsg) cout << "add " << len_now << " ticks" << endl; if (allow_dots) { - for (int i=0;i<=quant_power2;i++) - for (int j=0;j<=quant_power2-i;j++) + for (int i=0;i<=MAX_QUANT_POWER;i++) + for (int j=0;j<=MAX_QUANT_POWER-i;j++) if (calc_len(i,j) == len_now) { retval.push_back(note_len_t (i,j)); @@ -2016,7 +2022,7 @@ list parse_note_len(int len_ticks, int begin_tick, vector& foo, if (len_now) //the above failed or allow_dots=false { - for (int i=0; i<=quant_power2; i++) + for (int i=0; i<=MAX_QUANT_POWER; i++) { int tmp=calc_len(i,0); if (tmp <= len_now) @@ -2170,7 +2176,7 @@ void staff_t::create_itemlist() { if (heavyDebugMsg) printf("\tend-of-measure: set rest at %i with len %i\n",lastevent,rest); - list lens=parse_note_len(rest,lastevent-last_measure,emphasize_list,parent->quant_power2(),DOTTED_RESTS,UNSPLIT_RESTS); + list lens=parse_note_len(rest,lastevent-last_measure,emphasize_list,DOTTED_RESTS,UNSPLIT_RESTS); unsigned tmppos=lastevent; for (list::iterator x=lens.begin(); x!=lens.end(); x++) { @@ -2198,7 +2204,7 @@ void staff_t::create_itemlist() // no need to check if the rest crosses measure boundaries; // it can't. - list lens=parse_note_len(rest,lastevent-last_measure,emphasize_list,parent->quant_power2(),DOTTED_RESTS,UNSPLIT_RESTS); + list lens=parse_note_len(rest,lastevent-last_measure,emphasize_list,DOTTED_RESTS,UNSPLIT_RESTS); unsigned tmppos=lastevent; for (list::iterator x=lens.begin(); x!=lens.end(); x++) { @@ -2239,7 +2245,7 @@ void staff_t::create_itemlist() eventlist.insert(pair(t+len, FloEvent(t+len,pitch, velo,0,FloEvent::NOTE_OFF,it->second.source_part, it->second.source_event))); } - list lens=parse_note_len(tmplen,t-last_measure,emphasize_list,parent->quant_power2(),true,true); + list lens=parse_note_len(tmplen,t-last_measure,emphasize_list,true,true); unsigned tmppos=t; int n_lens=lens.size(); int count=0; @@ -2640,7 +2646,7 @@ group_them_again: itemlist[t].insert( FloItem(FloItem::NOTE_END,tmp.pos,0,0) ); - list lens=parse_note_len(len_ticks_remaining,t-last_measure,emphasize_list,parent->quant_power2(),true,true); + list lens=parse_note_len(len_ticks_remaining,t-last_measure,emphasize_list,true,true); unsigned tmppos=t; int n_lens=lens.size(); int count=0; @@ -2685,7 +2691,7 @@ group_them_again: itemlist[t].insert( FloItem(FloItem::NOTE_END,tmp.pos,0,0) ); - list lens=parse_note_len(len_ticks_remaining,t-last_measure,emphasize_list,parent->quant_power2(),true,true); + list lens=parse_note_len(len_ticks_remaining,t-last_measure,emphasize_list,true,true); unsigned tmppos=t; int n_lens=lens.size(); int count=0; @@ -4481,6 +4487,7 @@ void staff_t::update_part_indices() * o add "move other notes" or "overwrite notes" or "mix with notes" to paste * * IMPORTANT TODO + * o add "dotted quarter" quantize option (for 6/8 beat) * o draw the edge of parts hiding notes "jagged" (hasHiddenEvents() is interesting for this) - Done. Tim. * o shrink a part from its beginning as well! watch out for clones! * o insert empty measure should also work inside parts, that is, diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h index 6a5dd63a..a2b25f7d 100644 --- a/muse2/muse/midiedit/scoreedit.h +++ b/muse2/muse/midiedit/scoreedit.h @@ -581,7 +581,7 @@ note_pos_t note_pos_(int note, key_enum key); note_pos_t note_pos (unsigned note, key_enum key, clef_t clef); int calc_len(int l, int d); -list parse_note_len(int len_ticks, int begin_tick, vector& foo, int quant_power2, bool allow_dots=true, bool allow_normal=true); +list parse_note_len(int len_ticks, int begin_tick, vector& foo, bool allow_dots=true, bool allow_normal=true); int clef_height(clef_t clef); -- cgit v1.2.3