summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--muse2/ChangeLog5
-rw-r--r--muse2/awl/posedit.cpp3
-rw-r--r--muse2/muse/arranger/arranger.cpp1
-rw-r--r--muse2/muse/arranger/pcanvas.cpp393
-rw-r--r--muse2/muse/arranger/pcanvas.h10
-rw-r--r--muse2/muse/audio.cpp4
-rw-r--r--muse2/muse/audio.h2
-rw-r--r--muse2/muse/audiotrack.cpp41
-rw-r--r--muse2/muse/cliplist/cliplist.cpp8
-rw-r--r--muse2/muse/ctrl.cpp110
-rw-r--r--muse2/muse/ctrl.h5
-rw-r--r--muse2/muse/dssihost.cpp15
-rw-r--r--muse2/muse/dssihost.h2
-rw-r--r--muse2/muse/mixer/astrip.cpp43
-rw-r--r--muse2/muse/mixer/panknob.cpp4
-rw-r--r--muse2/muse/mplugins/rhythmbase.ui8
-rw-r--r--muse2/muse/plugin.cpp92
-rw-r--r--muse2/muse/plugin.h10
-rw-r--r--muse2/muse/seqmsg.cpp27
-rw-r--r--muse2/muse/song.cpp17
-rw-r--r--muse2/muse/song.h7
-rw-r--r--muse2/muse/track.cpp4
-rw-r--r--muse2/muse/track.h1
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);
}
@@ -700,6 +695,22 @@ void AudioTrack::addACEvent(int id, int frame, double val)
}
//---------------------------------------------------------
+// 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<const int, CtrlVal> (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<int, CtrlVal, std::less<int> > {
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!</string>
<height>38</height>
</rect>
</property>
- <property name="label">
- <string>Tools</string>
- </property>
+ <widget class="QLabel">
+ <property name="text">
+ <string>Tools</string>
+ </property>
+ </widget>
<addaction name="fileNewAction"/>
<addaction name="fileOpenAction"/>
<addaction name="fileSaveAction"/>
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.
/*
//---------------------------------------------------------
@@ -1003,6 +1040,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,21 +1754,12 @@ 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);
};
//---------------------------------------------------------