comparison layer/FlexiNoteLayer.cpp @ 946:36cddc3de023 alignment_view

Merge from default branch
author Chris Cannam
date Mon, 20 Apr 2015 09:19:52 +0100
parents 26da827e8fb5
children bb80983c9e61
comparison
equal deleted inserted replaced
897:499b637f2a26 946:36cddc3de023
220 // unit.startsWith("midi")) return true; 220 // unit.startsWith("midi")) return true;
221 // return false; 221 // return false;
222 } 222 }
223 223
224 bool 224 bool
225 FlexiNoteLayer::getValueExtents(float &min, float &max, 225 FlexiNoteLayer::getValueExtents(double &min, double &max,
226 bool &logarithmic, QString &unit) const 226 bool &logarithmic, QString &unit) const
227 { 227 {
228 if (!m_model) return false; 228 if (!m_model) return false;
229 min = m_model->getValueMinimum(); 229 min = m_model->getValueMinimum();
230 max = m_model->getValueMaximum(); 230 max = m_model->getValueMaximum();
231 231
232 if (shouldConvertMIDIToHz()) { 232 if (shouldConvertMIDIToHz()) {
233 unit = "Hz"; 233 unit = "Hz";
234 min = Pitch::getFrequencyForPitch(lrintf(min)); 234 min = Pitch::getFrequencyForPitch(int(lrint(min)));
235 max = Pitch::getFrequencyForPitch(lrintf(max + 1)); 235 max = Pitch::getFrequencyForPitch(int(lrint(max + 1)));
236 } else unit = getScaleUnits(); 236 } else unit = getScaleUnits();
237 237
238 if (m_verticalScale == MIDIRangeScale || 238 if (m_verticalScale == MIDIRangeScale ||
239 m_verticalScale == LogScale) logarithmic = true; 239 m_verticalScale == LogScale) logarithmic = true;
240 240
241 return true; 241 return true;
242 } 242 }
243 243
244 bool 244 bool
245 FlexiNoteLayer::getDisplayExtents(float &min, float &max) const 245 FlexiNoteLayer::getDisplayExtents(double &min, double &max) const
246 { 246 {
247 if (!m_model || shouldAutoAlign()) { 247 if (!m_model || shouldAutoAlign()) {
248 // std::cerr << "No model or shouldAutoAlign()" << std::endl; 248 // std::cerr << "No model or shouldAutoAlign()" << std::endl;
249 return false; 249 return false;
250 } 250 }
262 min = m_scaleMinimum; 262 min = m_scaleMinimum;
263 max = m_scaleMaximum; 263 max = m_scaleMaximum;
264 } 264 }
265 265
266 if (shouldConvertMIDIToHz()) { 266 if (shouldConvertMIDIToHz()) {
267 min = Pitch::getFrequencyForPitch(lrintf(min)); 267 min = Pitch::getFrequencyForPitch(int(lrint(min)));
268 max = Pitch::getFrequencyForPitch(lrintf(max + 1)); 268 max = Pitch::getFrequencyForPitch(int(lrint(max + 1)));
269 } 269 }
270 270
271 #ifdef DEBUG_NOTE_LAYER 271 #ifdef DEBUG_NOTE_LAYER
272 cerr << "NoteLayer::getDisplayExtents: min = " << min << ", max = " << max << " (m_scaleMinimum = " << m_scaleMinimum << ", m_scaleMaximum = " << m_scaleMaximum << ")" << endl; 272 cerr << "NoteLayer::getDisplayExtents: min = " << min << ", max = " << max << " (m_scaleMinimum = " << m_scaleMinimum << ", m_scaleMaximum = " << m_scaleMaximum << ")" << endl;
273 #endif 273 #endif
274 274
275 return true; 275 return true;
276 } 276 }
277 277
278 bool 278 bool
279 FlexiNoteLayer::setDisplayExtents(float min, float max) 279 FlexiNoteLayer::setDisplayExtents(double min, double max)
280 { 280 {
281 if (!m_model) return false; 281 if (!m_model) return false;
282 282
283 if (min == max) { 283 if (min == max) {
284 if (min == 0.f) { 284 if (min == 0.f) {
285 max = 1.f; 285 max = 1.f;
286 } else { 286 } else {
287 max = min * 1.0001; 287 max = min * 1.0001f;
288 } 288 }
289 } 289 }
290 290
291 m_scaleMinimum = min; 291 m_scaleMinimum = min;
292 m_scaleMaximum = max; 292 m_scaleMaximum = max;
316 if (!m_model) return 0; 316 if (!m_model) return 0;
317 317
318 RangeMapper *mapper = getNewVerticalZoomRangeMapper(); 318 RangeMapper *mapper = getNewVerticalZoomRangeMapper();
319 if (!mapper) return 0; 319 if (!mapper) return 0;
320 320
321 float dmin, dmax; 321 double dmin, dmax;
322 getDisplayExtents(dmin, dmax); 322 getDisplayExtents(dmin, dmax);
323 323
324 int nr = mapper->getPositionForValue(dmax - dmin); 324 int nr = mapper->getPositionForValue(dmax - dmin);
325 325
326 delete mapper; 326 delete mapper;
337 if (!m_model) return; 337 if (!m_model) return;
338 338
339 RangeMapper *mapper = getNewVerticalZoomRangeMapper(); 339 RangeMapper *mapper = getNewVerticalZoomRangeMapper();
340 if (!mapper) return; 340 if (!mapper) return;
341 341
342 float min, max; 342 double min, max;
343 bool logarithmic; 343 bool logarithmic;
344 QString unit; 344 QString unit;
345 getValueExtents(min, max, logarithmic, unit); 345 getValueExtents(min, max, logarithmic, unit);
346 346
347 float dmin, dmax; 347 double dmin, dmax;
348 getDisplayExtents(dmin, dmax); 348 getDisplayExtents(dmin, dmax);
349 349
350 float newdist = mapper->getValueForPosition(100 - step); 350 double newdist = mapper->getValueForPosition(100 - step);
351 351
352 float newmin, newmax; 352 double newmin, newmax;
353 353
354 if (logarithmic) { 354 if (logarithmic) {
355 355
356 // see SpectrogramLayer::setVerticalZoomStep 356 // see SpectrogramLayer::setVerticalZoomStep
357 357
358 newmax = (newdist + sqrtf(newdist*newdist + 4*dmin*dmax)) / 2; 358 newmax = (newdist + sqrt(newdist*newdist + 4*dmin*dmax)) / 2;
359 newmin = newmax - newdist; 359 newmin = newmax - newdist;
360 360
361 // cerr << "newmin = " << newmin << ", newmax = " << newmax << endl; 361 // cerr << "newmin = " << newmin << ", newmax = " << newmax << endl;
362 362
363 } else { 363 } else {
364 float dmid = (dmax + dmin) / 2; 364 double dmid = (dmax + dmin) / 2;
365 newmin = dmid - newdist / 2; 365 newmin = dmid - newdist / 2;
366 newmax = dmid + newdist / 2; 366 newmax = dmid + newdist / 2;
367 } 367 }
368 368
369 if (newmin < min) { 369 if (newmin < min) {
386 { 386 {
387 if (!m_model) return 0; 387 if (!m_model) return 0;
388 388
389 RangeMapper *mapper; 389 RangeMapper *mapper;
390 390
391 float min, max; 391 double min, max;
392 bool logarithmic; 392 bool logarithmic;
393 QString unit; 393 QString unit;
394 getValueExtents(min, max, logarithmic, unit); 394 getValueExtents(min, max, logarithmic, unit);
395 395
396 if (min == max) return 0; 396 if (min == max) return 0;
407 FlexiNoteModel::PointList 407 FlexiNoteModel::PointList
408 FlexiNoteLayer::getLocalPoints(View *v, int x) const 408 FlexiNoteLayer::getLocalPoints(View *v, int x) const
409 { 409 {
410 if (!m_model) return FlexiNoteModel::PointList(); 410 if (!m_model) return FlexiNoteModel::PointList();
411 411
412 int frame = v->getFrameForX(x); 412 sv_frame_t frame = v->getFrameForX(x);
413 413
414 FlexiNoteModel::PointList onPoints = 414 FlexiNoteModel::PointList onPoints =
415 m_model->getPoints(frame); 415 m_model->getPoints(frame);
416 416
417 if (!onPoints.empty()) { 417 if (!onPoints.empty()) {
450 bool 450 bool
451 FlexiNoteLayer::getPointToDrag(View *v, int x, int y, FlexiNoteModel::Point &p) const 451 FlexiNoteLayer::getPointToDrag(View *v, int x, int y, FlexiNoteModel::Point &p) const
452 { 452 {
453 if (!m_model) return false; 453 if (!m_model) return false;
454 454
455 int frame = v->getFrameForX(x); 455 sv_frame_t frame = v->getFrameForX(x);
456 456
457 FlexiNoteModel::PointList onPoints = m_model->getPoints(frame); 457 FlexiNoteModel::PointList onPoints = m_model->getPoints(frame);
458 if (onPoints.empty()) return false; 458 if (onPoints.empty()) return false;
459 459
460 // cerr << "frame " << frame << ": " << onPoints.size() << " candidate points" << endl; 460 // cerr << "frame " << frame << ": " << onPoints.size() << " candidate points" << endl;
479 FlexiNoteLayer::getNoteToEdit(View *v, int x, int y, FlexiNoteModel::Point &p) const 479 FlexiNoteLayer::getNoteToEdit(View *v, int x, int y, FlexiNoteModel::Point &p) const
480 { 480 {
481 // GF: find the note that is closest to the cursor 481 // GF: find the note that is closest to the cursor
482 if (!m_model) return false; 482 if (!m_model) return false;
483 483
484 int frame = v->getFrameForX(x); 484 sv_frame_t frame = v->getFrameForX(x);
485 485
486 FlexiNoteModel::PointList onPoints = m_model->getPoints(frame); 486 FlexiNoteModel::PointList onPoints = m_model->getPoints(frame);
487 if (onPoints.empty()) return false; 487 if (onPoints.empty()) return false;
488 488
489 // std::cerr << "frame " << frame << ": " << onPoints.size() << " candidate points" << std::endl; 489 // std::cerr << "frame " << frame << ": " << onPoints.size() << " candidate points" << std::endl;
550 550
551 QString pitchText; 551 QString pitchText;
552 552
553 if (shouldConvertMIDIToHz()) { 553 if (shouldConvertMIDIToHz()) {
554 554
555 int mnote = lrintf(note.value); 555 int mnote = int(lrint(note.value));
556 int cents = lrintf((note.value - mnote) * 100); 556 int cents = int(lrint((note.value - double(mnote)) * 100));
557 float freq = Pitch::getFrequencyForPitch(mnote, cents); 557 double freq = Pitch::getFrequencyForPitch(mnote, cents);
558 pitchText = tr("%1 (%2, %3 Hz)") 558 pitchText = tr("%1 (%2, %3 Hz)")
559 .arg(Pitch::getPitchLabel(mnote, cents)) 559 .arg(Pitch::getPitchLabel(mnote, cents))
560 .arg(mnote) 560 .arg(mnote)
561 .arg(freq); 561 .arg(freq);
562 562
591 getYForValue(v, note.value)); 591 getYForValue(v, note.value));
592 return text; 592 return text;
593 } 593 }
594 594
595 bool 595 bool
596 FlexiNoteLayer::snapToFeatureFrame(View *v, int &frame, 596 FlexiNoteLayer::snapToFeatureFrame(View *v, sv_frame_t &frame,
597 int &resolution, 597 int &resolution,
598 SnapType snap) const 598 SnapType snap) const
599 { 599 {
600 if (!m_model) { 600 if (!m_model) {
601 return Layer::snapToFeatureFrame(v, frame, resolution, snap); 601 return Layer::snapToFeatureFrame(v, frame, resolution, snap);
611 frame = points.begin()->frame; 611 frame = points.begin()->frame;
612 return true; 612 return true;
613 } 613 }
614 614
615 points = m_model->getPoints(frame, frame); 615 points = m_model->getPoints(frame, frame);
616 int snapped = frame; 616 sv_frame_t snapped = frame;
617 bool found = false; 617 bool found = false;
618 618
619 for (FlexiNoteModel::PointList::const_iterator i = points.begin(); 619 for (FlexiNoteModel::PointList::const_iterator i = points.begin();
620 i != points.end(); ++i) { 620 i != points.end(); ++i) {
621 621
671 frame = snapped; 671 frame = snapped;
672 return found; 672 return found;
673 } 673 }
674 674
675 void 675 void
676 FlexiNoteLayer::getScaleExtents(View *v, float &min, float &max, bool &log) const 676 FlexiNoteLayer::getScaleExtents(View *v, double &min, double &max, bool &log) const
677 { 677 {
678 min = 0.0; 678 min = 0.0;
679 max = 0.0; 679 max = 0.0;
680 log = false; 680 log = false;
681 681
689 689
690 min = m_model->getValueMinimum(); 690 min = m_model->getValueMinimum();
691 max = m_model->getValueMaximum(); 691 max = m_model->getValueMaximum();
692 692
693 if (shouldConvertMIDIToHz()) { 693 if (shouldConvertMIDIToHz()) {
694 min = Pitch::getFrequencyForPitch(lrintf(min)); 694 min = Pitch::getFrequencyForPitch(int(lrint(min)));
695 max = Pitch::getFrequencyForPitch(lrintf(max + 1)); 695 max = Pitch::getFrequencyForPitch(int(lrint(max + 1)));
696 } 696 }
697 697
698 #ifdef DEBUG_NOTE_LAYER 698 #ifdef DEBUG_NOTE_LAYER
699 cerr << "FlexiNoteLayer[" << this << "]::getScaleExtents: min = " << min << ", max = " << max << ", log = " << log << endl; 699 cerr << "FlexiNoteLayer[" << this << "]::getScaleExtents: min = " << min << ", max = " << max << ", log = " << log << endl;
700 #endif 700 #endif
714 714
715 if (m_verticalScale == MIDIRangeScale) { 715 if (m_verticalScale == MIDIRangeScale) {
716 min = Pitch::getFrequencyForPitch(0); 716 min = Pitch::getFrequencyForPitch(0);
717 max = Pitch::getFrequencyForPitch(70); 717 max = Pitch::getFrequencyForPitch(70);
718 } else if (shouldConvertMIDIToHz()) { 718 } else if (shouldConvertMIDIToHz()) {
719 min = Pitch::getFrequencyForPitch(lrintf(min)); 719 min = Pitch::getFrequencyForPitch(int(lrint(min)));
720 max = Pitch::getFrequencyForPitch(lrintf(max + 1)); 720 max = Pitch::getFrequencyForPitch(int(lrint(max + 1)));
721 } 721 }
722 722
723 if (m_verticalScale == LogScale || m_verticalScale == MIDIRangeScale) { 723 if (m_verticalScale == LogScale || m_verticalScale == MIDIRangeScale) {
724 LogRange::mapRange(min, max); 724 LogRange::mapRange(min, max);
725 log = true; 725 log = true;
728 728
729 if (max == min) max = min + 1.0; 729 if (max == min) max = min + 1.0;
730 } 730 }
731 731
732 int 732 int
733 FlexiNoteLayer::getYForValue(View *v, float val) const 733 FlexiNoteLayer::getYForValue(View *v, double val) const
734 { 734 {
735 float min = 0.0, max = 0.0; 735 double min = 0.0, max = 0.0;
736 bool logarithmic = false; 736 bool logarithmic = false;
737 int h = v->height(); 737 int h = v->height();
738 738
739 getScaleExtents(v, min, max, logarithmic); 739 getScaleExtents(v, min, max, logarithmic);
740 740
741 #ifdef DEBUG_NOTE_LAYER 741 #ifdef DEBUG_NOTE_LAYER
742 cerr << "FlexiNoteLayer[" << this << "]::getYForValue(" << val << "): min = " << min << ", max = " << max << ", log = " << logarithmic << endl; 742 cerr << "FlexiNoteLayer[" << this << "]::getYForValue(" << val << "): min = " << min << ", max = " << max << ", log = " << logarithmic << endl;
743 #endif 743 #endif
744 744
745 if (shouldConvertMIDIToHz()) { 745 if (shouldConvertMIDIToHz()) {
746 val = Pitch::getFrequencyForPitch(lrintf(val), 746 val = Pitch::getFrequencyForPitch(int(lrint(val)),
747 lrintf((val - lrintf(val)) * 100)); 747 int(lrint((val - floor(val)) * 100.0)));
748 #ifdef DEBUG_NOTE_LAYER 748 #ifdef DEBUG_NOTE_LAYER
749 cerr << "shouldConvertMIDIToHz true, val now = " << val << endl; 749 cerr << "shouldConvertMIDIToHz true, val now = " << val << endl;
750 #endif 750 #endif
751 } 751 }
752 752
762 cerr << "y = " << y << endl; 762 cerr << "y = " << y << endl;
763 #endif 763 #endif
764 return y; 764 return y;
765 } 765 }
766 766
767 float 767 double
768 FlexiNoteLayer::getValueForY(View *v, int y) const 768 FlexiNoteLayer::getValueForY(View *v, int y) const
769 { 769 {
770 float min = 0.0, max = 0.0; 770 double min = 0.0, max = 0.0;
771 bool logarithmic = false; 771 bool logarithmic = false;
772 int h = v->height(); 772 int h = v->height();
773 773
774 getScaleExtents(v, min, max, logarithmic); 774 getScaleExtents(v, min, max, logarithmic);
775 775
776 float val = min + (float(h - y) * float(max - min)) / h; 776 double val = min + (double(h - y) * double(max - min)) / h;
777 777
778 if (logarithmic) { 778 if (logarithmic) {
779 val = powf(10.f, val); 779 val = pow(10.f, val);
780 } 780 }
781 781
782 if (shouldConvertMIDIToHz()) { 782 if (shouldConvertMIDIToHz()) {
783 val = Pitch::getPitchForFrequency(val); 783 val = Pitch::getPitchForFrequency(val);
784 } 784 }
796 void 796 void
797 FlexiNoteLayer::paint(View *v, QPainter &paint, QRect rect) const 797 FlexiNoteLayer::paint(View *v, QPainter &paint, QRect rect) const
798 { 798 {
799 if (!m_model || !m_model->isOK()) return; 799 if (!m_model || !m_model->isOK()) return;
800 800
801 int sampleRate = m_model->getSampleRate(); 801 sv_samplerate_t sampleRate = m_model->getSampleRate();
802 if (!sampleRate) return; 802 if (!sampleRate) return;
803 803
804 // Profiler profiler("FlexiNoteLayer::paint", true); 804 // Profiler profiler("FlexiNoteLayer::paint", true);
805 805
806 int x1 = rect.right(); 806 int x1 = rect.right();
807 int frame1 = v->getFrameForX(x1); 807 sv_frame_t frame1 = v->getFrameForX(x1);
808 808
809 FlexiNoteModel::PointList points(m_model->getPoints(0, frame1)); 809 FlexiNoteModel::PointList points(m_model->getPoints(0, frame1));
810 if (points.empty()) return; 810 if (points.empty()) return;
811 811
812 paint.setPen(getBaseQColor()); 812 paint.setPen(getBaseQColor());
815 brushColour.setAlpha(80); 815 brushColour.setAlpha(80);
816 816
817 // SVDEBUG << "FlexiNoteLayer::paint: resolution is " 817 // SVDEBUG << "FlexiNoteLayer::paint: resolution is "
818 // << m_model->getResolution() << " frames" << endl; 818 // << m_model->getResolution() << " frames" << endl;
819 819
820 float min = m_model->getValueMinimum(); 820 double min = m_model->getValueMinimum();
821 float max = m_model->getValueMaximum(); 821 double max = m_model->getValueMaximum();
822 if (max == min) max = min + 1.0; 822 if (max == min) max = min + 1.0;
823 823
824 QPoint localPos; 824 QPoint localPos;
825 FlexiNoteModel::Point illuminatePoint(0); 825 FlexiNoteModel::Point illuminatePoint(0);
826 bool shouldIlluminate = false; 826 bool shouldIlluminate = false;
921 FlexiNoteLayer::paintVerticalScale(View *v, bool, QPainter &paint, QRect) const 921 FlexiNoteLayer::paintVerticalScale(View *v, bool, QPainter &paint, QRect) const
922 { 922 {
923 if (!m_model || m_model->getPoints().empty()) return; 923 if (!m_model || m_model->getPoints().empty()) return;
924 924
925 QString unit; 925 QString unit;
926 float min, max; 926 double min, max;
927 bool logarithmic; 927 bool logarithmic;
928 928
929 int w = getVerticalScaleWidth(v, false, paint); 929 int w = getVerticalScaleWidth(v, false, paint);
930 int h = v->height(); 930 int h = v->height();
931 931
960 { 960 {
961 // SVDEBUG << "FlexiNoteLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl; 961 // SVDEBUG << "FlexiNoteLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl;
962 962
963 if (!m_model) return; 963 if (!m_model) return;
964 964
965 int frame = v->getFrameForX(e->x()); 965 sv_frame_t frame = v->getFrameForX(e->x());
966 if (frame < 0) frame = 0; 966 if (frame < 0) frame = 0;
967 frame = frame / m_model->getResolution() * m_model->getResolution(); 967 frame = frame / m_model->getResolution() * m_model->getResolution();
968 968
969 float value = getValueForY(v, e->y()); 969 double value = getValueForY(v, e->y());
970 970
971 m_editingPoint = FlexiNoteModel::Point(frame, value, 0, 0.8, tr("New Point")); 971 m_editingPoint = FlexiNoteModel::Point(frame, float(value), 0, 0.8f, tr("New Point"));
972 m_originalPoint = m_editingPoint; 972 m_originalPoint = m_editingPoint;
973 973
974 if (m_editingCommand) finish(m_editingCommand); 974 if (m_editingCommand) finish(m_editingCommand);
975 m_editingCommand = new FlexiNoteModel::EditCommand(m_model, 975 m_editingCommand = new FlexiNoteModel::EditCommand(m_model,
976 tr("Draw Point")); 976 tr("Draw Point"));
984 { 984 {
985 // SVDEBUG << "FlexiNoteLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl; 985 // SVDEBUG << "FlexiNoteLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl;
986 986
987 if (!m_model || !m_editing) return; 987 if (!m_model || !m_editing) return;
988 988
989 int frame = v->getFrameForX(e->x()); 989 sv_frame_t frame = v->getFrameForX(e->x());
990 if (frame < 0) frame = 0; 990 if (frame < 0) frame = 0;
991 frame = frame / m_model->getResolution() * m_model->getResolution(); 991 frame = frame / m_model->getResolution() * m_model->getResolution();
992 992
993 float newValue = getValueForY(v, e->y()); 993 double newValue = getValueForY(v, e->y());
994 994
995 int newFrame = m_editingPoint.frame; 995 sv_frame_t newFrame = m_editingPoint.frame;
996 int newDuration = frame - newFrame; 996 sv_frame_t newDuration = frame - newFrame;
997 if (newDuration < 0) { 997 if (newDuration < 0) {
998 newFrame = frame; 998 newFrame = frame;
999 newDuration = -newDuration; 999 newDuration = -newDuration;
1000 } else if (newDuration == 0) { 1000 } else if (newDuration == 0) {
1001 newDuration = 1; 1001 newDuration = 1;
1002 } 1002 }
1003 1003
1004 m_editingCommand->deletePoint(m_editingPoint); 1004 m_editingCommand->deletePoint(m_editingPoint);
1005 m_editingPoint.frame = newFrame; 1005 m_editingPoint.frame = newFrame;
1006 m_editingPoint.value = newValue; 1006 m_editingPoint.value = float(newValue);
1007 m_editingPoint.duration = newDuration; 1007 m_editingPoint.duration = newDuration;
1008 m_editingCommand->addPoint(m_editingPoint); 1008 m_editingCommand->addPoint(m_editingPoint);
1009 } 1009 }
1010 1010
1011 void 1011 void
1083 1083
1084 m_editing = true; 1084 m_editing = true;
1085 m_dragStartX = e->x(); 1085 m_dragStartX = e->x();
1086 m_dragStartY = e->y(); 1086 m_dragStartY = e->y();
1087 1087
1088 int onset = m_originalPoint.frame; 1088 sv_frame_t onset = m_originalPoint.frame;
1089 int offset = m_originalPoint.frame + m_originalPoint.duration - 1; 1089 sv_frame_t offset = m_originalPoint.frame + m_originalPoint.duration - 1;
1090 1090
1091 m_greatestLeftNeighbourFrame = -1; 1091 m_greatestLeftNeighbourFrame = -1;
1092 m_smallestRightNeighbourFrame = std::numeric_limits<int>::max(); 1092 m_smallestRightNeighbourFrame = std::numeric_limits<int>::max();
1093 1093
1094 for (FlexiNoteModel::PointList::const_iterator i = m_model->getPoints().begin(); 1094 for (FlexiNoteModel::PointList::const_iterator i = m_model->getPoints().begin();
1120 int xdist = e->x() - m_dragStartX; 1120 int xdist = e->x() - m_dragStartX;
1121 int ydist = e->y() - m_dragStartY; 1121 int ydist = e->y() - m_dragStartY;
1122 int newx = m_dragPointX + xdist; 1122 int newx = m_dragPointX + xdist;
1123 int newy = m_dragPointY + ydist; 1123 int newy = m_dragPointY + ydist;
1124 1124
1125 int dragFrame = v->getFrameForX(newx); 1125 sv_frame_t dragFrame = v->getFrameForX(newx);
1126 if (dragFrame < 0) dragFrame = 0; 1126 if (dragFrame < 0) dragFrame = 0;
1127 dragFrame = dragFrame / m_model->getResolution() * m_model->getResolution(); 1127 dragFrame = dragFrame / m_model->getResolution() * m_model->getResolution();
1128 1128
1129 float value = getValueForY(v, newy); 1129 double value = getValueForY(v, newy);
1130 1130
1131 if (!m_editingCommand) { 1131 if (!m_editingCommand) {
1132 m_editingCommand = new FlexiNoteModel::EditCommand(m_model, 1132 m_editingCommand = new FlexiNoteModel::EditCommand(m_model,
1133 tr("Drag Point")); 1133 tr("Drag Point"));
1134 } 1134 }
1135 1135
1136 m_editingCommand->deletePoint(m_editingPoint); 1136 m_editingCommand->deletePoint(m_editingPoint);
1137 1137
1138 std::cerr << "edit mode: " << m_editMode << std::endl; 1138 std::cerr << "edit mode: " << m_editMode << " intelligent actions = "
1139 << m_intelligentActions << std::endl;
1139 1140
1140 switch (m_editMode) { 1141 switch (m_editMode) {
1141 case LeftBoundary : { 1142 case LeftBoundary : {
1142 // left 1143 // left
1143 if (m_intelligentActions && dragFrame <= m_greatestLeftNeighbourFrame) dragFrame = m_greatestLeftNeighbourFrame + 1; 1144 if (m_intelligentActions && dragFrame <= m_greatestLeftNeighbourFrame) dragFrame = m_greatestLeftNeighbourFrame + 1;
1162 // right 1163 // right
1163 if (m_intelligentActions && dragFrame + m_originalPoint.duration >= m_smallestRightNeighbourFrame) { 1164 if (m_intelligentActions && dragFrame + m_originalPoint.duration >= m_smallestRightNeighbourFrame) {
1164 dragFrame = m_smallestRightNeighbourFrame - m_originalPoint.duration; 1165 dragFrame = m_smallestRightNeighbourFrame - m_originalPoint.duration;
1165 } 1166 }
1166 m_editingPoint.frame = dragFrame; 1167 m_editingPoint.frame = dragFrame;
1167 m_editingPoint.value = value; 1168
1169 m_editingPoint.value = float(value);
1170
1171 // Re-analyse region within +/- 1 semitone of the dragged value
1172 float cents = 0;
1173 int midiPitch = Pitch::getPitchForFrequency(m_editingPoint.value, &cents);
1174 double lower = Pitch::getFrequencyForPitch(midiPitch - 1, cents);
1175 double higher = Pitch::getFrequencyForPitch(midiPitch + 1, cents);
1176
1177 emit reAnalyseRegion(m_editingPoint.frame,
1178 m_editingPoint.frame + m_editingPoint.duration,
1179 float(lower), float(higher));
1168 break; 1180 break;
1169 } 1181 }
1170 case SplitNote: // nothing 1182 case SplitNote: // nothing
1171 break; 1183 break;
1172 } 1184 }
1173 updateNoteValue(v, m_editingPoint); 1185
1186 // updateNoteValueFromPitchCurve(v, m_editingPoint);
1174 m_editingCommand->addPoint(m_editingPoint); 1187 m_editingCommand->addPoint(m_editingPoint);
1188
1175 std::cerr << "added new point(" << m_editingPoint.frame << "," << m_editingPoint.duration << ")" << std::endl; 1189 std::cerr << "added new point(" << m_editingPoint.frame << "," << m_editingPoint.duration << ")" << std::endl;
1176 1190 }
1177 } 1191
1178 1192 void
1179 void 1193 FlexiNoteLayer::editEnd(View *v, QMouseEvent *e)
1180 FlexiNoteLayer::editEnd(View *, QMouseEvent *e)
1181 { 1194 {
1182 // SVDEBUG << "FlexiNoteLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl; 1195 // SVDEBUG << "FlexiNoteLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl;
1183 std::cerr << "FlexiNoteLayer::editEnd(" << e->x() << "," << e->y() << ")" << std::endl; 1196 std::cerr << "FlexiNoteLayer::editEnd(" << e->x() << "," << e->y() << ")" << std::endl;
1184 1197
1185 if (!m_model || !m_editing) return; 1198 if (!m_model || !m_editing) return;
1186 1199
1187 if (m_editingCommand) { 1200 if (m_editingCommand) {
1188 1201
1189 QString newName = m_editingCommand->getName(); 1202 QString newName = m_editingCommand->getName();
1203
1204 if (m_editMode == DragNote) {
1205 //!!! command nesting is wrong?
1206 emit materialiseReAnalysis();
1207 }
1208
1209 m_editingCommand->deletePoint(m_editingPoint);
1210 updateNoteValueFromPitchCurve(v, m_editingPoint);
1211 m_editingCommand->addPoint(m_editingPoint);
1190 1212
1191 if (m_editingPoint.frame != m_originalPoint.frame) { 1213 if (m_editingPoint.frame != m_originalPoint.frame) {
1192 if (m_editingPoint.value != m_originalPoint.value) { 1214 if (m_editingPoint.value != m_originalPoint.value) {
1193 newName = tr("Edit Point"); 1215 newName = tr("Edit Point");
1194 } else { 1216 } else {
1208 1230
1209 void 1231 void
1210 FlexiNoteLayer::splitStart(View *v, QMouseEvent *e) 1232 FlexiNoteLayer::splitStart(View *v, QMouseEvent *e)
1211 { 1233 {
1212 // GF: note splitting starts (!! remove printing soon) 1234 // GF: note splitting starts (!! remove printing soon)
1213 std::cerr << "splitStart" << std::endl; 1235 std::cerr << "splitStart (n.b. editStart will be called later, if the user drags the mouse)" << std::endl;
1214 if (!m_model) return; 1236 if (!m_model) return;
1215 1237
1216 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; 1238 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
1217 // m_originalPoint = m_editingPoint; 1239 // m_originalPoint = m_editingPoint;
1218 // 1240 //
1225 } 1247 }
1226 1248
1227 m_editing = true; 1249 m_editing = true;
1228 m_dragStartX = e->x(); 1250 m_dragStartX = e->x();
1229 m_dragStartY = e->y(); 1251 m_dragStartY = e->y();
1230
1231 } 1252 }
1232 1253
1233 void 1254 void
1234 FlexiNoteLayer::splitEnd(View *v, QMouseEvent *e) 1255 FlexiNoteLayer::splitEnd(View *v, QMouseEvent *e)
1235 { 1256 {
1242 if (xdist != 0 || ydist != 0) { 1263 if (xdist != 0 || ydist != 0) {
1243 std::cerr << "mouse moved" << std::endl; 1264 std::cerr << "mouse moved" << std::endl;
1244 return; 1265 return;
1245 } 1266 }
1246 1267
1247 int frame = v->getFrameForX(e->x()); 1268 sv_frame_t frame = v->getFrameForX(e->x());
1248 1269
1249 splitNotesAt(v, frame, e); 1270 splitNotesAt(v, frame, e);
1250 } 1271 }
1251 1272
1252 void 1273 void
1253 FlexiNoteLayer::splitNotesAt(View *v, int frame) 1274 FlexiNoteLayer::splitNotesAt(View *v, sv_frame_t frame)
1254 { 1275 {
1255 splitNotesAt(v, frame, 0); 1276 splitNotesAt(v, frame, 0);
1256 } 1277 }
1257 1278
1258 void 1279 void
1259 FlexiNoteLayer::splitNotesAt(View *v, int frame, QMouseEvent *e) 1280 FlexiNoteLayer::splitNotesAt(View *v, sv_frame_t frame, QMouseEvent *e)
1260 { 1281 {
1261 FlexiNoteModel::PointList onPoints = m_model->getPoints(frame); 1282 FlexiNoteModel::PointList onPoints = m_model->getPoints(frame);
1262 if (onPoints.empty()) return; 1283 if (onPoints.empty()) return;
1263 1284
1264 FlexiNote note(*onPoints.begin()); 1285 FlexiNote note(*onPoints.begin());
1278 FlexiNote newNote2(frame, note.value, 1299 FlexiNote newNote2(frame, note.value,
1279 note.duration - newNote1.duration, 1300 note.duration - newNote1.duration,
1280 note.level, note.label); 1301 note.level, note.label);
1281 1302
1282 if (m_intelligentActions) { 1303 if (m_intelligentActions) {
1283 if (updateNoteValue(v, newNote1)) { 1304 if (updateNoteValueFromPitchCurve(v, newNote1)) {
1284 command->addPoint(newNote1); 1305 command->addPoint(newNote1);
1285 } 1306 }
1286 if (updateNoteValue(v, newNote2)) { 1307 if (updateNoteValueFromPitchCurve(v, newNote2)) {
1287 command->addPoint(newNote2); 1308 command->addPoint(newNote2);
1288 } 1309 }
1289 } else { 1310 } else {
1290 command->addPoint(newNote1); 1311 command->addPoint(newNote1);
1291 command->addPoint(newNote2); 1312 command->addPoint(newNote2);
1299 FlexiNoteLayer::addNote(View *v, QMouseEvent *e) 1320 FlexiNoteLayer::addNote(View *v, QMouseEvent *e)
1300 { 1321 {
1301 std::cerr << "addNote" << std::endl; 1322 std::cerr << "addNote" << std::endl;
1302 if (!m_model) return; 1323 if (!m_model) return;
1303 1324
1304 int duration = 10000; 1325 sv_frame_t duration = 10000;
1305 1326
1306 int frame = v->getFrameForX(e->x()); 1327 sv_frame_t frame = v->getFrameForX(e->x());
1307 float value = getValueForY(v, e->y()); 1328 double value = getValueForY(v, e->y());
1308 1329
1309 FlexiNoteModel::PointList noteList = m_model->getPoints(); 1330 FlexiNoteModel::PointList noteList = m_model->getPoints();
1310 1331
1311 if (m_intelligentActions) { 1332 if (m_intelligentActions) {
1312 int smallestRightNeighbourFrame = 0; 1333 sv_frame_t smallestRightNeighbourFrame = 0;
1313 for (FlexiNoteModel::PointList::const_iterator i = noteList.begin(); 1334 for (FlexiNoteModel::PointList::const_iterator i = noteList.begin();
1314 i != noteList.end(); ++i) { 1335 i != noteList.end(); ++i) {
1315 FlexiNote currentNote = *i; 1336 FlexiNote currentNote = *i;
1316 if (currentNote.frame > frame) { 1337 if (currentNote.frame > frame) {
1317 smallestRightNeighbourFrame = currentNote.frame; 1338 smallestRightNeighbourFrame = currentNote.frame;
1324 } 1345 }
1325 } 1346 }
1326 1347
1327 if (!m_intelligentActions || 1348 if (!m_intelligentActions ||
1328 (m_model->getPoints(frame).empty() && duration > 0)) { 1349 (m_model->getPoints(frame).empty() && duration > 0)) {
1329 FlexiNote newNote(frame, value, duration, 100, "new note"); 1350 FlexiNote newNote(frame, float(value), duration, 100.f, "new note");
1330 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand 1351 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand
1331 (m_model, tr("Add Point")); 1352 (m_model, tr("Add Point"));
1332 command->addPoint(newNote); 1353 command->addPoint(newNote);
1333 finish(command); 1354 finish(command);
1334 } 1355 }
1337 SparseTimeValueModel * 1358 SparseTimeValueModel *
1338 FlexiNoteLayer::getAssociatedPitchModel(View *v) const 1359 FlexiNoteLayer::getAssociatedPitchModel(View *v) const
1339 { 1360 {
1340 // Better than we used to do, but still not very satisfactory 1361 // Better than we used to do, but still not very satisfactory
1341 1362
1342 cerr << "FlexiNoteLayer::getAssociatedPitchModel()" << endl; 1363 // cerr << "FlexiNoteLayer::getAssociatedPitchModel()" << endl;
1343 1364
1344 for (int i = 0; i < v->getLayerCount(); ++i) { 1365 for (int i = 0; i < v->getLayerCount(); ++i) {
1345 Layer *layer = v->getLayer(i); 1366 Layer *layer = v->getLayer(i);
1346 if (layer && 1367 if (layer &&
1347 layer->getLayerPresentationName() != "candidate") { 1368 layer->getLayerPresentationName() != "candidate") {
1348 cerr << "FlexiNoteLayer::getAssociatedPitchModel: looks like our layer is " << layer << endl; 1369 // cerr << "FlexiNoteLayer::getAssociatedPitchModel: looks like our layer is " << layer << endl;
1349 SparseTimeValueModel *model = qobject_cast<SparseTimeValueModel *> 1370 SparseTimeValueModel *model = qobject_cast<SparseTimeValueModel *>
1350 (layer->getModel()); 1371 (layer->getModel());
1351 cerr << "FlexiNoteLayer::getAssociatedPitchModel: and its model is " << model << endl; 1372 // cerr << "FlexiNoteLayer::getAssociatedPitchModel: and its model is " << model << endl;
1352 if (model && model->getScaleUnits() == "Hz") { 1373 if (model && model->getScaleUnits() == "Hz") {
1353 cerr << "FlexiNoteLayer::getAssociatedPitchModel: it's good, returning " << model << endl; 1374 cerr << "FlexiNoteLayer::getAssociatedPitchModel: it's good, returning " << model << endl;
1354 return model; 1375 return model;
1355 } 1376 }
1356 } 1377 }
1357 } 1378 }
1379 cerr << "FlexiNoteLayer::getAssociatedPitchModel: failed to find a model" << endl;
1358 return 0; 1380 return 0;
1359 } 1381 }
1360 1382
1361 void 1383 void
1362 FlexiNoteLayer::snapSelectedNotesToPitchTrack(View *v, Selection s) 1384 FlexiNoteLayer::snapSelectedNotesToPitchTrack(View *v, Selection s)
1386 cerr << "snapSelectedNotesToPitchTrack: making new note" << endl; 1408 cerr << "snapSelectedNotesToPitchTrack: making new note" << endl;
1387 FlexiNote newNote(note); 1409 FlexiNote newNote(note);
1388 1410
1389 command->deletePoint(note); 1411 command->deletePoint(note);
1390 1412
1391 if (updateNoteValue(v, newNote)) { 1413 if (updateNoteValueFromPitchCurve(v, newNote)) {
1392 command->addPoint(newNote); 1414 command->addPoint(newNote);
1393 } 1415 }
1394 } 1416 }
1395 1417
1396 finish(command); 1418 finish(command);
1432 command->deletePoint(*i); 1454 command->deletePoint(*i);
1433 1455
1434 ++i; 1456 ++i;
1435 } 1457 }
1436 1458
1437 updateNoteValue(v, newNote); 1459 updateNoteValueFromPitchCurve(v, newNote);
1438 command->addPoint(newNote); 1460 command->addPoint(newNote);
1439 finish(command); 1461 finish(command);
1440 } 1462 }
1441 1463
1442 bool 1464 bool
1443 FlexiNoteLayer::updateNoteValue(View *v, FlexiNoteModel::Point &note) const 1465 FlexiNoteLayer::updateNoteValueFromPitchCurve(View *v,
1466 FlexiNoteModel::Point &note) const
1444 { 1467 {
1445 SparseTimeValueModel *model = getAssociatedPitchModel(v); 1468 SparseTimeValueModel *model = getAssociatedPitchModel(v);
1446 if (!model) return false; 1469 if (!model) return false;
1447 1470
1448 std::cerr << model->getTypeName() << std::endl; 1471 std::cerr << model->getTypeName() << std::endl;
1452 1475
1453 std::cerr << "frame " << note.frame << ": " << dataPoints.size() << " candidate points" << std::endl; 1476 std::cerr << "frame " << note.frame << ": " << dataPoints.size() << " candidate points" << std::endl;
1454 1477
1455 if (dataPoints.empty()) return false; 1478 if (dataPoints.empty()) return false;
1456 1479
1457 std::vector<float> pitchValues; 1480 std::vector<double> pitchValues;
1458 1481
1459 for (SparseModel<TimeValuePoint>::PointList::const_iterator i = 1482 for (SparseModel<TimeValuePoint>::PointList::const_iterator i =
1460 dataPoints.begin(); i != dataPoints.end(); ++i) { 1483 dataPoints.begin(); i != dataPoints.end(); ++i) {
1461 if (i->frame >= note.frame && 1484 if (i->frame >= note.frame &&
1462 i->frame < note.frame + note.duration) { 1485 i->frame < note.frame + note.duration) {
1465 } 1488 }
1466 1489
1467 if (pitchValues.empty()) return false; 1490 if (pitchValues.empty()) return false;
1468 1491
1469 sort(pitchValues.begin(), pitchValues.end()); 1492 sort(pitchValues.begin(), pitchValues.end());
1470 int size = pitchValues.size(); 1493 int size = int(pitchValues.size());
1471 double median; 1494 double median;
1472 1495
1473 if (size % 2 == 0) { 1496 if (size % 2 == 0) {
1474 median = (pitchValues[size/2 - 1] + pitchValues[size/2]) / 2; 1497 median = (pitchValues[size/2 - 1] + pitchValues[size/2]) / 2;
1475 } else { 1498 } else {
1476 median = pitchValues[size/2]; 1499 median = pitchValues[size/2];
1477 } 1500 }
1478 1501
1479 note.value = median; 1502 std::cerr << "updateNoteValueFromPitchCurve: corrected from " << note.value << " to median " << median << std::endl;
1503
1504 note.value = float(median);
1480 1505
1481 return true; 1506 return true;
1482 } 1507 }
1483 1508
1484 void 1509 void
1490 if (!getNoteToEdit(v, e->x(), e->y(), note)) { 1515 if (!getNoteToEdit(v, e->x(), e->y(), note)) {
1491 // v->setCursor(Qt::UpArrowCursor); 1516 // v->setCursor(Qt::UpArrowCursor);
1492 return; 1517 return;
1493 } 1518 }
1494 1519
1495 bool closeToLeft = false, closeToRight = false, closeToTop = false, closeToBottom = false; 1520 bool closeToLeft = false, closeToRight = false,
1496 getRelativeMousePosition(v, note, e->x(), e->y(), closeToLeft, closeToRight, closeToTop, closeToBottom); 1521 closeToTop = false, closeToBottom = false;
1497 // if (!closeToLeft) return; 1522 getRelativeMousePosition(v, note, e->x(), e->y(),
1498 // if (closeToTop) v->setCursor(Qt::SizeVerCursor); 1523 closeToLeft, closeToRight,
1499 1524 closeToTop, closeToBottom);
1500 if (closeToLeft) { v->setCursor(Qt::SizeHorCursor); m_editMode = LeftBoundary; return; } 1525
1501 if (closeToRight) { v->setCursor(Qt::SizeHorCursor); m_editMode = RightBoundary; return; } 1526 if (closeToLeft) {
1502 if (closeToTop) { v->setCursor(Qt::CrossCursor); m_editMode = DragNote; return; } 1527 v->setCursor(Qt::SizeHorCursor);
1503 if (closeToBottom) { v->setCursor(Qt::UpArrowCursor); m_editMode = SplitNote; return; } 1528 m_editMode = LeftBoundary;
1504 1529 cerr << "edit mode -> LeftBoundary" << endl;
1505 v->setCursor(Qt::ArrowCursor); 1530 } else if (closeToRight) {
1506 1531 v->setCursor(Qt::SizeHorCursor);
1507 std::cerr << "Mouse moved in edit mode over FlexiNoteLayer" << std::endl; 1532 m_editMode = RightBoundary;
1508 // v->setCursor(Qt::SizeHorCursor); 1533 cerr << "edit mode -> RightBoundary" << endl;
1509 1534 } else if (closeToTop) {
1535 v->setCursor(Qt::CrossCursor);
1536 m_editMode = DragNote;
1537 cerr << "edit mode -> DragNote" << endl;
1538 } else if (closeToBottom) {
1539 v->setCursor(Qt::UpArrowCursor);
1540 m_editMode = SplitNote;
1541 cerr << "edit mode -> SplitNote" << endl;
1542 } else {
1543 v->setCursor(Qt::ArrowCursor);
1544 }
1510 } 1545 }
1511 1546
1512 void 1547 void
1513 FlexiNoteLayer::getRelativeMousePosition(View *v, FlexiNoteModel::Point &note, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const 1548 FlexiNoteLayer::getRelativeMousePosition(View *v, FlexiNoteModel::Point &note, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const
1514 { 1549 {
1580 delete dialog; 1615 delete dialog;
1581 return true; 1616 return true;
1582 } 1617 }
1583 1618
1584 void 1619 void
1585 FlexiNoteLayer::moveSelection(Selection s, int newStartFrame) 1620 FlexiNoteLayer::moveSelection(Selection s, sv_frame_t newStartFrame)
1586 { 1621 {
1587 if (!m_model) return; 1622 if (!m_model) return;
1588 1623
1589 FlexiNoteModel::EditCommand *command = 1624 FlexiNoteModel::EditCommand *command =
1590 new FlexiNoteModel::EditCommand(m_model, tr("Drag Selection")); 1625 new FlexiNoteModel::EditCommand(m_model, tr("Drag Selection"));
1624 for (FlexiNoteModel::PointList::iterator i = points.begin(); 1659 for (FlexiNoteModel::PointList::iterator i = points.begin();
1625 i != points.end(); ++i) { 1660 i != points.end(); ++i) {
1626 1661
1627 if (s.contains(i->frame)) { 1662 if (s.contains(i->frame)) {
1628 1663
1629 double targetStart = i->frame; 1664 double targetStart = double(i->frame);
1630 targetStart = newSize.getStartFrame() + 1665 targetStart = double(newSize.getStartFrame()) +
1631 double(targetStart - s.getStartFrame()) * ratio; 1666 targetStart - double(s.getStartFrame()) * ratio;
1632 1667
1633 double targetEnd = i->frame + i->duration; 1668 double targetEnd = double(i->frame + i->duration);
1634 targetEnd = newSize.getStartFrame() + 1669 targetEnd = double(newSize.getStartFrame()) +
1635 double(targetEnd - s.getStartFrame()) * ratio; 1670 targetEnd - double(s.getStartFrame()) * ratio;
1636 1671
1637 FlexiNoteModel::Point newPoint(*i); 1672 FlexiNoteModel::Point newPoint(*i);
1638 newPoint.frame = lrint(targetStart); 1673 newPoint.frame = lrint(targetStart);
1639 newPoint.duration = lrint(targetEnd - targetStart); 1674 newPoint.duration = lrint(targetEnd - targetStart);
1640 command->deletePoint(*i); 1675 command->deletePoint(*i);
1709 } 1744 }
1710 } 1745 }
1711 } 1746 }
1712 1747
1713 bool 1748 bool
1714 FlexiNoteLayer::paste(View *v, const Clipboard &from, int /*frameOffset */, bool /* interactive */) 1749 FlexiNoteLayer::paste(View *v, const Clipboard &from, sv_frame_t /*frameOffset */, bool /* interactive */)
1715 { 1750 {
1716 if (!m_model) return false; 1751 if (!m_model) return false;
1717 1752
1718 const Clipboard::PointList &points = from.getPoints(); 1753 const Clipboard::PointList &points = from.getPoints();
1719 1754
1741 1776
1742 for (Clipboard::PointList::const_iterator i = points.begin(); 1777 for (Clipboard::PointList::const_iterator i = points.begin();
1743 i != points.end(); ++i) { 1778 i != points.end(); ++i) {
1744 1779
1745 if (!i->haveFrame()) continue; 1780 if (!i->haveFrame()) continue;
1746 int frame = 0; 1781 sv_frame_t frame = 0;
1747 1782
1748 if (!realign) { 1783 if (!realign) {
1749 1784
1750 frame = i->getFrame(); 1785 frame = i->getFrame();
1751 1786
1766 else newPoint.value = (m_model->getValueMinimum() + 1801 else newPoint.value = (m_model->getValueMinimum() +
1767 m_model->getValueMaximum()) / 2; 1802 m_model->getValueMaximum()) / 2;
1768 if (i->haveLevel()) newPoint.level = i->getLevel(); 1803 if (i->haveLevel()) newPoint.level = i->getLevel();
1769 if (i->haveDuration()) newPoint.duration = i->getDuration(); 1804 if (i->haveDuration()) newPoint.duration = i->getDuration();
1770 else { 1805 else {
1771 int nextFrame = frame; 1806 sv_frame_t nextFrame = frame;
1772 Clipboard::PointList::const_iterator j = i; 1807 Clipboard::PointList::const_iterator j = i;
1773 for (; j != points.end(); ++j) { 1808 for (; j != points.end(); ++j) {
1774 if (!j->haveFrame()) continue; 1809 if (!j->haveFrame()) continue;
1775 if (j != i) break; 1810 if (j != i) break;
1776 } 1811 }
1790 finish(command); 1825 finish(command);
1791 return true; 1826 return true;
1792 } 1827 }
1793 1828
1794 void 1829 void
1795 FlexiNoteLayer::addNoteOn(int frame, int pitch, int velocity) 1830 FlexiNoteLayer::addNoteOn(sv_frame_t frame, int pitch, int velocity)
1796 { 1831 {
1797 m_pendingNoteOns.insert(FlexiNote(frame, pitch, 0, float(velocity) / 127.0, "")); 1832 m_pendingNoteOns.insert(FlexiNote(frame, float(pitch), 0, float(velocity / 127.0), ""));
1798 } 1833 }
1799 1834
1800 void 1835 void
1801 FlexiNoteLayer::addNoteOff(int frame, int pitch) 1836 FlexiNoteLayer::addNoteOff(sv_frame_t frame, int pitch)
1802 { 1837 {
1803 for (FlexiNoteSet::iterator i = m_pendingNoteOns.begin(); 1838 for (FlexiNoteSet::iterator i = m_pendingNoteOns.begin();
1804 i != m_pendingNoteOns.end(); ++i) { 1839 i != m_pendingNoteOns.end(); ++i) {
1805 if (lrintf((*i).value) == pitch) { 1840 if (lrint((*i).value) == pitch) {
1806 FlexiNote note(*i); 1841 FlexiNote note(*i);
1807 m_pendingNoteOns.erase(i); 1842 m_pendingNoteOns.erase(i);
1808 note.duration = frame - note.frame; 1843 note.duration = frame - note.frame;
1809 if (m_model) { 1844 if (m_model) {
1810 FlexiNoteModel::AddPointCommand *c = new FlexiNoteModel::AddPointCommand 1845 FlexiNoteModel::AddPointCommand *c = new FlexiNoteModel::AddPointCommand
1851 VerticalScale scale = (VerticalScale) 1886 VerticalScale scale = (VerticalScale)
1852 attributes.value("verticalScale").toInt(&ok); 1887 attributes.value("verticalScale").toInt(&ok);
1853 if (ok) setVerticalScale(scale); 1888 if (ok) setVerticalScale(scale);
1854 1889
1855 // bool alsoOk; 1890 // bool alsoOk;
1856 // float min = attributes.value("scaleMinimum").toFloat(&ok); 1891 // double min = attributes.value("scaleMinimum").toDouble(&ok);
1857 // float max = attributes.value("scaleMaximum").toFloat(&alsoOk); 1892 // double max = attributes.value("scaleMaximum").toDouble(&alsoOk);
1858 // if (ok && alsoOk && min != max) setDisplayExtents(min, max); 1893 // if (ok && alsoOk && min != max) setDisplayExtents(min, max);
1859 } 1894 }
1860 1895
1861 void 1896 void
1862 FlexiNoteLayer::setVerticalRangeToNoteRange(View *v) 1897 FlexiNoteLayer::setVerticalRangeToNoteRange(View *v)
1863 { 1898 {
1864 float minf = std::numeric_limits<float>::max(); 1899 double minf = std::numeric_limits<double>::max();
1865 float maxf = 0; 1900 double maxf = 0;
1866 bool hasNotes = 0; 1901 bool hasNotes = 0;
1867 for (FlexiNoteModel::PointList::const_iterator i = m_model->getPoints().begin(); 1902 for (FlexiNoteModel::PointList::const_iterator i = m_model->getPoints().begin();
1868 i != m_model->getPoints().end(); ++i) { 1903 i != m_model->getPoints().end(); ++i) {
1869 hasNotes = 1; 1904 hasNotes = 1;
1870 FlexiNote note = *i; 1905 FlexiNote note = *i;