From 217b37620cb47a9a6d9ae6c4027638d763e9df1b Mon Sep 17 00:00:00 2001 From: Robert Jonsson Date: Tue, 4 Jan 2011 19:16:13 +0000 Subject: automation viewable in arranger and rec changes --- muse2/ChangeLog | 5 +- muse2/muse/arranger/arranger.cpp | 6 +- muse2/muse/arranger/pcanvas.cpp | 52 +++++++++------- muse2/muse/arranger/tlist.cpp | 125 +++++++++++++++++++++++++++++--------- muse2/muse/arranger/tlist.h | 3 +- muse2/muse/audio.cpp | 6 +- muse2/muse/audiotrack.cpp | 2 +- muse2/muse/ctrl.cpp | 25 +++++++- muse2/muse/ctrl.h | 13 +++- muse2/share/templates/default.med | 49 ++++++++------- 10 files changed, 204 insertions(+), 82 deletions(-) (limited to 'muse2') diff --git a/muse2/ChangeLog b/muse2/ChangeLog index 54c07677..07ad91bd 100644 --- a/muse2/ChangeLog +++ b/muse2/ChangeLog @@ -5,13 +5,16 @@ TODO: Fix trackinfo scrollbar not showing at right time. - Replace all QWidget::setShown() calls with setVisible(). (Tim) It's supposed to be a Qt3 function, but still supported. + - Enabled displaying of audio automation on tracks (rj) + - Added right-click on track ARM buttons, now enables/disables all tracks of it's kind (rj) + - leave audio tracks ARMED after record, same as midi tracks (rj) 02.01.2011: - Fixed arranger focussing problems again. (Tim) Scratch setFocusProxy() fix of 31.12. Gave MusE a keyPress handler and pass it on to canvas. - Fixed transport +/- position snapping. Works globally now too. (Tim) Moves by, and snaps to, snap setting of either an editor, or globally to arranger by default. - Added transport position "Shift + +/-" keys, for no snapping. (Tim) - - Removed (hopefully) the last bits of Qt3sepport functions from .ui files. (Orcan) + - Removed (hopefully) the last bits of Qt3support functions from .ui files. (Orcan) - fixed patch loading for deicsonze and reverted to it's standard colortheme (rj) 31.12.2010: - Possible fix for arranger focussing problems. (Tim) diff --git a/muse2/muse/arranger/arranger.cpp b/muse2/muse/arranger/arranger.cpp index d9cf5d5b..834b9613 100644 --- a/muse2/muse/arranger/arranger.cpp +++ b/muse2/muse/arranger/arranger.cpp @@ -67,7 +67,7 @@ void Arranger::setHeaderToolTips() header->setToolTip(COL_OCHANNEL, tr("Midi output channel number or audio channels")); header->setToolTip(COL_OPORT, tr("Midi output port or synth midi port")); header->setToolTip(COL_TIMELOCK, tr("Time Lock")); - //header->setToolTip(COL_AUTOMATION, tr("Automation parameter selection")); + header->setToolTip(COL_AUTOMATION, tr("Automation parameter selection")); } @@ -287,7 +287,7 @@ Arranger::Arranger(QMainWindow* parent, const char* name) header->setColumnLabel(tr("Port"), COL_OPORT, 60); header->setColumnLabel(tr("Ch"), COL_OCHANNEL, 30); header->setColumnLabel(tr("T"), COL_TIMELOCK, fm1.width('T')+fw); - //header->setColumnLabel(tr("Automation"), COL_AUTOMATION, 30); + header->setColumnLabel(tr("Automation"), COL_AUTOMATION, 75); header->setResizeMode(COL_RECORD, QHeaderView::Fixed); header->setResizeMode(COL_MUTE, QHeaderView::Fixed); header->setResizeMode(COL_SOLO, QHeaderView::Fixed); @@ -296,7 +296,7 @@ Arranger::Arranger(QMainWindow* parent, const char* name) header->setResizeMode(COL_OPORT, QHeaderView::Interactive); header->setResizeMode(COL_OCHANNEL, QHeaderView::Fixed); header->setResizeMode(COL_TIMELOCK, QHeaderView::Fixed); - //header->setResizeMode(COL_AUTOMATION, QHeaderView::Interactive); + header->setResizeMode(COL_AUTOMATION, QHeaderView::Interactive); setHeaderToolTips(); setHeaderWhatsThis(); diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index b57f524f..3e6919a7 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -2887,33 +2887,40 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& r, AudioTrack *t) // printf("drawAudioTrack %d x %d y %d w %d h %d\n",t, r.x(), r.y(), r.width(), r.height()); //int v2=r.x()+r.width(); //printf("v2=%d mapx=%d rmapx=%d mapxdev=%d rmapxdev=%d\n",v2, mapx(v2),rmapx(v2),mapxDev(v2),rmapxDev(v2)); - return; + //return; - p.setPen(QPen(Qt::black, 2, Qt::SolidLine)); +// p.setPen(QPen(Qt::black, 2, Qt::SolidLine)); int height=r.bottom()-r.top()-4; // limit height CtrlListList* cll = t->controller(); - QColor cols[10]; - cols[0]=Qt::white; - cols[1]=Qt::red; - cols[2]=Qt::yellow; - cols[3]=Qt::black; - cols[4]=Qt::blue; - int colIndex=0; +// QColor cols[10]; +// cols[0]=Qt::white; +// cols[1]=Qt::red; +// cols[2]=Qt::yellow; +// cols[3]=Qt::black; +// cols[4]=Qt::blue; + //int colIndex=0; 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(); - p.setPen(QPen(cols[colIndex++],1,Qt::SolidLine)); + if (!cl->isVisible()) + continue; // skip this iteration if this controller isn't in the visible list + p.setPen(QPen(cl->color(),1,Qt::SolidLine)); - if (ic!=cl->end()) { // if there are no automation values we don't draw at all + // First check that there ARE automation, ic == cl->end means no automation + if (ic != cl->end()) { CtrlVal cvFirst = ic->second; ic++; int prevPos=cvFirst.frame; prevVal = cvFirst.val; + + // prepare prevVal if (cl->id() == AC_VOLUME ) { // use db scale for volume prevVal = (20.0*log10(cvFirst.val)+60) / 70.0; // represent volume between 0 and 1 if (prevVal < 0) prevVal = 0.0; @@ -2924,6 +2931,7 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& r, AudioTrack *t) cl->range(&min,&max); prevVal = (prevVal- min)/(max-min); } + for (; ic !=cl->end(); ++ic) { CtrlVal cv = ic->second; @@ -2938,29 +2946,27 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& r, AudioTrack *t) cl->range(&min,&max); nextVal = (nextVal- min)/(max-min); } - //printf("volume automation event %d %f %f %d\n",cv.frame,cv.val, tempomap.frame2tick(cv.frame)); - //p.drawLine(r.x(),(r.bottom()-2)-lastVal*height,r.x()+r.width(),(r.bottom()-2)-curVal*height); // debuggingtest int leftX=tempomap.frame2tick(prevPos); if (firstRun && leftX>r.x()) { - printf("first run\n"); leftX=r.x(); } - printf("inner draw\n"); - p.drawLine(leftX,(r.bottom()-2)-prevVal*height,tempomap.frame2tick(cv.frame),(r.bottom()-2)-prevVal*height); + p.drawLine( leftX, + (r.bottom()-2)-prevVal*height, + tempomap.frame2tick(cv.frame), + (r.bottom()-2)-nextVal*height); firstRun=false; //printf("draw line: %d %f %d %f\n",tempomap.frame2tick(lastPos),r.bottom()-lastVal*height,tempomap.frame2tick(cv.frame),r.bottom()-curVal*height); prevPos=cv.frame; prevVal=nextVal; } - printf("outer draw %f\n", cvFirst.val); - p.drawLine(tempomap.frame2tick(prevPos),(r.bottom()-2)-prevVal*height,tempomap.frame2tick(prevPos)+r.width(),(r.bottom()-2)-prevVal*height); - //printf("draw last line: %d %f %d %f\n",tempomap.frame2tick(lastPos),r.bottom()-lastVal*height,150000,r.bottom()-lastVal*height); + //printf("outer draw %f\n", cvFirst.val ); + p.drawLine(tempomap.frame2tick(prevPos), + (r.bottom()-2)-prevVal*height, + r.x()+r.width(), + (r.bottom()-2)-prevVal*height); + //printf("draw last line: %d %f %d %f\n",tempomap.frame2tick(prevPos),(r.bottom()-2)-prevVal*height,tempomap.frame2tick(prevPos)+r.width(),(r.bottom()-2)-prevVal*height); } -// if (height >100) { -// p.drawText(tempomap.frame2tick(0)+1000,40,"FOOO"); -// printf("drawText %s\n", cl->name().toLatin1().constData()); -// } } } diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index 4c104e0b..02f742f7 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -21,6 +21,7 @@ #include #include +#include "popupmenu.h" #include "globals.h" #include "icons.h" #include "scrollscale.h" @@ -329,19 +330,19 @@ void TList::paint(const QRect& r) p.drawText(r, Qt::AlignVCenter|Qt::AlignLeft, s); } break; -// case COL_AUTOMATION: -// { -// QString s="-"; -// -// if (!track->isMidiTrack()) { -// int count = ((AudioTrack*)track)->controller()->size(); -// s.sprintf("%d", count); -// } -// -// -// p.drawText(r, Qt::AlignVCenter|Qt::AlignLeft, s); -// } -// break; + case COL_AUTOMATION: + { + QString s="-"; + + if (!track->isMidiTrack()) { + int count = ((AudioTrack*)track)->controller()->size(); + s.sprintf("%d viewed", count); + } + + + p.drawText(r, Qt::AlignVCenter|Qt::AlignLeft, s); + } + break; default: break; } @@ -774,6 +775,25 @@ TrackList TList::getRecEnabledTracks() // mousePressEvent //--------------------------------------------------------- +void TList::changeAutomation(QAction* act) +{ + printf("changeAutomation!\n"); + if (editTrack->type() == Track::MIDI) { + printf("this is wrong, we can't edit automation for midi tracks from arranger yet!\n"); + return; + } + + CtrlListList* cll = ((AudioTrack*)editTrack)->controller(); + int index=0; + for(CtrlListList::iterator icll =cll->begin();icll!=cll->end();++icll) { + if (act->data() == index++) { // got it, change state + CtrlList *cl = icll->second; + cl->setVisible(!cl->isVisible()); + } + } + song->update(SC_TRACK_MODIFIED); +} + void TList::mousePressEvent(QMouseEvent* ev) { int x = ev->x(); @@ -919,24 +939,73 @@ void TList::mousePressEvent(QMouseEvent* ev) mode = START_DRAG; switch (col) { + case COL_AUTOMATION: + { + if (t->type() != Track::MIDI) { + editTrack = t; + PopupMenu* p = new PopupMenu(); + p->disconnect(); + p->clear(); + p->setTitle(tr("Viewable automation")); + CtrlListList* cll = ((AudioTrack*)t)->controller(); + QAction* act = 0; + int index=0; + for(CtrlListList::iterator icll =cll->begin();icll!=cll->end();++icll) { + CtrlList *cl = icll->second; + if (cl->dontShow()) + continue; + act = p->addAction(cl->name()); + act->setCheckable(true); + act->setChecked(cl->isVisible()); + act->setData(index++); + } + connect(p, SIGNAL(triggered(QAction*)), SLOT(changeAutomation(QAction*))); + //connect(p, SIGNAL(aboutToHide()), muse, SLOT(routingPopupMenuAboutToHide())); + //p->popup(QCursor::pos()); + p->exec(QCursor::pos()); + + delete p; + } + break; + } + case COL_RECORD: { - bool val = !(t->recordFlag()); - if (!t->isMidiTrack()) { - if (t->type() == Track::AUDIO_OUTPUT) { - if (val && t->recordFlag() == false) { - muse->bounceToFile((AudioOutput*)t); + bool val = !(t->recordFlag()); + if (button == Qt::LeftButton) { + if (!t->isMidiTrack()) { + if (t->type() == Track::AUDIO_OUTPUT) { + if (val && t->recordFlag() == false) { + muse->bounceToFile((AudioOutput*)t); + } + audio->msgSetRecord((AudioOutput*)t, val); + if (!((AudioOutput*)t)->recFile()) + val = false; + else + return; } - audio->msgSetRecord((AudioOutput*)t, val); - if (!((AudioOutput*)t)->recFile()) - val = false; - else + song->setRecordFlag(t, val); + } + else + song->setRecordFlag(t, val); + } else if (button == Qt::RightButton) { + // enable or disable ALL tracks of this type + if (!t->isMidiTrack()) { + if (t->type() == Track::AUDIO_OUTPUT) { return; + } + WaveTrackList* wtl = song->waves(); + foreach (WaveTrack *wt, *wtl) { + song->setRecordFlag(wt, val); + } } - song->setRecordFlag(t, val); + else { + MidiTrackList* mtl = song->midis(); + foreach (MidiTrack *mt, *mtl) { + song->setRecordFlag(mt, val); + } } - else - song->setRecordFlag(t, val); + } } break; case COL_NONE: @@ -1001,7 +1070,7 @@ void TList::mousePressEvent(QMouseEvent* ev) mode = NORMAL; QMenu* p = new QMenu; //p->clear(); - p->addAction(QIcon(*automation_clear_dataIcon), tr("Delete Track"))->setData(0); // ddskrjo + p->addAction(QIcon(*automation_clear_dataIcon), tr("Delete Track"))->setData(0); p->addAction(QIcon(*track_commentIcon), tr("Track Comment"))->setData(1); QAction* act = p->exec(ev->globalPos(), 0); if (act) { @@ -1238,7 +1307,7 @@ void TList::mouseReleaseEvent(QMouseEvent* ev) setCursor(QCursor(Qt::ArrowCursor)); redraw(); } - if (editTrack) + if (editTrack && editor && editor->isVisible()) editor->setFocus(); adjustScrollbar(); } @@ -1265,7 +1334,7 @@ void TList::wheelEvent(QWheelEvent* ev) case COL_NONE: case COL_CLASS: case COL_NAME: - //case COL_AUTOMATION: + case COL_AUTOMATION: break; case COL_MUTE: // p3.3.29 diff --git a/muse2/muse/arranger/tlist.h b/muse2/muse/arranger/tlist.h index 3431a7a1..188685bc 100644 --- a/muse2/muse/arranger/tlist.h +++ b/muse2/muse/arranger/tlist.h @@ -34,9 +34,9 @@ enum TrackColumn { COL_OPORT, COL_OCHANNEL, COL_TIMELOCK, + COL_AUTOMATION, COL_NONE = -1 }; -// COL_AUTOMATION, -- not enabled //--------------------------------------------------------- // TList @@ -87,6 +87,7 @@ class TList : public QWidget { private slots: void returnPressed(); void songChanged(int flags); + void changeAutomation(QAction*); signals: ///void selectionChanged(); diff --git a/muse2/muse/audio.cpp b/muse2/muse/audio.cpp index d266db9a..da7a0af3 100644 --- a/muse2/muse/audio.cpp +++ b/muse2/muse/audio.cpp @@ -1359,8 +1359,10 @@ void Audio::recordStop() // Or _recFile may have been discarded (no new recorded part created). // Regardless, we are done with the pointer itself. Set to zero so // song->setRecordFlag knows about it... - track->setRecFile(0); - song->setRecordFlag(track, false); + + track->setRecFile(0); // flush out the old file + song->setRecordFlag(track, false); // and re-arm the track + song->setRecordFlag(track, true); // here } } MidiTrackList* ml = song->midis(); diff --git a/muse2/muse/audiotrack.cpp b/muse2/muse/audiotrack.cpp index 1d92e811..7330e79e 100644 --- a/muse2/muse/audiotrack.cpp +++ b/muse2/muse/audiotrack.cpp @@ -81,7 +81,7 @@ AudioTrack::AudioTrack(TrackType t) setChannels(2); addController(new CtrlList(AC_VOLUME,"Volume",0.0,1.0)); addController(new CtrlList(AC_PAN, "Pan", -1.0, 1.0)); - addController(new CtrlList(AC_MUTE,"Mute",0.0,1.0)); + addController(new CtrlList(AC_MUTE,"Mute",0.0,1.0, true /*dont show in arranger */)); // Changed by Tim. p3.3.15 //outBuffers = new float*[MAX_CHANNELS]; diff --git a/muse2/muse/ctrl.cpp b/muse2/muse/ctrl.cpp index a2bd0754..42802829 100644 --- a/muse2/muse/ctrl.cpp +++ b/muse2/muse/ctrl.cpp @@ -10,6 +10,7 @@ #include +#include //#include #include "globals.h" @@ -17,6 +18,24 @@ #include "xml.h" // #include "audio.h" +void CtrlList::initColor(int i) +{ + if (i == 0) + _displayColor = Qt::red; + else if (i == 1) + _displayColor = Qt::yellow; + else + _displayColor = Qt::black; + + if (i < 2) + _visible = true; + else + _visible = false; + +} + + + //--------------------------------------------------------- // CtrlList //--------------------------------------------------------- @@ -27,11 +46,12 @@ CtrlList::CtrlList(int id) _default = 0.0; _curVal = 0.0; _mode = INTERPOLATE; + initColor(id); } //--------------------------------------------------------- // CtrlList //--------------------------------------------------------- -CtrlList::CtrlList(int id, QString name, double min, double max) +CtrlList::CtrlList(int id, QString name, double min, double max, bool dontShow) { _id = id; _default = 0.0; @@ -40,6 +60,8 @@ CtrlList::CtrlList(int id, QString name, double min, double max) _name = name; _min = min; _max = max; + _dontShow = dontShow; + initColor(id); } //--------------------------------------------------------- // CtrlList @@ -51,6 +73,7 @@ CtrlList::CtrlList() _default = 0.0; _curVal = 0.0; _mode = INTERPOLATE; + initColor(0); } //--------------------------------------------------------- diff --git a/muse2/muse/ctrl.h b/muse2/muse/ctrl.h index 99767b55..c845bb1e 100644 --- a/muse2/muse/ctrl.h +++ b/muse2/muse/ctrl.h @@ -13,6 +13,7 @@ #include #include +#include const int AC_VOLUME = 0; const int AC_PAN = 1; @@ -87,11 +88,15 @@ class CtrlList : public std::map > { QString _name; double _min, _max; CtrlValueType _valueType; + QColor _displayColor; + bool _visible; + bool _dontShow; // when this is true the control exists but is not compatible with viewing in the arranger + void initColor(int i); public: CtrlList(); CtrlList(int id); - CtrlList(int id, QString name, double min, double max); + CtrlList(int id, QString name, double min, double max, bool dontShow=false); Mode mode() const { return _mode; } void setMode(Mode m) { _mode = m; } @@ -117,6 +122,12 @@ class CtrlList : public std::map > { void add(int tick, double value); void del(int tick); void read(Xml& xml); + + void setColor( QColor c ) { _displayColor = c;} + QColor color() { return _displayColor; } + void setVisible(bool v) { _visible = v; } + bool isVisible() { return _visible; } + bool dontShow() { return _dontShow; } }; //--------------------------------------------------------- diff --git a/muse2/share/templates/default.med b/muse2/share/templates/default.med index 3ffe562d..31bb5128 100644 --- a/muse2/share/templates/default.med +++ b/muse2/share/templates/default.med @@ -9,27 +9,24 @@ 0 0 0 - 127 - 127 - 1 - -1 1 00:00:00:00:00 + 1 + 1 + 1 0 - 0 - 0 - 0 - 0 - 1 - 1 0 0 - 0 + 0 + + + 0 + 0 1 - 440 799 + 418 751 -
7 6 5 4 3 2 1 0
+
8 7 6 5 4 3 2 1 0
0 266 @@ -52,6 +49,7 @@ 0 1 0 + 0.5 0 28 @@ -89,6 +87,7 @@ + 1 0 0 @@ -117,19 +116,25 @@ 0 1 0 - 1 - + 0 + 0 + + 0 1, + 0 0, + + + 0 0, - - 1:Out 1 - alsa_pcm:playback_1 + + + - - 2:Out 1 - alsa_pcm:playback_2 + + + @@ -147,4 +152,6 @@ + + -- cgit v1.2.3