comparison data/model/WaveFileModel.cpp @ 377:166c22eff678

* Ensure waveforms are strictly correct even when using a non-power-of-two non-power-of-sqrt-two block size with cacheing off and painting only small areas at a time
author Chris Cannam
date Thu, 07 Feb 2008 15:25:05 +0000
parents 0e30c8ec15a0
children 183ee2a55fc7
comparison
equal deleted inserted replaced
376:ab24af1271e9 377:166c22eff678
377 } 377 }
378 378
379 return i; 379 return i;
380 } 380 }
381 381
382 size_t
383 WaveFileModel::getSummaryBlockSize(size_t desired) const
384 {
385 int cacheType = 0;
386 int power = m_zoomConstraint.getMinCachePower();
387 size_t roundedBlockSize = m_zoomConstraint.getNearestBlockSize
388 (desired, cacheType, power, ZoomConstraint::RoundDown);
389 if (cacheType != 0 && cacheType != 1) {
390 // We will be reading directly from file, so can satisfy any
391 // blocksize requirement
392 return desired;
393 } else {
394 return roundedBlockSize;
395 }
396 }
397
382 void 398 void
383 WaveFileModel::getSummaries(size_t channel, size_t start, size_t count, 399 WaveFileModel::getSummaries(size_t channel, size_t start, size_t count,
384 RangeBlock &ranges, size_t &blockSize) const 400 RangeBlock &ranges, size_t &blockSize) const
385 { 401 {
386 ranges.clear(); 402 ranges.clear();
387 if (!isOK()) return; 403 if (!isOK()) return;
404 ranges.reserve((count / blockSize) + 1);
388 405
389 if (start > m_startFrame) start -= m_startFrame; 406 if (start > m_startFrame) start -= m_startFrame;
390 else if (count <= m_startFrame - start) return; 407 else if (count <= m_startFrame - start) return;
391 else { 408 else {
392 count -= (m_startFrame - start); 409 count -= (m_startFrame - start);
393 start = 0; 410 start = 0;
394 } 411 }
395 412
396 int cacheType = 0; 413 int cacheType = 0;
397 int power = m_zoomConstraint.getMinCachePower(); 414 int power = m_zoomConstraint.getMinCachePower();
398 blockSize = m_zoomConstraint.getNearestBlockSize 415 size_t roundedBlockSize = m_zoomConstraint.getNearestBlockSize
399 (blockSize, cacheType, power, ZoomConstraint::RoundUp); 416 (blockSize, cacheType, power, ZoomConstraint::RoundDown);
400 417
401 size_t channels = getChannelCount(); 418 size_t channels = getChannelCount();
402 419
403 if (cacheType != 0 && cacheType != 1) { 420 if (cacheType != 0 && cacheType != 1) {
404 421
408 // for stereo files, in two separate calls to this method. 425 // for stereo files, in two separate calls to this method.
409 // We could fairly trivially handle this for most cases that 426 // We could fairly trivially handle this for most cases that
410 // matter by putting a single cache in getInterleavedFrames 427 // matter by putting a single cache in getInterleavedFrames
411 // for short queries. 428 // for short queries.
412 429
413 SampleBlock frames; 430 m_directReadMutex.lock();
414 m_reader->getInterleavedFrames(start, count, frames); 431
432 if (m_lastDirectReadStart != start ||
433 m_lastDirectReadCount != count ||
434 m_directRead.empty()) {
435
436 m_reader->getInterleavedFrames(start, count, m_directRead);
437 m_lastDirectReadStart = start;
438 m_lastDirectReadCount = count;
439 }
440
415 float max = 0.0, min = 0.0, total = 0.0; 441 float max = 0.0, min = 0.0, total = 0.0;
416 size_t i = 0, got = 0; 442 size_t i = 0, got = 0;
417 443
418 while (i < count) { 444 while (i < count) {
419 445
420 size_t index = i * channels + channel; 446 size_t index = i * channels + channel;
421 if (index >= frames.size()) break; 447 if (index >= m_directRead.size()) break;
422 448
423 float sample = frames[index]; 449 float sample = m_directRead[index];
424 if (sample > max || got == 0) max = sample; 450 if (sample > max || got == 0) max = sample;
425 if (sample < min || got == 0) min = sample; 451 if (sample < min || got == 0) min = sample;
426 total += fabsf(sample); 452 total += fabsf(sample);
427 453
428 ++i; 454 ++i;
433 min = max = total = 0.0f; 459 min = max = total = 0.0f;
434 got = 0; 460 got = 0;
435 } 461 }
436 } 462 }
437 463
464 m_directReadMutex.unlock();
465
438 if (got > 0) { 466 if (got > 0) {
439 ranges.push_back(Range(min, max, total / got)); 467 ranges.push_back(Range(min, max, total / got));
440 } 468 }
441 469
442 return; 470 return;
444 } else { 472 } else {
445 473
446 QMutexLocker locker(&m_mutex); 474 QMutexLocker locker(&m_mutex);
447 475
448 const RangeBlock &cache = m_cache[cacheType]; 476 const RangeBlock &cache = m_cache[cacheType];
477
478 blockSize = roundedBlockSize;
449 479
450 size_t cacheBlock, div; 480 size_t cacheBlock, div;
451 481
452 if (cacheType == 0) { 482 if (cacheType == 0) {
453 cacheBlock = (1 << m_zoomConstraint.getMinCachePower()); 483 cacheBlock = (1 << m_zoomConstraint.getMinCachePower());