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) {