comparison layer/WaveformLayer.cpp @ 302:e9549ea3f825

* Change WaveFileModel API from getValues(start,end) to getData(start,count). It's much less error-prone to pass in frame counts instead of start/end locations. Should have done this ages ago. This closes #1794563. * Add option to apply a transform to only the selection region, instead of the whole audio. * (to make the above work properly) Add start frame offset to wave models
author Chris Cannam
date Mon, 01 Oct 2007 13:48:38 +0000
parents 5636eeacc467
children c0b9eec70639
comparison
equal deleted inserted replaced
301:5636eeacc467 302:e9549ea3f825
402 if (!m_model || !m_model->isOK()) { 402 if (!m_model || !m_model->isOK()) {
403 return; 403 return;
404 } 404 }
405 405
406 long startFrame = v->getStartFrame(); 406 long startFrame = v->getStartFrame();
407 long endFrame = v->getEndFrame();
407 int zoomLevel = v->getZoomLevel(); 408 int zoomLevel = v->getZoomLevel();
408 409
409 #ifdef DEBUG_WAVEFORM_PAINT 410 #ifdef DEBUG_WAVEFORM_PAINT
410 Profiler profiler("WaveformLayer::paint", true); 411 Profiler profiler("WaveformLayer::paint", true);
411 std::cerr << "WaveformLayer::paint (" << rect.x() << "," << rect.y() 412 std::cerr << "WaveformLayer::paint (" << rect.x() << "," << rect.y()
477 if (x0 > 0) --x0; 478 if (x0 > 0) --x0;
478 if (x1 < v->width()) ++x1; 479 if (x1 < v->width()) ++x1;
479 480
480 long frame0 = v->getFrameForX(x0); 481 long frame0 = v->getFrameForX(x0);
481 long frame1 = v->getFrameForX(x1 + 1); 482 long frame1 = v->getFrameForX(x1 + 1);
482 483
483 #ifdef DEBUG_WAVEFORM_PAINT 484 #ifdef DEBUG_WAVEFORM_PAINT
484 std::cerr << "Painting waveform from " << frame0 << " to " << frame1 << " (" << (x1-x0+1) << " pixels at zoom " << zoomLevel << ")" << std::endl; 485 std::cerr << "Painting waveform from " << frame0 << " to " << frame1 << " (" << (x1-x0+1) << " pixels at zoom " << zoomLevel << ")" << std::endl;
485 #endif 486 #endif
486 487
487 RangeSummarisableTimeValueModel::RangeBlock *ranges = 488 RangeSummarisableTimeValueModel::RangeBlock *ranges =
504 505
505 while (m_effectiveGains.size() <= maxChannel) { 506 while (m_effectiveGains.size() <= maxChannel) {
506 m_effectiveGains.push_back(m_gain); 507 m_effectiveGains.push_back(m_gain);
507 } 508 }
508 509
510 // Although a long for purposes of comparison against the view
511 // start and end frames, these are known to be non-negative
512 long modelStart = long(m_model->getStartFrame());
513 long modelEnd = long(m_model->getEndFrame());
514
515 #ifdef DEBUG_WAVEFORM_PAINT
516 std::cerr << "Model start = " << modelStart << ", end = " << modelEnd << std::endl;
517 #endif
518
509 for (size_t ch = minChannel; ch <= maxChannel; ++ch) { 519 for (size_t ch = minChannel; ch <= maxChannel; ++ch) {
510 520
511 int prevRangeBottom = -1, prevRangeTop = -1; 521 int prevRangeBottom = -1, prevRangeTop = -1;
512 QColor prevRangeBottomColour = baseColour, prevRangeTopColour = baseColour; 522 QColor prevRangeBottomColour = baseColour, prevRangeTopColour = baseColour;
523 size_t rangeStart, rangeEnd;
513 524
514 m_effectiveGains[ch] = m_gain; 525 m_effectiveGains[ch] = m_gain;
515 526
516 if (m_autoNormalize) { 527 if (m_autoNormalize) {
528
529 if (startFrame < modelStart) rangeStart = modelStart;
530 else rangeStart = startFrame;
531
532 if (endFrame < 0) rangeEnd = 0;
533 else if (endFrame > modelEnd) rangeEnd = modelEnd;
534 else rangeEnd = endFrame;
535
536 if (rangeEnd < rangeStart) rangeEnd = rangeStart;
537
517 RangeSummarisableTimeValueModel::Range range = 538 RangeSummarisableTimeValueModel::Range range =
518 m_model->getRange(ch, startFrame < 0 ? 0 : startFrame, 539 m_model->getSummary(ch, rangeStart, rangeEnd - rangeStart);
519 v->getEndFrame());
520 if (mergingChannels || mixingChannels) { 540 if (mergingChannels || mixingChannels) {
521 RangeSummarisableTimeValueModel::Range otherRange = 541 RangeSummarisableTimeValueModel::Range otherRange =
522 m_model->getRange(1, startFrame < 0 ? 0 : startFrame, 542 m_model->getSummary(1, rangeStart, rangeEnd - rangeStart);
523 v->getEndFrame());
524 range.max = std::max(range.max, otherRange.max); 543 range.max = std::max(range.max, otherRange.max);
525 range.min = std::min(range.min, otherRange.min); 544 range.min = std::min(range.min, otherRange.min);
526 range.absmean = std::min(range.absmean, otherRange.absmean); 545 range.absmean = std::min(range.absmean, otherRange.absmean);
527 } 546 }
528 m_effectiveGains[ch] = 1.0 / std::max(fabsf(range.max), 547 m_effectiveGains[ch] = 1.0 / std::max(fabsf(range.max),
593 paint->drawLine(x0, ny, x1, ny); 612 paint->drawLine(x0, ny, x1, ny);
594 } 613 }
595 } 614 }
596 } 615 }
597 616
598 if (frame1 <= 0) continue; 617 if (frame1 < modelStart) continue;
599 618
600 size_t modelZoomLevel = zoomLevel; 619 size_t modelZoomLevel = zoomLevel;
601 620
602 m_model->getRanges 621 if (frame0 < modelStart) rangeStart = modelStart;
603 (ch, frame0 < 0 ? 0 : frame0, frame1, *ranges, modelZoomLevel); 622 else rangeStart = frame0;
623
624 if (frame1 < 0) rangeEnd = 0;
625 else if (frame1 > modelEnd) rangeEnd = modelEnd;
626 else rangeEnd = frame1;
627
628 if (rangeEnd < rangeStart) rangeEnd = rangeStart;
629
630 m_model->getSummaries
631 (ch, rangeStart, rangeEnd - rangeStart, *ranges, modelZoomLevel);
632
633 // std::cerr << ranges->size() << " ranges" << std::endl;
604 634
605 if (mergingChannels || mixingChannels) { 635 if (mergingChannels || mixingChannels) {
606 if (m_model->getChannelCount() > 1) { 636 if (m_model->getChannelCount() > 1) {
607 if (!otherChannelRanges) { 637 if (!otherChannelRanges) {
608 otherChannelRanges = 638 otherChannelRanges =
609 new RangeSummarisableTimeValueModel::RangeBlock; 639 new RangeSummarisableTimeValueModel::RangeBlock;
610 } 640 }
611 m_model->getRanges 641 m_model->getSummaries
612 (1, frame0 < 0 ? 0 : frame0, frame1, *otherChannelRanges, 642 (1, rangeStart, rangeEnd - rangeStart, *otherChannelRanges,
613 modelZoomLevel); 643 modelZoomLevel);
614 } else { 644 } else {
615 if (otherChannelRanges != ranges) delete otherChannelRanges; 645 if (otherChannelRanges != ranges) delete otherChannelRanges;
616 otherChannelRanges = ranges; 646 otherChannelRanges = ranges;
617 } 647 }
621 651
622 range = RangeSummarisableTimeValueModel::Range(); 652 range = RangeSummarisableTimeValueModel::Range();
623 size_t index = x - x0; 653 size_t index = x - x0;
624 size_t maxIndex = index; 654 size_t maxIndex = index;
625 655
626 if (frame0 < 0) { 656 if (frame0 < modelStart) {
627 if (index < size_t(-frame0 / zoomLevel)) { 657 if (index < size_t((modelStart - frame0) / zoomLevel)) {
628 continue; 658 continue;
629 } else { 659 } else {
630 index -= -frame0 / zoomLevel; 660 index -= ((modelStart - frame0) / zoomLevel);
631 maxIndex = index; 661 maxIndex = index;
632 } 662 }
633 } 663 }
634 664
635 if (int(modelZoomLevel) != zoomLevel) { 665 if (int(modelZoomLevel) != zoomLevel) {
636 666
637 index = size_t((double(index) * zoomLevel) / modelZoomLevel); 667 index = size_t((double(index) * zoomLevel) / modelZoomLevel);
638 668
889 919
890 for (size_t ch = minChannel; ch <= maxChannel; ++ch) { 920 for (size_t ch = minChannel; ch <= maxChannel; ++ch) {
891 921
892 size_t blockSize = v->getZoomLevel(); 922 size_t blockSize = v->getZoomLevel();
893 RangeSummarisableTimeValueModel::RangeBlock ranges; 923 RangeSummarisableTimeValueModel::RangeBlock ranges;
894 m_model->getRanges(ch, f0, f1, ranges, blockSize); 924 m_model->getSummaries(ch, f0, f1 - f0, ranges, blockSize);
895 925
896 if (ranges.empty()) continue; 926 if (ranges.empty()) continue;
897 927
898 RangeSummarisableTimeValueModel::Range range = ranges[0]; 928 RangeSummarisableTimeValueModel::Range range = ranges[0];
899 929