Mercurial > hg > svcore
comparison data/model/ReadOnlyWaveFileModel.cpp @ 1151:def42cbba8bc 3.0-integration
Adjust locking when filling range cache in background thread, so as to spend less time waiting on locks
author | Chris Cannam |
---|---|
date | Fri, 22 Jan 2016 09:52:30 +0000 |
parents | efea94b04d5a |
children | d73b4bac2dc4 |
comparison
equal
deleted
inserted
replaced
1150:fc4cb3901316 | 1151:def42cbba8bc |
---|---|
191 { | 191 { |
192 // Read directly from the file. This is used for e.g. audio | 192 // Read directly from the file. This is used for e.g. audio |
193 // playback or input to transforms. | 193 // playback or input to transforms. |
194 | 194 |
195 #ifdef DEBUG_WAVE_FILE_MODEL | 195 #ifdef DEBUG_WAVE_FILE_MODEL |
196 cout << "ReadOnlyWaveFileModel::getData[" << this << "]: " << channel << ", " << start << ", " << count << ", " << buffer << endl; | 196 cout << "ReadOnlyWaveFileModel::getData[" << this << "]: " << channel << ", " << start << ", " << count << endl; |
197 #endif | 197 #endif |
198 | 198 |
199 int channels = getChannelCount(); | 199 int channels = getChannelCount(); |
200 | 200 |
201 if (channel >= channels) { | 201 if (channel >= channels) { |
250 { | 250 { |
251 // Read directly from the file. This is used for e.g. audio | 251 // Read directly from the file. This is used for e.g. audio |
252 // playback or input to transforms. | 252 // playback or input to transforms. |
253 | 253 |
254 #ifdef DEBUG_WAVE_FILE_MODEL | 254 #ifdef DEBUG_WAVE_FILE_MODEL |
255 cout << "ReadOnlyWaveFileModel::getData[" << this << "]: " << fromchannel << "," << tochannel << ", " << start << ", " << count << ", " << buffer << endl; | 255 cout << "ReadOnlyWaveFileModel::getData[" << this << "]: " << fromchannel << "," << tochannel << ", " << start << ", " << count << endl; |
256 #endif | 256 #endif |
257 | 257 |
258 int channels = getChannelCount(); | 258 int channels = getChannelCount(); |
259 | 259 |
260 if (fromchannel > tochannel) { | 260 if (fromchannel > tochannel) { |
320 } | 320 } |
321 } | 321 } |
322 | 322 |
323 void | 323 void |
324 ReadOnlyWaveFileModel::getSummaries(int channel, sv_frame_t start, sv_frame_t count, | 324 ReadOnlyWaveFileModel::getSummaries(int channel, sv_frame_t start, sv_frame_t count, |
325 RangeBlock &ranges, int &blockSize) const | 325 RangeBlock &ranges, int &blockSize) const |
326 { | 326 { |
327 ranges.clear(); | 327 ranges.clear(); |
328 if (!isOK()) return; | 328 if (!isOK()) return; |
329 ranges.reserve((count / blockSize) + 1); | 329 ranges.reserve((count / blockSize) + 1); |
330 | 330 |
446 ranges.push_back(Range(min, max, total / float(got))); | 446 ranges.push_back(Range(min, max, total / float(got))); |
447 } | 447 } |
448 } | 448 } |
449 | 449 |
450 #ifdef DEBUG_WAVE_FILE_MODEL | 450 #ifdef DEBUG_WAVE_FILE_MODEL |
451 SVDEBUG << "returning " << ranges.size() << " ranges" << endl; | 451 cerr << "returning " << ranges.size() << " ranges" << endl; |
452 #endif | 452 #endif |
453 return; | 453 return; |
454 } | 454 } |
455 | 455 |
456 ReadOnlyWaveFileModel::Range | 456 ReadOnlyWaveFileModel::Range |
571 cacheBlockSize[0] = (1 << m_model.m_zoomConstraint.getMinCachePower()); | 571 cacheBlockSize[0] = (1 << m_model.m_zoomConstraint.getMinCachePower()); |
572 cacheBlockSize[1] = (int((1 << m_model.m_zoomConstraint.getMinCachePower()) * | 572 cacheBlockSize[1] = (int((1 << m_model.m_zoomConstraint.getMinCachePower()) * |
573 sqrt(2.) + 0.01)); | 573 sqrt(2.) + 0.01)); |
574 | 574 |
575 sv_frame_t frame = 0; | 575 sv_frame_t frame = 0; |
576 const sv_frame_t readBlockSize = 16384; | 576 const sv_frame_t readBlockSize = 32768; |
577 vector<float> block; | 577 vector<float> block; |
578 | 578 |
579 if (!m_model.isOK()) return; | 579 if (!m_model.isOK()) return; |
580 | 580 |
581 int channels = m_model.getChannelCount(); | 581 int channels = m_model.getChannelCount(); |
582 bool updating = m_model.m_reader->isUpdating(); | 582 bool updating = m_model.m_reader->isUpdating(); |
583 | 583 |
584 if (updating) { | 584 if (updating) { |
585 while (channels == 0 && !m_model.m_exiting) { | 585 while (channels == 0 && !m_model.m_exiting) { |
586 // SVDEBUG << "ReadOnlyWaveFileModel::fill: Waiting for channels..." << endl; | 586 #ifdef DEBUG_WAVE_FILE_MODEL |
587 cerr << "ReadOnlyWaveFileModel::fill: Waiting for channels..." << endl; | |
588 #endif | |
587 sleep(1); | 589 sleep(1); |
588 channels = m_model.getChannelCount(); | 590 channels = m_model.getChannelCount(); |
589 } | 591 } |
590 } | 592 } |
591 | 593 |
602 while (first || updating) { | 604 while (first || updating) { |
603 | 605 |
604 updating = m_model.m_reader->isUpdating(); | 606 updating = m_model.m_reader->isUpdating(); |
605 m_frameCount = m_model.getFrameCount(); | 607 m_frameCount = m_model.getFrameCount(); |
606 | 608 |
607 // SVDEBUG << "ReadOnlyWaveFileModel::fill: frame = " << frame << ", count = " << m_frameCount << endl; | 609 m_model.m_mutex.lock(); |
608 | 610 |
609 while (frame < m_frameCount) { | 611 while (frame < m_frameCount) { |
610 | 612 |
611 // SVDEBUG << "ReadOnlyWaveFileModel::fill inner loop: frame = " << frame << ", count = " << m_frameCount << ", blocksize " << readBlockSize << endl; | 613 m_model.m_mutex.unlock(); |
614 | |
615 #ifdef DEBUG_WAVE_FILE_MODEL | |
616 cerr << "ReadOnlyWaveFileModel::fill inner loop: frame = " << frame << ", count = " << m_frameCount << ", blocksize " << readBlockSize << endl; | |
617 #endif | |
612 | 618 |
613 if (updating && (frame + readBlockSize > m_frameCount)) break; | 619 if (updating && (frame + readBlockSize > m_frameCount)) break; |
614 | 620 |
615 block = m_model.m_reader->getInterleavedFrames(frame, readBlockSize); | 621 block = m_model.m_reader->getInterleavedFrames(frame, readBlockSize); |
616 | 622 |
617 // cerr << "block is " << block.size() << endl; | 623 sv_frame_t gotBlockSize = block.size() / channels; |
618 | 624 |
619 for (sv_frame_t i = 0; i < readBlockSize; ++i) { | 625 m_model.m_mutex.lock(); |
626 | |
627 for (sv_frame_t i = 0; i < gotBlockSize; ++i) { | |
620 | 628 |
621 if (channels * i + channels > (int)block.size()) break; | |
622 | |
623 for (int ch = 0; ch < channels; ++ch) { | 629 for (int ch = 0; ch < channels; ++ch) { |
624 | 630 |
625 sv_frame_t index = channels * i + ch; | 631 sv_frame_t index = channels * i + ch; |
626 float sample = block[index]; | 632 float sample = block[index]; |
627 | 633 |
628 for (int cacheType = 0; cacheType < 2; ++cacheType) { // cache type | 634 for (int cacheType = 0; cacheType < 2; ++cacheType) { |
629 | |
630 sv_frame_t rangeIndex = ch * 2 + cacheType; | 635 sv_frame_t rangeIndex = ch * 2 + cacheType; |
631 range[rangeIndex].sample(sample); | 636 range[rangeIndex].sample(sample); |
632 means[rangeIndex] += fabsf(sample); | 637 means[rangeIndex] += fabsf(sample); |
633 } | 638 } |
634 } | 639 } |
635 | |
636 //!!! this looks like a ludicrous way to do synchronisation | |
637 QMutexLocker locker(&m_model.m_mutex); | |
638 | 640 |
639 for (int cacheType = 0; cacheType < 2; ++cacheType) { | 641 for (int cacheType = 0; cacheType < 2; ++cacheType) { |
640 | 642 |
641 if (++count[cacheType] == cacheBlockSize[cacheType]) { | 643 if (++count[cacheType] == cacheBlockSize[cacheType]) { |
642 | 644 |
653 } | 655 } |
654 } | 656 } |
655 | 657 |
656 ++frame; | 658 ++frame; |
657 } | 659 } |
660 | |
661 if (m_model.m_exiting) break; | |
662 m_fillExtent = frame; | |
663 } | |
664 | |
665 m_model.m_mutex.unlock(); | |
658 | 666 |
659 if (m_model.m_exiting) break; | |
660 | |
661 m_fillExtent = frame; | |
662 } | |
663 | |
664 // cerr << "ReadOnlyWaveFileModel: inner loop ended" << endl; | |
665 | |
666 first = false; | 667 first = false; |
667 if (m_model.m_exiting) break; | 668 if (m_model.m_exiting) break; |
668 if (updating) { | 669 if (updating) { |
669 // cerr << "sleeping..." << endl; | |
670 sleep(1); | 670 sleep(1); |
671 } | 671 } |
672 } | 672 } |
673 | 673 |
674 if (!m_model.m_exiting) { | 674 if (!m_model.m_exiting) { |