1
//=========================================================
4
// $Id: prcanvas.cpp,v 1.2 2002/02/27 08:48:09 muse Exp $
5
// (C) Copyright 1999,2000 Werner Schweer (ws@seh.de)
6
//=========================================================
9
#include <qapplication.h>
10
#include <qclipboard.h>
12
#include <qdragobject.h>
18
#include "midithread.h"
30
//---------------------------------------------------------
32
//---------------------------------------------------------
34
NEvent::NEvent(Event* e, Part* p, int y) : CItem(e, p)
37
setPos(QPoint(e->posTick(), y));
38
setBBox(QRect(e->posTick(), y, e->lenTick(), KH/2));
41
//---------------------------------------------------------
43
//---------------------------------------------------------
45
void PianoCanvas::addItem(Part* part, Event* event)
47
NEvent* ev = new NEvent(event, part, pitch2y(((MidiEvent*)event)->pitch()));
51
//---------------------------------------------------------
53
//---------------------------------------------------------
55
PianoCanvas::PianoCanvas(MidiEditor* pr, QWidget* parent, int sx, int sy)
56
: EventCanvas(pr, parent, sx, sy)
59
cmdRange = 0; // all Events
62
songChanged(SC_TRACK_INSERTED);
63
connect(midiThread, SIGNAL(midiNote(int, int)), SLOT(midiNote(int,int)));
66
//---------------------------------------------------------
68
//---------------------------------------------------------
70
int PianoCanvas::pitch2y(int pitch) const
73
5, 12, 19, 26, 33, 44, 51, 58, 64, 71, 78, 85
75
int y = (75 * KH) - (tt[pitch%12] + (7 * KH) * (pitch/12));
81
//---------------------------------------------------------
83
//---------------------------------------------------------
85
int PianoCanvas::y2pitch(int y) const
87
const int total = (10 * 7 + 5) * KH; // 75 Ganztonschritte
89
int oct = (y / (7 * KH)) * 12;
91
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5
92
1, 1, 1, 1, 1, 1, 1, // 13
93
2, 2, 2, 2, 2, 2, // 19
94
3, 3, 3, 3, 3, 3, 3, // 26
95
4, 4, 4, 4, 4, 4, 4, 4, 4, // 34
96
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 43
97
6, 6, 6, 6, 6, 6, 6, // 52
98
7, 7, 7, 7, 7, 7, // 58
99
8, 8, 8, 8, 8, 8, 8, // 65
100
9, 9, 9, 9, 9, 9, // 71
101
10, 10, 10, 10, 10, 10, 10, // 78
102
11, 11, 11, 11, 11, 11, 11, 11, 11, 11 // 87
104
return kt[y % 91] + oct;
107
//---------------------------------------------------------
110
//---------------------------------------------------------
112
void PianoCanvas::drawItem(QPainter& p, const CItem* item,
116
QRect r = item->bbox();
121
static Triple color1[12] = {
122
{ 0xff, 0x3d, 0x39 },
123
{ 0x39, 0xff, 0x39 },
124
{ 0x39, 0x3d, 0xff },
125
{ 0xff, 0xff, 0x39 },
126
{ 0xff, 0x3d, 0xff },
127
{ 0x39, 0xff, 0xff },
128
{ 0xff, 0x7e, 0x7a },
129
{ 0x7a, 0x7e, 0xff },
130
{ 0x7a, 0xff, 0x7a },
131
{ 0xff, 0x7e, 0xbf },
132
{ 0x7a, 0xbf, 0xff },
136
NEvent* nevent = (NEvent*) item;
137
MidiEvent* event = (MidiEvent*)nevent->event();
140
if (nevent->part() != curPart)
141
p.setBrush(lightGray);
143
if (item->isMoving()) {
147
p.drawRect(item->mp().x(), item->mp().y() - item->height()/2, item->width(), item->height());
150
else if (item->isSelected()) {
154
color.setRgb(0, 0, 255);
160
Triple* c = &color1[event->pitch() % 12];
161
color.setRgb(c->r, c->g, c->b);
166
int velo = event->velo();
168
color.setRgb(velo*4, 0, 0xff);
170
color.setRgb(0xff, 0, (velo-64) * 4);
180
//---------------------------------------------------------
181
// viewMouseDoubleClickEvent
182
//---------------------------------------------------------
184
void PianoCanvas::viewMouseDoubleClickEvent(QMouseEvent* event)
186
if ((_tool != PointerTool) && (event->button() != QMouseEvent::LeftButton)) {
192
//---------------------------------------------------------
194
// wird nach dem Moven eines Objektes aufgerufen
195
//---------------------------------------------------------
197
bool PianoCanvas::moveItem(CItem* item, const QPoint& pos, bool copy)
199
NEvent* nevent = (NEvent*) item;
200
MidiEvent* event = (MidiEvent*)nevent->event();
201
int ntick = editor->rasterVal(pos.x());
202
int npitch = y2pitch(pos.y());
203
MidiEvent* newEvent = new MidiEvent(*event);
205
if (event->pitch() != npitch && _playEvents) {
206
int port = track()->outPort();
207
int channel = track()->outChannel();
209
MidiEvent ev1(port, channel, 0, MidiEvent::Note, event->pitch(), 0, 0, 0);
210
midiThread->playMidiEvent(&ev1);
211
MidiEvent ev2(port, channel, 0, MidiEvent::Note, npitch, event->velo(), 0, 0);
212
midiThread->playMidiEvent(&ev2);
215
newEvent->setPitch(npitch);
216
newEvent->setPosTick(ntick);
217
newEvent->setLenTick(event->lenTick());
220
midiThread->msgAddEvent(newEvent, nevent->part(), false);
223
midiThread->msgChangeEvent(event, newEvent, nevent->part(), false);
228
//---------------------------------------------------------
230
//---------------------------------------------------------
232
CItem* PianoCanvas::newItem(const QPoint& p, int)
234
int pitch = y2pitch(p.y());
235
int tick = editor->rasterVal1(p.x());
236
int len = p.x() - tick;
237
MidiEvent* e = new MidiEvent(track()->outPort(),
238
track()->outChannel(), tick, MidiEvent::Note,
239
pitch, curVelo, 0, len);
240
return new NEvent(e, curPart, pitch2y(pitch));
243
void PianoCanvas::newItem(CItem* item, bool noSnap)
245
NEvent* nevent = (NEvent*) item;
246
MidiEvent* event = (MidiEvent*)nevent->event();
248
event->setPosTick(item->x()); //round down
249
event->setLenTick(item->width());
252
event->setPosTick(editor->rasterVal1(item->x())); //round down
253
event->setLenTick(editor->quantVal(item->width()));
255
event->setPitch(y2pitch(item->y()));
256
midiThread->msgAddEvent(event, nevent->part());
259
//---------------------------------------------------------
261
//---------------------------------------------------------
263
void PianoCanvas::resizeItem(CItem* item, bool noSnap)
265
NEvent* nevent = (NEvent*) item;
266
MidiEvent* event = (MidiEvent*)(nevent->event());
267
MidiEvent* newEvent = new MidiEvent(*event);
270
len = nevent->width();
272
len = editor->quantVal(nevent->width());
273
newEvent->setLenTick(len);
274
midiThread->msgChangeEvent(event, newEvent, nevent->part());
277
//---------------------------------------------------------
279
//---------------------------------------------------------
281
bool PianoCanvas::deleteItem(CItem* item)
283
NEvent* nevent = (NEvent*) item;
284
if (nevent->part() == curPart) {
285
midiThread->msgDeleteEvent(((NEvent*)item)->event(), ((NEvent*)item)->part());
291
//---------------------------------------------------------
293
//---------------------------------------------------------
295
void PianoCanvas::pianoCmd(int cmd)
299
song->setPos(0, pos[0] - editor->rasterStep(pos[0]),
300
true, false, true); //CDW
303
song->setPos(0, pos[0] + editor->rasterStep(pos[0]),
304
true, false, true); //CDW
307
if (pos[0] < start() || pos[0] >= end())
310
MidiPart* part = (MidiPart*)curPart;
314
EventList* el = part->events();
316
std::list <MidiEvent*> elist;
317
for (iEvent e = el->lower_bound(pos[0]); e != el->end(); ++e)
318
elist.push_back((MidiEvent*)e->second);
319
for (std::list<MidiEvent*>::iterator i = elist.begin(); i != elist.end(); ++i) {
320
MidiEvent* event = *i;
321
MidiEvent* newEvent = new MidiEvent(*event);
322
newEvent->setPosTick(event->posTick() + editor->raster());
323
midiThread->msgChangeEvent(event, newEvent, part, false);
325
song->endUndo(SC_EVENT_MODIFIED);
326
song->setPos(0, editor->rasterVal(pos[0] + editor->rasterStep(pos[0])),
331
if (pos[0] < start() || pos[0] >= end())
334
MidiPart* part = (MidiPart*)curPart;
338
EventList* el = part->events();
340
std::list <MidiEvent*> elist;
341
for (iEvent e = el->lower_bound(pos[0]); e != el->end(); ++e)
342
elist.push_back((MidiEvent*)e->second);
343
for (std::list<MidiEvent*>::iterator i = elist.begin(); i != elist.end(); ++i) {
344
MidiEvent* event = *i;
345
MidiEvent* newEvent = new MidiEvent(*event);
346
newEvent->setPosTick(event->posTick() - editor->raster());
347
midiThread->msgChangeEvent(event, newEvent, part, false);
349
song->endUndo(SC_EVENT_MODIFIED);
350
song->setPos(0, editor->rasterVal(pos[0] - editor->rasterStep(pos[0])),
357
//---------------------------------------------------------
359
//---------------------------------------------------------
361
void PianoCanvas::pianoPressed(int pitch, bool shift)
363
int port = track()->outPort();
364
int channel = track()->outChannel();
367
MidiEvent e(port, channel, 0, MidiEvent::Note, pitch, 127, 0, 0);
368
midiThread->playMidiEvent(&e);
370
if (_steprec && pos[0] >= start_tick && pos[0] < end_tick) {
373
int len = editor->quant();
374
int tick = pos[0]; //CDW
376
tick -= editor->rasterStep(tick);
377
MidiEvent* e = new MidiEvent(port, channel,
378
tick, MidiEvent::Note, pitch, 127, 0, len);
379
midiThread->msgAddEvent(e, curPart);
380
tick += editor->rasterStep(tick);
381
if (tick != song->cpos())
382
song->setPos(0, tick, true, false, true);
386
//---------------------------------------------------------
388
//---------------------------------------------------------
390
void PianoCanvas::pianoReleased(int pitch, bool)
392
int port = track()->outPort();
393
int channel = track()->outChannel();
396
MidiEvent e(port, channel, 0, MidiEvent::Note, pitch, 0, 0, 0);
397
midiThread->playMidiEvent(&e);
400
//---------------------------------------------------------
402
//---------------------------------------------------------
404
void drawTickRaster(QPainter& p, int x, int y, int w, int h, int quant)
406
int bar1, bar2, beat, tick;
407
sigmap.tickValues(x, &bar1, &beat, &tick);
408
sigmap.tickValues(x+w, &bar2, &beat, &tick);
411
for (int bar = bar1; bar < bar2; ++bar) {
412
int x = sigmap.bar2tick(bar, 0, 0);
414
p.drawLine(x, y, x, y2);
417
sigmap.timesig(x, z, n);
418
int q = p.xForm(QPoint(quant, 0)).x() - p.xForm(QPoint(0, 0)).x();
420
if (q < 8) // grid too dense
428
case 128: // 8tel Triolen
432
for (int beat = 1; beat <= z; beat++) {
433
int xxx = sigmap.bar2tick(bar, beat, 0);
435
p.drawLine(xx, y, xx, y2);
443
for (int beat = 1; beat < z; beat++) {
444
int xx = sigmap.bar2tick(bar, beat, 0);
445
p.drawLine(xx, y, xx, y2);
452
//---------------------------------------------------------
454
//---------------------------------------------------------
456
void PianoCanvas::drawCanvas(QPainter& p, const QRect& rect)
460
int w = rect.width();
461
int h = rect.height();
463
//---------------------------------------------------
465
//---------------------------------------------------
467
int yy = ((y-1) / KH) * KH + KH;
468
int key = 75 - (yy / KH);
469
for (; yy < y + h; yy += KH) {
479
p.drawLine(x, yy, x + w, yy);
483
//---------------------------------------------------
485
//---------------------------------------------------
487
drawTickRaster(p, x, y, w, h, editor->quant());
490
//---------------------------------------------------------
492
// pulldown menu commands
493
//---------------------------------------------------------
495
void PianoCanvas::cmd(int cmd, int quantStrength,
496
int quantLimit, bool quantLen, int range)
503
for (iCItem i = items.begin(); i != items.end(); ++i) {
504
if (!(i->second->isSelected()))
506
NEvent* e = (NEvent*)(i->second);
507
midiThread->msgDeleteEvent(e->event(), e->part(), false);
509
song->endUndo(SC_EVENT_REMOVED);
518
if (selectionSize()) {
520
for (iCItem i = items.begin(); i != items.end(); ++i) {
521
if (!i->second->isSelected())
523
midiThread->msgDeleteEvent(i->second->event(), i->second->part(), false);
525
song->endUndo(SC_EVENT_REMOVED);
528
case CMD_OVER_QUANTIZE: // over quantize
529
quantize(100, 1, quantLen);
531
case CMD_ON_QUANTIZE: // note on quantize
532
quantize(50, 1, false);
534
case CMD_ONOFF_QUANTIZE: // note on/off quantize
535
quantize(50, 1, true);
537
case CMD_ITERATIVE_QUANTIZE: // Iterative Quantize
538
quantize(quantStrength, quantLimit, quantLen);
540
case CMD_SELECT_ALL: // select all
541
for (iCItem k = items.begin(); k != items.end(); ++k) {
542
if (!k->second->isSelected())
543
selectItem(k->second, true);
546
case CMD_SELECT_NONE: // select none
549
case CMD_SELECT_INVERT: // invert selection
550
for (iCItem k = items.begin(); k != items.end(); ++k) {
551
selectItem(k->second, !k->second->isSelected());
554
case CMD_SELECT_ILOOP: // select inside loop
555
for (iCItem k = items.begin(); k != items.end(); ++k) {
556
NEvent* nevent =(NEvent*)(k->second);
557
Event* event = nevent->event();
558
int tick = event->posTick();
559
if (tick < song->lpos() || tick >= song->rpos())
560
selectItem(k->second, false);
562
selectItem(k->second, true);
565
case CMD_SELECT_OLOOP: // select outside loop
566
for (iCItem k = items.begin(); k != items.end(); ++k) {
567
NEvent* nevent =(NEvent*)(k->second);
568
Event* event = nevent->event();
569
int tick = event->posTick();
570
if (tick < song->lpos() || tick >= song->rpos())
571
selectItem(k->second, true);
573
selectItem(k->second, false);
576
case CMD_MODIFY_GATE_TIME:
582
int range = w.range(); // all, selected, looped, sel+loop
583
int rate = w.rateVal();
584
int offset = w.offsetVal();
587
for (iCItem k = items.begin(); k != items.end(); ++k) {
588
NEvent* nevent =(NEvent*)(k->second);
589
MidiEvent* event = (MidiEvent*)nevent->event();
590
if (event->type() != MidiEvent::Note)
592
int tick = event->posTick();
593
bool selected = k->second->isSelected();
594
bool inLoop = (tick >= song->lpos()) && (tick < song->rpos());
597
|| (range == 1 && selected)
598
|| (range == 2 && inLoop)
599
|| (range == 3 && selected && inLoop)) {
600
int len = event->lenTick();
602
len = rate ? (len * 100) / rate : 1;
605
if (event->lenTick() != len) {
606
MidiEvent* newEvent = new MidiEvent(*event);
607
newEvent->setLenTick(len);
608
midiThread->msgChangeEvent(event, newEvent, nevent->part(), false);
612
song->endUndo(SC_EVENT_MODIFIED);
616
case CMD_MODIFY_VELOCITY:
622
int range = w.range(); // all, selected, looped, sel+loop
623
int rate = w.rateVal();
624
int offset = w.offsetVal();
627
for (iCItem k = items.begin(); k != items.end(); ++k) {
628
NEvent* nevent =(NEvent*)(k->second);
629
MidiEvent* event = (MidiEvent*)nevent->event();
630
if (event->type() != MidiEvent::Note)
632
int tick = event->posTick();
633
bool selected = k->second->isSelected();
634
bool inLoop = (tick >= song->lpos()) && (tick < song->rpos());
637
|| (range == 1 && selected)
638
|| (range == 2 && inLoop)
639
|| (range == 3 && selected && inLoop)) {
640
int velo = event->velo();
642
velo = rate ? (velo * 100) / rate : 64;
649
if (event->velo() != velo) {
650
MidiEvent* newEvent = new MidiEvent(*event);
651
newEvent->setVelo(velo);
652
midiThread->msgChangeEvent(event, newEvent, nevent->part(), false);
656
song->endUndo(SC_EVENT_MODIFIED);
663
case CMD_ERASE_EVENT:
666
case CMD_COPY_MEASURE:
667
case CMD_ERASE_MEASURE:
668
case CMD_DELETE_MEASURE:
669
case CMD_CREATE_MEASURE:
672
// printf("unknown ecanvas cmd %d\n", cmd);
679
//---------------------------------------------------------
681
//---------------------------------------------------------
683
void PianoCanvas::quantize(int strength, int limit, bool quantLen)
686
for (iCItem k = items.begin(); k != items.end(); ++k) {
687
NEvent* nevent =(NEvent*)(k->second);
688
MidiEvent* event = (MidiEvent*)nevent->event();
689
if (event->type() != MidiEvent::Note)
692
if ((cmdRange & CMD_RANGE_SELECTED) && !k->second->isSelected())
695
int tick = event->posTick();
697
if ((cmdRange & CMD_RANGE_LOOP)
698
&& ((tick < song->lpos() || tick >= song->rpos())))
701
int len = event->lenTick();
702
int tick2 = tick + len;
704
// quant start position
705
int diff = editor->rasterVal(tick) - tick;
706
if (abs(diff) > limit)
707
tick += ((diff * strength) / 100);
710
diff = editor->rasterVal(tick2) - tick2;
711
if (quantLen && (abs(diff) > limit))
712
len += ((diff * strength) / 100);
714
// something changed?
715
if ((event->posTick() != tick) || (event->lenTick() != len)) {
716
MidiEvent* newEvent = new MidiEvent(*event);
717
newEvent->setPosTick(tick);
718
newEvent->setLenTick(len);
719
midiThread->msgChangeEvent(event, newEvent, nevent->part(), false);
722
song->endUndo(SC_EVENT_MODIFIED);
725
//---------------------------------------------------------
727
//---------------------------------------------------------
729
void PianoCanvas::midiNote(int pitch, int velo)
731
if (_midiin && _steprec && curPart
732
&& !song->play() && velo && pos[0] >= start_tick
734
&& !(globalKeyState & AltButton)) {
735
int len = editor->quant();
736
int tick = pos[0]; //CDW
737
int starttick = tick;
738
if (globalKeyState & ShiftButton)
739
tick -= editor->rasterStep(tick);
742
// extend len of last note?
744
EventList* events = curPart->events();
745
if (globalKeyState & ControlButton) {
746
for (iEvent i = events->begin(); i != events->end(); ++i) {
747
MidiEvent* ev = (MidiEvent*)i->second;
750
if (ev->pitch() == pitch && ((ev->posTick()+ev->lenTick()) == starttick)) {
751
MidiEvent* e = new MidiEvent(*ev);
752
e->setLenTick(ev->lenTick() + editor->rasterStep(starttick));
753
midiThread->msgChangeEvent(ev, e, curPart);
754
tick += editor->rasterStep(tick);
755
if (tick != song->cpos())
756
song->setPos(0, tick, true, false, true);
763
// if we already entered the note, delete it
765
EventRange range = events->equal_range(tick);
766
for (iEvent i = range.first; i != range.second; ++i) {
767
MidiEvent* ev = (MidiEvent*)i->second;
768
if (ev->isNote() && ev->pitch() == pitch) {
769
midiThread->msgDeleteEvent(ev, curPart);
770
if (globalKeyState & ShiftButton)
771
tick += editor->rasterStep(tick);
775
MidiEvent* e = new MidiEvent(track()->outPort(),
776
track()->outChannel(), tick, MidiEvent::Note, pitch, velo, 0, len);
777
midiThread->msgAddEvent(e, curPart);
778
tick += editor->rasterStep(tick);
779
if (tick != song->cpos())
780
song->setPos(0, tick, true, false, true);
784
//---------------------------------------------------------
786
//---------------------------------------------------------
788
QTextDrag* PianoCanvas::getTextDrag(QWidget* parent)
790
//---------------------------------------------------
791
// generate event list from selected events
792
//---------------------------------------------------
796
for (iCItem i = items.begin(); i != items.end(); ++i) {
797
if (!i->second->isSelected())
799
NEvent* ne = (NEvent*)(i->second);
800
MidiEvent* e = (MidiEvent*)ne->event();
802
startTick = e->posTick();
806
//---------------------------------------------------
807
// write events as XML into tmp file
808
//---------------------------------------------------
810
FILE* tmp = tmpfile();
812
fprintf(stderr, "PianoCanvas::copy() fopen failed: %s\n",
819
for (ciEvent e = el.begin(); e != el.end(); ++e)
820
e->second->write(level, xml, -startTick);
822
//---------------------------------------------------
823
// read tmp file into QTextDrag Object
824
//---------------------------------------------------
828
if (fstat(fileno(tmp), &f_stat) == -1) {
829
fprintf(stderr, "PianoCanvas::copy() fstat failes:<%s>\n",
834
int n = f_stat.st_size;
835
char* fbuf = (char*)mmap(0, n+1, PROT_READ|PROT_WRITE,
836
MAP_PRIVATE, fileno(tmp), 0);
838
QTextDrag* drag = new QTextDrag(fbuf, parent);
839
drag->setSubtype("eventlist");
845
//---------------------------------------------------------
848
//---------------------------------------------------------
850
void PianoCanvas::copy()
852
QTextDrag* drag = getTextDrag(0);
854
QApplication::clipboard()->setData(drag);
857
//---------------------------------------------------------
859
//---------------------------------------------------------
861
int PianoCanvas::pasteAt(const QString& pt, int pos)
863
const char* p = pt.latin1();
867
Xml::Token token = xml.parse();
868
const QString& tag = xml.s1();
872
song->endUndo(SC_EVENT_INSERTED);
875
if (tag == "event") {
876
MidiEvent* e = new MidiEvent();
878
e->setPosTick(e->posTick() + pos);
879
e->setPort(track()->outPort());
880
e->setChannel(track()->outChannel());
881
midiThread->msgAddEvent(e, curPart, false);
884
xml.unknown("PianoCanvas::paste");
893
//---------------------------------------------------------
896
//---------------------------------------------------------
898
void PianoCanvas::paste()
900
QCString subtype("eventlist");
901
QMimeSource* ms = QApplication::clipboard()->data();
903
if (!QTextDrag::decode(ms, pt, subtype)) {
904
printf("cannot paste: bad data type\n");
907
pasteAt(pt, song->cpos());
910
//---------------------------------------------------------
912
//---------------------------------------------------------
914
void PianoCanvas::startDrag(CItem* /* item*/, bool copymode)
916
QTextDrag* drag = getTextDrag(this);
918
// QApplication::clipboard()->setData(drag);
927
//---------------------------------------------------------
929
//---------------------------------------------------------
931
void PianoCanvas::dragEnterEvent(QDragEnterEvent* event)
933
event->accept(QTextDrag::canDecode(event));
936
//---------------------------------------------------------
938
//---------------------------------------------------------
940
void PianoCanvas::dragMoveEvent(QDragMoveEvent*)
942
// printf("drag move %x\n", this);
945
//---------------------------------------------------------
947
//---------------------------------------------------------
949
void PianoCanvas::dragLeaveEvent(QDragLeaveEvent*)
951
// printf("drag leave\n");
954
//---------------------------------------------------------
956
//---------------------------------------------------------
958
void PianoCanvas::viewDropEvent(QDropEvent* event)
961
if (event->source() == this) {
962
printf("local DROP\n");
965
if (QTextDrag::decode(event, text)) {
966
printf("drop <%s>\n", text.ascii());
967
int x = editor->rasterVal(event->pos().x());
973
printf("cannot decode drop\n");
977
//---------------------------------------------------------
979
//---------------------------------------------------------
981
void PianoCanvas::itemPressed(const CItem* item)
986
int port = track()->outPort();
987
int channel = track()->outChannel();
988
NEvent* nevent = (NEvent*) item;
989
MidiEvent* event = (MidiEvent*)nevent->event();
990
playedPitch = event->pitch();
991
int velo = event->velo();
994
MidiEvent e(port, channel, 0, MidiEvent::Note, playedPitch, velo, 0, 0);
995
midiThread->playMidiEvent(&e);
998
//---------------------------------------------------------
1000
//---------------------------------------------------------
1002
void PianoCanvas::itemReleased(const CItem* item, const QPoint&)
1006
int port = track()->outPort();
1007
int channel = track()->outChannel();
1010
MidiEvent ev(port, channel, 0, MidiEvent::Note, playedPitch, 0, 0, 0);
1011
midiThread->playMidiEvent(&ev);
1015
//---------------------------------------------------------
1017
//---------------------------------------------------------
1019
void PianoCanvas::itemMoved(const CItem* item, const QPoint& pos)
1021
int npitch = y2pitch(pos.y());
1022
if ((playedPitch != -1) && (playedPitch != npitch)) {
1023
int port = track()->outPort();
1024
int channel = track()->outChannel();
1025
NEvent* nevent = (NEvent*) item;
1026
MidiEvent* event = (MidiEvent*)nevent->event();
1029
MidiEvent ev1(port, channel, 0, MidiEvent::Note, playedPitch, 0, 0, 0);
1030
midiThread->playMidiEvent(&ev1);
1032
MidiEvent e2(port, channel, 0, MidiEvent::Note, npitch, event->velo(), 0, 0);
1033
midiThread->playMidiEvent(&e2);
1034
playedPitch = npitch;
1038
//---------------------------------------------------------
1040
//---------------------------------------------------------
1042
void PianoCanvas::curPartChanged()
1044
editor->setCaption(getCaption());