Mercurial > hg > svgui
comparison layer/FlexiNoteLayer.cpp @ 922:26da827e8fb5 tonioni
Merge from cxx11 branch
author | Chris Cannam |
---|---|
date | Mon, 23 Mar 2015 11:26:28 +0000 |
parents | b62c2785ed83 b66fb15de477 |
children | bb80983c9e61 |
comparison
equal
deleted
inserted
replaced
921:4968bbaf1ed8 | 922:26da827e8fb5 |
---|---|
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 } |
1163 // right | 1163 // right |
1164 if (m_intelligentActions && dragFrame + m_originalPoint.duration >= m_smallestRightNeighbourFrame) { | 1164 if (m_intelligentActions && dragFrame + m_originalPoint.duration >= m_smallestRightNeighbourFrame) { |
1165 dragFrame = m_smallestRightNeighbourFrame - m_originalPoint.duration; | 1165 dragFrame = m_smallestRightNeighbourFrame - m_originalPoint.duration; |
1166 } | 1166 } |
1167 m_editingPoint.frame = dragFrame; | 1167 m_editingPoint.frame = dragFrame; |
1168 m_editingPoint.value = value; | 1168 |
1169 m_editingPoint.value = float(value); | |
1169 | 1170 |
1170 // Re-analyse region within +/- 1 semitone of the dragged value | 1171 // Re-analyse region within +/- 1 semitone of the dragged value |
1171 float cents = 0; | 1172 float cents = 0; |
1172 int midiPitch = Pitch::getPitchForFrequency(m_editingPoint.value, ¢s); | 1173 int midiPitch = Pitch::getPitchForFrequency(m_editingPoint.value, ¢s); |
1173 float lower = Pitch::getFrequencyForPitch(midiPitch - 1, cents); | 1174 double lower = Pitch::getFrequencyForPitch(midiPitch - 1, cents); |
1174 float higher = Pitch::getFrequencyForPitch(midiPitch + 1, cents); | 1175 double higher = Pitch::getFrequencyForPitch(midiPitch + 1, cents); |
1175 | 1176 |
1176 emit reAnalyseRegion(m_editingPoint.frame, | 1177 emit reAnalyseRegion(m_editingPoint.frame, |
1177 m_editingPoint.frame + m_editingPoint.duration, | 1178 m_editingPoint.frame + m_editingPoint.duration, |
1178 lower, higher); | 1179 float(lower), float(higher)); |
1179 break; | 1180 break; |
1180 } | 1181 } |
1181 case SplitNote: // nothing | 1182 case SplitNote: // nothing |
1182 break; | 1183 break; |
1183 } | 1184 } |
1262 if (xdist != 0 || ydist != 0) { | 1263 if (xdist != 0 || ydist != 0) { |
1263 std::cerr << "mouse moved" << std::endl; | 1264 std::cerr << "mouse moved" << std::endl; |
1264 return; | 1265 return; |
1265 } | 1266 } |
1266 | 1267 |
1267 int frame = v->getFrameForX(e->x()); | 1268 sv_frame_t frame = v->getFrameForX(e->x()); |
1268 | 1269 |
1269 splitNotesAt(v, frame, e); | 1270 splitNotesAt(v, frame, e); |
1270 } | 1271 } |
1271 | 1272 |
1272 void | 1273 void |
1273 FlexiNoteLayer::splitNotesAt(View *v, int frame) | 1274 FlexiNoteLayer::splitNotesAt(View *v, sv_frame_t frame) |
1274 { | 1275 { |
1275 splitNotesAt(v, frame, 0); | 1276 splitNotesAt(v, frame, 0); |
1276 } | 1277 } |
1277 | 1278 |
1278 void | 1279 void |
1279 FlexiNoteLayer::splitNotesAt(View *v, int frame, QMouseEvent *e) | 1280 FlexiNoteLayer::splitNotesAt(View *v, sv_frame_t frame, QMouseEvent *e) |
1280 { | 1281 { |
1281 FlexiNoteModel::PointList onPoints = m_model->getPoints(frame); | 1282 FlexiNoteModel::PointList onPoints = m_model->getPoints(frame); |
1282 if (onPoints.empty()) return; | 1283 if (onPoints.empty()) return; |
1283 | 1284 |
1284 FlexiNote note(*onPoints.begin()); | 1285 FlexiNote note(*onPoints.begin()); |
1319 FlexiNoteLayer::addNote(View *v, QMouseEvent *e) | 1320 FlexiNoteLayer::addNote(View *v, QMouseEvent *e) |
1320 { | 1321 { |
1321 std::cerr << "addNote" << std::endl; | 1322 std::cerr << "addNote" << std::endl; |
1322 if (!m_model) return; | 1323 if (!m_model) return; |
1323 | 1324 |
1324 int duration = 10000; | 1325 sv_frame_t duration = 10000; |
1325 | 1326 |
1326 int frame = v->getFrameForX(e->x()); | 1327 sv_frame_t frame = v->getFrameForX(e->x()); |
1327 float value = getValueForY(v, e->y()); | 1328 double value = getValueForY(v, e->y()); |
1328 | 1329 |
1329 FlexiNoteModel::PointList noteList = m_model->getPoints(); | 1330 FlexiNoteModel::PointList noteList = m_model->getPoints(); |
1330 | 1331 |
1331 if (m_intelligentActions) { | 1332 if (m_intelligentActions) { |
1332 int smallestRightNeighbourFrame = 0; | 1333 sv_frame_t smallestRightNeighbourFrame = 0; |
1333 for (FlexiNoteModel::PointList::const_iterator i = noteList.begin(); | 1334 for (FlexiNoteModel::PointList::const_iterator i = noteList.begin(); |
1334 i != noteList.end(); ++i) { | 1335 i != noteList.end(); ++i) { |
1335 FlexiNote currentNote = *i; | 1336 FlexiNote currentNote = *i; |
1336 if (currentNote.frame > frame) { | 1337 if (currentNote.frame > frame) { |
1337 smallestRightNeighbourFrame = currentNote.frame; | 1338 smallestRightNeighbourFrame = currentNote.frame; |
1344 } | 1345 } |
1345 } | 1346 } |
1346 | 1347 |
1347 if (!m_intelligentActions || | 1348 if (!m_intelligentActions || |
1348 (m_model->getPoints(frame).empty() && duration > 0)) { | 1349 (m_model->getPoints(frame).empty() && duration > 0)) { |
1349 FlexiNote newNote(frame, value, duration, 100, "new note"); | 1350 FlexiNote newNote(frame, float(value), duration, 100.f, "new note"); |
1350 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand | 1351 FlexiNoteModel::EditCommand *command = new FlexiNoteModel::EditCommand |
1351 (m_model, tr("Add Point")); | 1352 (m_model, tr("Add Point")); |
1352 command->addPoint(newNote); | 1353 command->addPoint(newNote); |
1353 finish(command); | 1354 finish(command); |
1354 } | 1355 } |
1474 | 1475 |
1475 std::cerr << "frame " << note.frame << ": " << dataPoints.size() << " candidate points" << std::endl; | 1476 std::cerr << "frame " << note.frame << ": " << dataPoints.size() << " candidate points" << std::endl; |
1476 | 1477 |
1477 if (dataPoints.empty()) return false; | 1478 if (dataPoints.empty()) return false; |
1478 | 1479 |
1479 std::vector<float> pitchValues; | 1480 std::vector<double> pitchValues; |
1480 | 1481 |
1481 for (SparseModel<TimeValuePoint>::PointList::const_iterator i = | 1482 for (SparseModel<TimeValuePoint>::PointList::const_iterator i = |
1482 dataPoints.begin(); i != dataPoints.end(); ++i) { | 1483 dataPoints.begin(); i != dataPoints.end(); ++i) { |
1483 if (i->frame >= note.frame && | 1484 if (i->frame >= note.frame && |
1484 i->frame < note.frame + note.duration) { | 1485 i->frame < note.frame + note.duration) { |
1487 } | 1488 } |
1488 | 1489 |
1489 if (pitchValues.empty()) return false; | 1490 if (pitchValues.empty()) return false; |
1490 | 1491 |
1491 sort(pitchValues.begin(), pitchValues.end()); | 1492 sort(pitchValues.begin(), pitchValues.end()); |
1492 int size = pitchValues.size(); | 1493 int size = int(pitchValues.size()); |
1493 double median; | 1494 double median; |
1494 | 1495 |
1495 if (size % 2 == 0) { | 1496 if (size % 2 == 0) { |
1496 median = (pitchValues[size/2 - 1] + pitchValues[size/2]) / 2; | 1497 median = (pitchValues[size/2 - 1] + pitchValues[size/2]) / 2; |
1497 } else { | 1498 } else { |
1498 median = pitchValues[size/2]; | 1499 median = pitchValues[size/2]; |
1499 } | 1500 } |
1500 | 1501 |
1501 std::cerr << "updateNoteValueFromPitchCurve: corrected from " << note.value << " to median " << median << std::endl; | 1502 std::cerr << "updateNoteValueFromPitchCurve: corrected from " << note.value << " to median " << median << std::endl; |
1502 | 1503 |
1503 note.value = median; | 1504 note.value = float(median); |
1504 | 1505 |
1505 return true; | 1506 return true; |
1506 } | 1507 } |
1507 | 1508 |
1508 void | 1509 void |
1614 delete dialog; | 1615 delete dialog; |
1615 return true; | 1616 return true; |
1616 } | 1617 } |
1617 | 1618 |
1618 void | 1619 void |
1619 FlexiNoteLayer::moveSelection(Selection s, int newStartFrame) | 1620 FlexiNoteLayer::moveSelection(Selection s, sv_frame_t newStartFrame) |
1620 { | 1621 { |
1621 if (!m_model) return; | 1622 if (!m_model) return; |
1622 | 1623 |
1623 FlexiNoteModel::EditCommand *command = | 1624 FlexiNoteModel::EditCommand *command = |
1624 new FlexiNoteModel::EditCommand(m_model, tr("Drag Selection")); | 1625 new FlexiNoteModel::EditCommand(m_model, tr("Drag Selection")); |
1658 for (FlexiNoteModel::PointList::iterator i = points.begin(); | 1659 for (FlexiNoteModel::PointList::iterator i = points.begin(); |
1659 i != points.end(); ++i) { | 1660 i != points.end(); ++i) { |
1660 | 1661 |
1661 if (s.contains(i->frame)) { | 1662 if (s.contains(i->frame)) { |
1662 | 1663 |
1663 double targetStart = i->frame; | 1664 double targetStart = double(i->frame); |
1664 targetStart = newSize.getStartFrame() + | 1665 targetStart = double(newSize.getStartFrame()) + |
1665 double(targetStart - s.getStartFrame()) * ratio; | 1666 targetStart - double(s.getStartFrame()) * ratio; |
1666 | 1667 |
1667 double targetEnd = i->frame + i->duration; | 1668 double targetEnd = double(i->frame + i->duration); |
1668 targetEnd = newSize.getStartFrame() + | 1669 targetEnd = double(newSize.getStartFrame()) + |
1669 double(targetEnd - s.getStartFrame()) * ratio; | 1670 targetEnd - double(s.getStartFrame()) * ratio; |
1670 | 1671 |
1671 FlexiNoteModel::Point newPoint(*i); | 1672 FlexiNoteModel::Point newPoint(*i); |
1672 newPoint.frame = lrint(targetStart); | 1673 newPoint.frame = lrint(targetStart); |
1673 newPoint.duration = lrint(targetEnd - targetStart); | 1674 newPoint.duration = lrint(targetEnd - targetStart); |
1674 command->deletePoint(*i); | 1675 command->deletePoint(*i); |
1743 } | 1744 } |
1744 } | 1745 } |
1745 } | 1746 } |
1746 | 1747 |
1747 bool | 1748 bool |
1748 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 */) |
1749 { | 1750 { |
1750 if (!m_model) return false; | 1751 if (!m_model) return false; |
1751 | 1752 |
1752 const Clipboard::PointList &points = from.getPoints(); | 1753 const Clipboard::PointList &points = from.getPoints(); |
1753 | 1754 |
1775 | 1776 |
1776 for (Clipboard::PointList::const_iterator i = points.begin(); | 1777 for (Clipboard::PointList::const_iterator i = points.begin(); |
1777 i != points.end(); ++i) { | 1778 i != points.end(); ++i) { |
1778 | 1779 |
1779 if (!i->haveFrame()) continue; | 1780 if (!i->haveFrame()) continue; |
1780 int frame = 0; | 1781 sv_frame_t frame = 0; |
1781 | 1782 |
1782 if (!realign) { | 1783 if (!realign) { |
1783 | 1784 |
1784 frame = i->getFrame(); | 1785 frame = i->getFrame(); |
1785 | 1786 |
1800 else newPoint.value = (m_model->getValueMinimum() + | 1801 else newPoint.value = (m_model->getValueMinimum() + |
1801 m_model->getValueMaximum()) / 2; | 1802 m_model->getValueMaximum()) / 2; |
1802 if (i->haveLevel()) newPoint.level = i->getLevel(); | 1803 if (i->haveLevel()) newPoint.level = i->getLevel(); |
1803 if (i->haveDuration()) newPoint.duration = i->getDuration(); | 1804 if (i->haveDuration()) newPoint.duration = i->getDuration(); |
1804 else { | 1805 else { |
1805 int nextFrame = frame; | 1806 sv_frame_t nextFrame = frame; |
1806 Clipboard::PointList::const_iterator j = i; | 1807 Clipboard::PointList::const_iterator j = i; |
1807 for (; j != points.end(); ++j) { | 1808 for (; j != points.end(); ++j) { |
1808 if (!j->haveFrame()) continue; | 1809 if (!j->haveFrame()) continue; |
1809 if (j != i) break; | 1810 if (j != i) break; |
1810 } | 1811 } |
1824 finish(command); | 1825 finish(command); |
1825 return true; | 1826 return true; |
1826 } | 1827 } |
1827 | 1828 |
1828 void | 1829 void |
1829 FlexiNoteLayer::addNoteOn(int frame, int pitch, int velocity) | 1830 FlexiNoteLayer::addNoteOn(sv_frame_t frame, int pitch, int velocity) |
1830 { | 1831 { |
1831 m_pendingNoteOns.insert(FlexiNote(frame, pitch, 0, float(velocity) / 127.0, "")); | 1832 m_pendingNoteOns.insert(FlexiNote(frame, float(pitch), 0, float(velocity / 127.0), "")); |
1832 } | 1833 } |
1833 | 1834 |
1834 void | 1835 void |
1835 FlexiNoteLayer::addNoteOff(int frame, int pitch) | 1836 FlexiNoteLayer::addNoteOff(sv_frame_t frame, int pitch) |
1836 { | 1837 { |
1837 for (FlexiNoteSet::iterator i = m_pendingNoteOns.begin(); | 1838 for (FlexiNoteSet::iterator i = m_pendingNoteOns.begin(); |
1838 i != m_pendingNoteOns.end(); ++i) { | 1839 i != m_pendingNoteOns.end(); ++i) { |
1839 if (lrintf((*i).value) == pitch) { | 1840 if (lrint((*i).value) == pitch) { |
1840 FlexiNote note(*i); | 1841 FlexiNote note(*i); |
1841 m_pendingNoteOns.erase(i); | 1842 m_pendingNoteOns.erase(i); |
1842 note.duration = frame - note.frame; | 1843 note.duration = frame - note.frame; |
1843 if (m_model) { | 1844 if (m_model) { |
1844 FlexiNoteModel::AddPointCommand *c = new FlexiNoteModel::AddPointCommand | 1845 FlexiNoteModel::AddPointCommand *c = new FlexiNoteModel::AddPointCommand |
1885 VerticalScale scale = (VerticalScale) | 1886 VerticalScale scale = (VerticalScale) |
1886 attributes.value("verticalScale").toInt(&ok); | 1887 attributes.value("verticalScale").toInt(&ok); |
1887 if (ok) setVerticalScale(scale); | 1888 if (ok) setVerticalScale(scale); |
1888 | 1889 |
1889 // bool alsoOk; | 1890 // bool alsoOk; |
1890 // float min = attributes.value("scaleMinimum").toFloat(&ok); | 1891 // double min = attributes.value("scaleMinimum").toDouble(&ok); |
1891 // float max = attributes.value("scaleMaximum").toFloat(&alsoOk); | 1892 // double max = attributes.value("scaleMaximum").toDouble(&alsoOk); |
1892 // if (ok && alsoOk && min != max) setDisplayExtents(min, max); | 1893 // if (ok && alsoOk && min != max) setDisplayExtents(min, max); |
1893 } | 1894 } |
1894 | 1895 |
1895 void | 1896 void |
1896 FlexiNoteLayer::setVerticalRangeToNoteRange(View *v) | 1897 FlexiNoteLayer::setVerticalRangeToNoteRange(View *v) |
1897 { | 1898 { |
1898 float minf = std::numeric_limits<float>::max(); | 1899 double minf = std::numeric_limits<double>::max(); |
1899 float maxf = 0; | 1900 double maxf = 0; |
1900 bool hasNotes = 0; | 1901 bool hasNotes = 0; |
1901 for (FlexiNoteModel::PointList::const_iterator i = m_model->getPoints().begin(); | 1902 for (FlexiNoteModel::PointList::const_iterator i = m_model->getPoints().begin(); |
1902 i != m_model->getPoints().end(); ++i) { | 1903 i != m_model->getPoints().end(); ++i) { |
1903 hasNotes = 1; | 1904 hasNotes = 1; |
1904 FlexiNote note = *i; | 1905 FlexiNote note = *i; |