Mercurial > hg > svgui
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, ¢s); | |
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 ¬e) const | 1465 FlexiNoteLayer::updateNoteValueFromPitchCurve(View *v, |
1466 FlexiNoteModel::Point ¬e) 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 ¬e, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const | 1548 FlexiNoteLayer::getRelativeMousePosition(View *v, FlexiNoteModel::Point ¬e, 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; |