summaryrefslogtreecommitdiff
path: root/muse2
diff options
context:
space:
mode:
authorRobert Jonsson <spamatica@gmail.com>2011-03-16 20:37:58 +0000
committerRobert Jonsson <spamatica@gmail.com>2011-03-16 20:37:58 +0000
commit062b07f0cb5a27bf5508af692b0b533a66a1bbd6 (patch)
treea1ae8586f53be944b2ec9c08d38f7b8dc526a34a /muse2
parent82ffcfacf70e611092a36feadae5845d6772f176 (diff)
draw midi part during recording
Diffstat (limited to 'muse2')
-rw-r--r--muse2/ChangeLog2
-rw-r--r--muse2/muse/arranger/pcanvas.cpp224
-rw-r--r--muse2/muse/arranger/pcanvas.h1
3 files changed, 144 insertions, 83 deletions
diff --git a/muse2/ChangeLog b/muse2/ChangeLog
index a0e1cf3c..effaf218 100644
--- a/muse2/ChangeLog
+++ b/muse2/ChangeLog
@@ -1,3 +1,5 @@
+16.03.2011:
+ - Added: Midi events drawing while recording (rj)
12.03.2011:
- Cursor mode in drum editor should be usable now (rj)
Changes:
diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp
index a68f3bb5..49808faf 100644
--- a/muse2/muse/arranger/pcanvas.cpp
+++ b/muse2/muse/arranger/pcanvas.cpp
@@ -37,6 +37,9 @@
#include "app.h"
#include "filedialog.h"
#include "marker/marker.h"
+#include "mpevent.h"
+#include "midievent.h"
+#include "midi.h"
// Moved into global config by Tim.
/*
@@ -1586,74 +1589,13 @@ void PartCanvas::drawItem(QPainter& p, const CItem* item, const QRect& rect)
mp = (MidiPart*)part;
}
- if (config.canvasShowPartType & 2) { // show events
- if (mp)
- {
- // Do not allow this, causes segfault.
- if(from <= to)
- {
- p.setPen(Qt::darkGray);
- EventList* events = mp->events();
- iEvent ito(events->lower_bound(to));
-
- for (iEvent i = events->lower_bound(from); i != ito; ++i) {
- EventType type = i->second.type();
- if (
- ((config.canvasShowPartEvent & 1) && (type == Note))
- || ((config.canvasShowPartEvent & 2) && (type == PAfter))
- || ((config.canvasShowPartEvent & 4) && (type == Controller))
- || ((config.canvasShowPartEvent &16) && (type == CAfter))
- || ((config.canvasShowPartEvent &64) && (type == Sysex || type == Meta))
- ) {
- int t = i->first + pTick;
- int th = part->track()->height();
- if(t >= r.left() && t <= r.right())
- p.drawLine(t, r.y()+2, t, r.y()+th-4);
- }
- }
- }
- }
- else if (wp)
- drawWavePart(p, rect, wp, r);
- }
-
- else { // show Cakewalk Style
- if (mp) {
- p.setPen(Qt::darkGray);
- EventList* events = mp->events();
- iEvent ito(events->lower_bound(to));
- //printf("PartCanvas::drawItem pTick:%d from:%d to:%d part len:%d\n", pTick, from, to, part->lenTick());
-
- for (iEvent i = events->begin(); i != ito; ++i) {
- int t = i->first + pTick;
- int te = t + i->second.lenTick();
+ if (wp)
+ drawWavePart(p, rect, wp, r);
+ else if (mp)
+ {
+ drawMidiPart(p, rect, mp->events(),(MidiTrack*)part->track(), r, mp->tick(), from, to);
+ }
- if (t > (to + pTick))
- {
- printf("PartCanvas::drawItem t:%d > to:%d + pTick:%d i->first:%d\n", t, to, pTick, i->first);
-
- break;
- }
-
- if (te < (from + pTick))
- continue;
-
- if (te > (to + pTick))
- te = to + pTick;
-
- EventType type = i->second.type();
- if (type == Note) {
- int pitch = i->second.pitch();
- int th = int(part->track()->height() * 0.75); // only draw on three quarters
- int hoffset = (part->track()->height() - th ) / 2; // offset from bottom
- int y = hoffset + (r.y() + th - (pitch * (th) / 127));
- p.drawLine(t, y, te, y);
- }
- }
- }
- else if (wp)
- drawWavePart(p, rect, wp, r);
- }
if (config.canvasShowPartType & 1) { // show names
// draw name
// FN: Set text color depending on part color (black / white)
@@ -1700,6 +1642,76 @@ void PartCanvas::drawMoving(QPainter& p, const CItem* item, const QRect&)
p.drawRect(item->mp().x(), item->mp().y(), item->width(), item->height());
}
+
+//---------------------------------------------------------
+// drawWavePart
+// bb - bounding box of paint area
+// pr - part rectangle
+//---------------------------------------------------------
+
+void PartCanvas::drawMidiPart(QPainter& p, const QRect& bb, EventList* events, MidiTrack *mt, const QRect& r, int pTick, int from, int to)
+{
+ //printf("x=%d y=%d h=%d w=%d\n",r.x(),r.y(),r.height(),r.width());
+ if (config.canvasShowPartType & 2) { // show events
+ // Do not allow this, causes segfault.
+ if(from <= to)
+ {
+ p.setPen(Qt::darkGray);
+ //EventList* events = mp->events();
+ iEvent ito(events->lower_bound(to));
+
+ for (iEvent i = events->lower_bound(from); i != ito; ++i) {
+ EventType type = i->second.type();
+ if (
+ ((config.canvasShowPartEvent & 1) && (type == Note))
+ || ((config.canvasShowPartEvent & 2) && (type == PAfter))
+ || ((config.canvasShowPartEvent & 4) && (type == Controller))
+ || ((config.canvasShowPartEvent &16) && (type == CAfter))
+ || ((config.canvasShowPartEvent &64) && (type == Sysex || type == Meta))
+ ) {
+ int t = i->first + pTick;
+ int th = mt->height();
+ if(t >= r.left() && t <= r.right())
+ p.drawLine(t, r.y()+2, t, r.y()+th-4);
+ }
+ }
+ }
+ }
+ else { // show Cakewalk Style
+ p.setPen(Qt::darkGray);
+ //EventList* events = mp->events();
+ iEvent ito(events->lower_bound(to));
+ //printf("PartCanvas::drawItem pTick:%d from:%d to:%d\n", pTick, from, to);
+
+ for (iEvent i = events->begin(); i != ito; ++i) {
+ int t = i->first + pTick;
+ int te = t + i->second.lenTick();
+
+ if (t > (to + pTick))
+ {
+ //printf("PartCanvas::drawItem t:%d > to:%d + pTick:%d i->first:%d\n", t, to, pTick, i->first);
+
+ break;
+ }
+
+ if (te < (from + pTick))
+ continue;
+
+ if (te > (to + pTick))
+ te = to + pTick;
+
+ EventType type = i->second.type();
+ if (type == Note) {
+ int pitch = i->second.pitch();
+ int th = int(mt->height() * 0.75); // only draw on three quarters
+ int hoffset = (mt->height() - th ) / 2; // offset from bottom
+ int y = hoffset + (r.y() + th - (pitch * (th) / 127));
+ p.drawLine(t, y, te, y);
+ }
+ }
+ }
+}
+
//---------------------------------------------------------
// drawWavePart
// bb - bounding box of paint area
@@ -2956,31 +2968,32 @@ void PartCanvas::drawTopItem(QPainter& p, const QRect& rect)
QRect rr = p.worldMatrix().mapRect(rect);
+
+ unsigned int startPos = audio->getStartRecordPos().tick();
+ if (song->punchin())
+ startPos=song->lpos();
+ int startx = mapx(startPos);
+ int width = mapx(song->cpos()) - mapx(startPos);
+
+ if (song->cpos() < startPos) {
+ return; // no drawing if we are before punch out
+ }
+ if (song->punchout() && song->cpos() > song->rpos()) {
+ return; // no drawing if we are beyond punch out.
+ }
+
p.save();
p.resetTransform();
- // primitive write recording while it happens
- // should be enhanced/exchanged with solution that draws events and waveform
+ // write recording while it happens to get feedback
+ // should be enhanced with solution that draws waveform also
int yPos=0;
if (song->record() && audio->isPlaying()) {
for (iTrack it = tl->begin(); it != tl->end(); ++it) {
Track* track = *it;
if (track->recordFlag()) {
- unsigned int startPos = audio->getStartRecordPos().tick();
- if (song->punchin())
- startPos=song->lpos();
- if (song->punchout() && song->cpos() > song->rpos()) {
- continue; // no drawing if we are beyond punch out.
- }
-
-
- if (song->cpos() > startPos) {
- int startx = mapx(startPos);
- int width = mapx(song->cpos()) - mapx(startPos);
-
QPen pen(Qt::black, 0, Qt::SolidLine);
p.setPen(pen);
-
QColor c(config.partColors[0]);
c.setAlpha(config.globalAlphaBlend);
QLinearGradient gradient(QPoint(0,0), QPoint(0,track->height()));
@@ -2990,12 +3003,57 @@ void PartCanvas::drawTopItem(QPainter& p, const QRect& rect)
p.setBrush(cc);
p.drawRect(startx,yPos, width, track->height());
- }
}
yPos+=track->height();
}
}
p.restore();
+
+ yPos=0;
+ if (song->record() && audio->isPlaying()) {
+ for (iTrack it = tl->begin(); it != tl->end(); ++it) {
+ Track* track = *it;
+
+ if (track->isMidiTrack()) {
+ MidiTrack *mt = (MidiTrack*)track;
+ QRect partRect(startPos,yPos, song->cpos()-startPos, track->height()); // probably the wrong rect
+ EventList myEventList;
+ MPEventList *el = mt->mpevents();
+ if (el->size() == 0)
+ continue;
+
+ //printf("num events %d\n", mt->mpevents()->size());
+ for (iMPEvent i = el->begin(); i != el->end(); ++i) {
+ MidiPlayEvent pe = *i;
+
+ if (pe.isNote() && !pe.isNoteOff()) {
+ Event e(Note);
+ e.setPitch(pe.dataA());
+ e.setTick(pe.time()-startPos);
+ e.setLenTick(song->cpos()-pe.time());
+ e.setC(1); // we abuse this value to determine that this note hasn't been concluded
+ myEventList.add(e);
+ }
+ else if (pe.isNoteOff()) {
+ for (iEvent i = myEventList.begin(); i != myEventList.end(); ++i) {
+ Event &e = i->second;
+ if (e.pitch() == pe.dataA() && e.dataC() == 1) {
+ e.setLenTick(pe.time() - e.tick()- startPos);
+ e.setC(0); // reset the variable we borrowed for state handling
+ //printf("editing event tick=%d startPos=%d\n",e.tick(), startPos);
+ continue;
+ }
+ }
+ }
+ }
+
+ drawMidiPart(p, rect, &myEventList, mt, partRect,startPos,0,song->cpos()-startPos);
+ }
+ yPos+=track->height();
+ }
+ }
+
+
}
//---------------------------------------------------------
diff --git a/muse2/muse/arranger/pcanvas.h b/muse2/muse/arranger/pcanvas.h
index e7fa1fdf..d3e835b0 100644
--- a/muse2/muse/arranger/pcanvas.h
+++ b/muse2/muse/arranger/pcanvas.h
@@ -112,6 +112,7 @@ class PartCanvas : public Canvas {
void movePartsTotheRight(unsigned int startTick, int length);
//Part* readClone(Xml&, Track*, bool toTrack = true);
void drawWavePart(QPainter&, const QRect&, WavePart*, const QRect&);
+ void drawMidiPart(QPainter&, const QRect& rect, EventList* events, MidiTrack *mt, const QRect& r, int pTick, int from, int to);
Track* y2Track(int) const;
void drawAudioTrack(QPainter& p, const QRect& r, AudioTrack* track);
void drawAutomation(QPainter& p, const QRect& r, AudioTrack* track);