Mercurial > hg > svcore
comparison data/model/ReadOnlyWaveFileModel.cpp @ 1557:d93e34684da7
Cautiously ensure we don't report readiness when the model is still updating; + some debug
| author | Chris Cannam |
|---|---|
| date | Thu, 18 Oct 2018 13:12:58 +0100 |
| parents | 710e6250a401 |
| children | 70e172e6cc59 |
comparison
equal
deleted
inserted
replaced
| 1556:7b4d56b01440 | 1557:d93e34684da7 |
|---|---|
| 46 m_myReader(true), | 46 m_myReader(true), |
| 47 m_startFrame(0), | 47 m_startFrame(0), |
| 48 m_fillThread(0), | 48 m_fillThread(0), |
| 49 m_updateTimer(0), | 49 m_updateTimer(0), |
| 50 m_lastFillExtent(0), | 50 m_lastFillExtent(0), |
| 51 m_prevCompletion(0), | |
| 51 m_exiting(false), | 52 m_exiting(false), |
| 52 m_lastDirectReadStart(0), | 53 m_lastDirectReadStart(0), |
| 53 m_lastDirectReadCount(0) | 54 m_lastDirectReadCount(0) |
| 54 { | 55 { |
| 56 SVDEBUG << "ReadOnlyWaveFileModel::ReadOnlyWaveFileModel: path " | |
| 57 << m_path << ", target rate " << targetRate << endl; | |
| 58 | |
| 55 m_source.waitForData(); | 59 m_source.waitForData(); |
| 56 | 60 |
| 57 if (m_source.isOK()) { | 61 if (m_source.isOK()) { |
| 58 | 62 |
| 59 Preferences *prefs = Preferences::getInstance(); | 63 Preferences *prefs = Preferences::getInstance(); |
| 75 if (m_reader) { | 79 if (m_reader) { |
| 76 SVDEBUG << "ReadOnlyWaveFileModel::ReadOnlyWaveFileModel: reader rate: " | 80 SVDEBUG << "ReadOnlyWaveFileModel::ReadOnlyWaveFileModel: reader rate: " |
| 77 << m_reader->getSampleRate() << endl; | 81 << m_reader->getSampleRate() << endl; |
| 78 } | 82 } |
| 79 } | 83 } |
| 80 | 84 |
| 81 if (m_reader) setObjectName(m_reader->getTitle()); | 85 if (m_reader) setObjectName(m_reader->getTitle()); |
| 82 if (objectName() == "") setObjectName(QFileInfo(m_path).fileName()); | 86 if (objectName() == "") setObjectName(QFileInfo(m_path).fileName()); |
| 83 if (isOK()) fillCache(); | 87 if (isOK()) fillCache(); |
| 84 } | 88 } |
| 85 | 89 |
| 90 m_myReader(false), | 94 m_myReader(false), |
| 91 m_startFrame(0), | 95 m_startFrame(0), |
| 92 m_fillThread(0), | 96 m_fillThread(0), |
| 93 m_updateTimer(0), | 97 m_updateTimer(0), |
| 94 m_lastFillExtent(0), | 98 m_lastFillExtent(0), |
| 99 m_prevCompletion(0), | |
| 95 m_exiting(false) | 100 m_exiting(false) |
| 96 { | 101 { |
| 102 SVDEBUG << "ReadOnlyWaveFileModel::ReadOnlyWaveFileModel: path " | |
| 103 << m_path << ", with reader" << endl; | |
| 104 | |
| 97 m_reader = reader; | 105 m_reader = reader; |
| 98 if (m_reader) setObjectName(m_reader->getTitle()); | 106 if (m_reader) setObjectName(m_reader->getTitle()); |
| 99 if (objectName() == "") setObjectName(QFileInfo(m_path).fileName()); | 107 if (objectName() == "") setObjectName(QFileInfo(m_path).fileName()); |
| 100 fillCache(); | 108 fillCache(); |
| 101 } | 109 } |
| 119 } | 127 } |
| 120 | 128 |
| 121 bool | 129 bool |
| 122 ReadOnlyWaveFileModel::isReady(int *completion) const | 130 ReadOnlyWaveFileModel::isReady(int *completion) const |
| 123 { | 131 { |
| 124 bool ready = (isOK() && (m_fillThread == 0)); | 132 bool ready = true; |
| 125 double c = double(m_lastFillExtent) / double(getEndFrame() - getStartFrame()); | 133 if (!isOK()) ready = false; |
| 126 static int prevCompletion = 0; | 134 if (m_fillThread) ready = false; |
| 135 if (m_reader && m_reader->isUpdating()) ready = false; | |
| 136 | |
| 137 double c = double(m_lastFillExtent) / | |
| 138 double(getEndFrame() - getStartFrame()); | |
| 139 | |
| 127 if (completion) { | 140 if (completion) { |
| 128 *completion = int(c * 100.0 + 0.01); | 141 *completion = int(c * 100.0 + 0.01); |
| 129 if (m_reader) { | 142 if (m_reader) { |
| 130 int decodeCompletion = m_reader->getDecodeCompletion(); | 143 int decodeCompletion = m_reader->getDecodeCompletion(); |
| 131 if (decodeCompletion < 90) *completion = decodeCompletion; | 144 if (decodeCompletion < 90) *completion = decodeCompletion; |
| 132 else *completion = min(*completion, decodeCompletion); | 145 else *completion = min(*completion, decodeCompletion); |
| 133 } | 146 } |
| 134 if (*completion != 0 && | 147 if (*completion != 0 && |
| 135 *completion != 100 && | 148 *completion != 100 && |
| 136 prevCompletion != 0 && | 149 m_prevCompletion != 0 && |
| 137 prevCompletion > *completion) { | 150 m_prevCompletion > *completion) { |
| 138 // just to avoid completion going backwards | 151 // just to avoid completion going backwards |
| 139 *completion = prevCompletion; | 152 *completion = m_prevCompletion; |
| 140 } | 153 } |
| 141 prevCompletion = *completion; | 154 m_prevCompletion = *completion; |
| 142 } | 155 } |
| 143 #ifdef DEBUG_WAVE_FILE_MODEL | 156 |
| 144 SVDEBUG << "ReadOnlyWaveFileModel::isReady(): ready = " << ready << ", completion = " << (completion ? *completion : -1) << endl; | 157 #ifdef DEBUG_WAVE_FILE_MODEL |
| 158 if (completion) { | |
| 159 SVDEBUG << "ReadOnlyWaveFileModel(" << objectName() << ")::isReady(): ready = " << ready << ", m_fillThread = " << m_fillThread << ", m_lastFillExtent = " << m_lastFillExtent << ", end frame = " << getEndFrame() << ", start frame = " << getStartFrame() << ", c = " << c << ", completion = " << *completion << endl; | |
| 160 } else { | |
| 161 SVDEBUG << "ReadOnlyWaveFileModel(" << objectName() << ")::isReady(): ready = " << ready << ", m_fillThread = " << m_fillThread << ", m_lastFillExtent = " << m_lastFillExtent << ", end frame = " << getEndFrame() << ", start frame = " << getStartFrame() << ", c = " << c << ", completion not requested" << endl; | |
| 162 } | |
| 145 #endif | 163 #endif |
| 146 return ready; | 164 return ready; |
| 147 } | 165 } |
| 148 | 166 |
| 149 sv_frame_t | 167 sv_frame_t |
| 548 | 566 |
| 549 m_mutex.unlock(); | 567 m_mutex.unlock(); |
| 550 m_fillThread->start(); | 568 m_fillThread->start(); |
| 551 | 569 |
| 552 #ifdef DEBUG_WAVE_FILE_MODEL | 570 #ifdef DEBUG_WAVE_FILE_MODEL |
| 553 SVDEBUG << "ReadOnlyWaveFileModel::fillCache: started fill thread" << endl; | 571 SVDEBUG << "ReadOnlyWaveFileModel(" << objectName() << ")::fillCache: started fill thread" << endl; |
| 554 #endif | 572 #endif |
| 555 } | 573 } |
| 556 | 574 |
| 557 void | 575 void |
| 558 ReadOnlyWaveFileModel::fillTimerTimedOut() | 576 ReadOnlyWaveFileModel::fillTimerTimedOut() |
| 559 { | 577 { |
| 560 if (m_fillThread) { | 578 if (m_fillThread) { |
| 561 sv_frame_t fillExtent = m_fillThread->getFillExtent(); | 579 sv_frame_t fillExtent = m_fillThread->getFillExtent(); |
| 562 #ifdef DEBUG_WAVE_FILE_MODEL | 580 #ifdef DEBUG_WAVE_FILE_MODEL |
| 563 SVDEBUG << "ReadOnlyWaveFileModel::fillTimerTimedOut: extent = " << fillExtent << endl; | 581 SVDEBUG << "ReadOnlyWaveFileModel(" << objectName() << ")::fillTimerTimedOut: extent = " << fillExtent << endl; |
| 564 #endif | 582 #endif |
| 565 if (fillExtent > m_lastFillExtent) { | 583 if (fillExtent > m_lastFillExtent) { |
| 566 emit modelChangedWithin(m_lastFillExtent, fillExtent); | 584 emit modelChangedWithin(m_lastFillExtent, fillExtent); |
| 567 m_lastFillExtent = fillExtent; | 585 m_lastFillExtent = fillExtent; |
| 568 } | 586 } |
| 569 } else { | 587 } else { |
| 570 #ifdef DEBUG_WAVE_FILE_MODEL | 588 #ifdef DEBUG_WAVE_FILE_MODEL |
| 571 SVDEBUG << "ReadOnlyWaveFileModel::fillTimerTimedOut: no thread" << endl; | 589 SVDEBUG << "ReadOnlyWaveFileModel(" << objectName() << ")::fillTimerTimedOut: no thread" << endl; |
| 572 #endif | 590 #endif |
| 573 emit modelChanged(); | 591 emit modelChanged(); |
| 574 } | 592 } |
| 575 } | 593 } |
| 576 | 594 |
| 580 m_mutex.lock(); | 598 m_mutex.lock(); |
| 581 delete m_fillThread; | 599 delete m_fillThread; |
| 582 m_fillThread = 0; | 600 m_fillThread = 0; |
| 583 delete m_updateTimer; | 601 delete m_updateTimer; |
| 584 m_updateTimer = 0; | 602 m_updateTimer = 0; |
| 603 auto prevFillExtent = m_lastFillExtent; | |
| 604 m_lastFillExtent = getEndFrame(); | |
| 585 m_mutex.unlock(); | 605 m_mutex.unlock(); |
| 586 if (getEndFrame() > m_lastFillExtent) { | 606 #ifdef DEBUG_WAVE_FILE_MODEL |
| 587 emit modelChangedWithin(m_lastFillExtent, getEndFrame()); | 607 SVDEBUG << "ReadOnlyWaveFileModel(" << objectName() << ")::cacheFilled, about to emit things" << endl; |
| 608 #endif | |
| 609 if (getEndFrame() > prevFillExtent) { | |
| 610 emit modelChangedWithin(prevFillExtent, getEndFrame()); | |
| 588 } | 611 } |
| 589 emit modelChanged(); | 612 emit modelChanged(); |
| 590 emit ready(); | 613 emit ready(); |
| 591 #ifdef DEBUG_WAVE_FILE_MODEL | |
| 592 SVDEBUG << "ReadOnlyWaveFileModel::cacheFilled" << endl; | |
| 593 #endif | |
| 594 } | 614 } |
| 595 | 615 |
| 596 void | 616 void |
| 597 ReadOnlyWaveFileModel::RangeCacheFillThread::run() | 617 ReadOnlyWaveFileModel::RangeCacheFillThread::run() |
| 598 { | 618 { |
| 611 bool updating = m_model.m_reader->isUpdating(); | 631 bool updating = m_model.m_reader->isUpdating(); |
| 612 | 632 |
| 613 if (updating) { | 633 if (updating) { |
| 614 while (channels == 0 && !m_model.m_exiting) { | 634 while (channels == 0 && !m_model.m_exiting) { |
| 615 #ifdef DEBUG_WAVE_FILE_MODEL | 635 #ifdef DEBUG_WAVE_FILE_MODEL |
| 616 cerr << "ReadOnlyWaveFileModel::fill: Waiting for channels..." << endl; | 636 cerr << "ReadOnlyWaveFileModel(" << objectName() << ")::fill: Waiting for channels..." << endl; |
| 617 #endif | 637 #endif |
| 618 sleep(1); | 638 sleep(1); |
| 619 channels = m_model.getChannelCount(); | 639 channels = m_model.getChannelCount(); |
| 620 } | 640 } |
| 621 } | 641 } |
| 640 while (frame < m_frameCount) { | 660 while (frame < m_frameCount) { |
| 641 | 661 |
| 642 m_model.m_mutex.unlock(); | 662 m_model.m_mutex.unlock(); |
| 643 | 663 |
| 644 #ifdef DEBUG_WAVE_FILE_MODEL | 664 #ifdef DEBUG_WAVE_FILE_MODEL |
| 645 cerr << "ReadOnlyWaveFileModel::fill inner loop: frame = " << frame << ", count = " << m_frameCount << ", blocksize " << readBlockSize << endl; | 665 SVDEBUG << "ReadOnlyWaveFileModel(" << m_model.objectName() << ")::fill inner loop: frame = " << frame << ", count = " << m_frameCount << ", blocksize " << readBlockSize << endl; |
| 646 #endif | 666 #endif |
| 647 | 667 |
| 648 if (updating && (frame + readBlockSize > m_frameCount)) { | 668 if (updating && (frame + readBlockSize > m_frameCount)) { |
| 649 m_model.m_mutex.lock(); // must be locked on exiting loop | 669 m_model.m_mutex.lock(); // must be locked on exiting loop |
| 650 break; | 670 break; |
| 733 | 753 |
| 734 m_fillExtent = m_frameCount; | 754 m_fillExtent = m_frameCount; |
| 735 | 755 |
| 736 #ifdef DEBUG_WAVE_FILE_MODEL | 756 #ifdef DEBUG_WAVE_FILE_MODEL |
| 737 for (int cacheType = 0; cacheType < 2; ++cacheType) { | 757 for (int cacheType = 0; cacheType < 2; ++cacheType) { |
| 738 cerr << "Cache type " << cacheType << " now contains " << m_model.m_cache[cacheType].size() << " ranges" << endl; | 758 SVDEBUG << "ReadOnlyWaveFileModel(" << m_model.objectName() << "): Cache type " << cacheType << " now contains " << m_model.m_cache[cacheType].size() << " ranges" << endl; |
| 739 } | 759 } |
| 740 #endif | 760 #endif |
| 741 } | 761 } |
| 742 | 762 |
| 743 void | 763 void |
