comparison data/model/ReadOnlyWaveFileModel.cpp @ 1527:710e6250a401 zoom

Merge from default branch
author Chris Cannam
date Mon, 17 Sep 2018 13:51:14 +0100
parents d4a28d1479a8 0925b37a3ed1
children 1ae6a19464a7 d93e34684da7
comparison
equal deleted inserted replaced
1324:d4a28d1479a8 1527:710e6250a401
104 { 104 {
105 m_exiting = true; 105 m_exiting = true;
106 if (m_fillThread) m_fillThread->wait(); 106 if (m_fillThread) m_fillThread->wait();
107 if (m_myReader) delete m_reader; 107 if (m_myReader) delete m_reader;
108 m_reader = 0; 108 m_reader = 0;
109
110 SVDEBUG << "ReadOnlyWaveFileModel: Destructor exiting; we had caches of "
111 << (m_cache[0].size() * sizeof(Range)) << " and "
112 << (m_cache[1].size() * sizeof(Range)) << " bytes" << endl;
109 } 113 }
110 114
111 bool 115 bool
112 ReadOnlyWaveFileModel::isOK() const 116 ReadOnlyWaveFileModel::isOK() const
113 { 117 {
200 { 204 {
201 if (m_reader) return m_reader->getLocalFilename(); 205 if (m_reader) return m_reader->getLocalFilename();
202 return ""; 206 return "";
203 } 207 }
204 208
205 vector<float> 209 floatvec_t
206 ReadOnlyWaveFileModel::getData(int channel, sv_frame_t start, sv_frame_t count) const 210 ReadOnlyWaveFileModel::getData(int channel,
207 { 211 sv_frame_t start,
208 // Read directly from the file. This is used for e.g. audio 212 sv_frame_t count)
209 // playback or input to transforms. 213 const
210 214 {
215 // Read a single channel (if channel >= 0) or a mixdown of all
216 // channels (if channel == -1) directly from the file. This is
217 // used for e.g. audio playback or input to transforms.
218
219 Profiler profiler("ReadOnlyWaveFileModel::getData");
220
211 #ifdef DEBUG_WAVE_FILE_MODEL 221 #ifdef DEBUG_WAVE_FILE_MODEL
212 cout << "ReadOnlyWaveFileModel::getData[" << this << "]: " << channel << ", " << start << ", " << count << endl; 222 cout << "ReadOnlyWaveFileModel::getData[" << this << "]: " << channel << ", " << start << ", " << count << endl;
213 #endif 223 #endif
214 224
215 int channels = getChannelCount(); 225 int channels = getChannelCount();
216 226
217 if (channel >= channels) { 227 if (channel >= channels) {
218 cerr << "ERROR: WaveFileModel::getData: channel (" 228 SVCERR << "ERROR: WaveFileModel::getData: channel ("
219 << channel << ") >= channel count (" << channels << ")" 229 << channel << ") >= channel count (" << channels << ")"
220 << endl; 230 << endl;
221 return {}; 231 return {};
222 } 232 }
223 233
234 count -= (m_startFrame - start); 244 count -= (m_startFrame - start);
235 start = 0; 245 start = 0;
236 } 246 }
237 } 247 }
238 248
239 vector<float> interleaved = m_reader->getInterleavedFrames(start, count); 249 floatvec_t interleaved = m_reader->getInterleavedFrames(start, count);
240 if (channels == 1) return interleaved; 250 if (channels == 1) return interleaved;
241 251
242 sv_frame_t obtained = interleaved.size() / channels; 252 sv_frame_t obtained = interleaved.size() / channels;
243 253
244 vector<float> result(obtained, 0.f); 254 floatvec_t result(obtained, 0.f);
245 255
246 if (channel != -1) { 256 if (channel != -1) {
247 // get a single channel 257 // get a single channel
248 for (int i = 0; i < obtained; ++i) { 258 for (int i = 0; i < obtained; ++i) {
249 result[i] = interleaved[i * channels + channel]; 259 result[i] = interleaved[i * channels + channel];
258 } 268 }
259 269
260 return result; 270 return result;
261 } 271 }
262 272
263 vector<vector<float>> 273 vector<floatvec_t>
264 ReadOnlyWaveFileModel::getMultiChannelData(int fromchannel, int tochannel, 274 ReadOnlyWaveFileModel::getMultiChannelData(int fromchannel, int tochannel,
265 sv_frame_t start, sv_frame_t count) const 275 sv_frame_t start, sv_frame_t count) const
266 { 276 {
267 // Read directly from the file. This is used for e.g. audio 277 // Read a set of channels directly from the file. This is used
268 // playback or input to transforms. 278 // for e.g. audio playback or input to transforms.
279
280 Profiler profiler("ReadOnlyWaveFileModel::getMultiChannelData");
269 281
270 #ifdef DEBUG_WAVE_FILE_MODEL 282 #ifdef DEBUG_WAVE_FILE_MODEL
271 cout << "ReadOnlyWaveFileModel::getData[" << this << "]: " << fromchannel << "," << tochannel << ", " << start << ", " << count << endl; 283 cout << "ReadOnlyWaveFileModel::getData[" << this << "]: " << fromchannel << "," << tochannel << ", " << start << ", " << count << endl;
272 #endif 284 #endif
273 285
274 int channels = getChannelCount(); 286 int channels = getChannelCount();
275 287
276 if (fromchannel > tochannel) { 288 if (fromchannel > tochannel) {
277 cerr << "ERROR: ReadOnlyWaveFileModel::getData: fromchannel (" 289 SVCERR << "ERROR: ReadOnlyWaveFileModel::getMultiChannelData: "
278 << fromchannel << ") > tochannel (" << tochannel << ")" 290 << "fromchannel (" << fromchannel
279 << endl; 291 << ") > tochannel (" << tochannel << ")"
292 << endl;
280 return {}; 293 return {};
281 } 294 }
282 295
283 if (tochannel >= channels) { 296 if (tochannel >= channels) {
284 cerr << "ERROR: ReadOnlyWaveFileModel::getData: tochannel (" 297 SVCERR << "ERROR: ReadOnlyWaveFileModel::getMultiChannelData: "
285 << tochannel << ") >= channel count (" << channels << ")" 298 << "tochannel (" << tochannel
286 << endl; 299 << ") >= channel count (" << channels << ")"
300 << endl;
287 return {}; 301 return {};
288 } 302 }
289 303
290 if (!m_reader || !m_reader->isOK() || count == 0) { 304 if (!m_reader || !m_reader->isOK() || count == 0) {
291 return {}; 305 return {};
302 count -= (m_startFrame - start); 316 count -= (m_startFrame - start);
303 start = 0; 317 start = 0;
304 } 318 }
305 } 319 }
306 320
307 vector<float> interleaved = m_reader->getInterleavedFrames(start, count); 321 floatvec_t interleaved = m_reader->getInterleavedFrames(start, count);
308 if (channels == 1) return { interleaved }; 322 if (channels == 1) return { interleaved };
309 323
310 sv_frame_t obtained = interleaved.size() / channels; 324 sv_frame_t obtained = interleaved.size() / channels;
311 vector<vector<float>> result(reqchannels, vector<float>(obtained, 0.f)); 325 vector<floatvec_t> result(reqchannels, floatvec_t(obtained, 0.f));
312 326
313 for (int c = fromchannel; c <= tochannel; ++c) { 327 for (int c = fromchannel; c <= tochannel; ++c) {
314 int destc = c - fromchannel; 328 int destc = c - fromchannel;
315 for (int i = 0; i < obtained; ++i) { 329 for (int i = 0; i < obtained; ++i) {
316 result[destc][i] = interleaved[i * channels + c]; 330 result[destc][i] = interleaved[i * channels + c];
359 373
360 int channels = getChannelCount(); 374 int channels = getChannelCount();
361 375
362 if (cacheType != 0 && cacheType != 1) { 376 if (cacheType != 0 && cacheType != 1) {
363 377
364 // We need to read directly from the file. We haven't got 378 // We need to read directly from the file. We haven't got
365 // this cached. Hope the requested area is small. This is 379 // this cached. Hope the requested area is small. This is
366 // not optimal -- we'll end up reading the same frames twice 380 // not optimal -- we'll end up reading the same frames twice
367 // for stereo files, in two separate calls to this method. 381 // for stereo files, in two separate calls to this method.
368 // We could fairly trivially handle this for most cases that 382 // We could fairly trivially handle this for most cases that
369 // matter by putting a single cache in getInterleavedFrames 383 // matter by putting a single cache in getInterleavedFrames
370 // for short queries. 384 // for short queries.
371 385
372 m_directReadMutex.lock(); 386 m_directReadMutex.lock();
373 387
374 if (m_lastDirectReadStart != start || 388 if (m_lastDirectReadStart != start ||
375 m_lastDirectReadCount != count || 389 m_lastDirectReadCount != count ||
378 m_directRead = m_reader->getInterleavedFrames(start, count); 392 m_directRead = m_reader->getInterleavedFrames(start, count);
379 m_lastDirectReadStart = start; 393 m_lastDirectReadStart = start;
380 m_lastDirectReadCount = count; 394 m_lastDirectReadCount = count;
381 } 395 }
382 396
383 float max = 0.0, min = 0.0, total = 0.0; 397 float max = 0.0, min = 0.0, total = 0.0;
384 sv_frame_t i = 0, got = 0; 398 sv_frame_t i = 0, got = 0;
385 399
386 while (i < count) { 400 while (i < count) {
387 401
388 sv_frame_t index = i * channels + channel; 402 sv_frame_t index = i * channels + channel;
389 if (index >= (sv_frame_t)m_directRead.size()) break; 403 if (index >= (sv_frame_t)m_directRead.size()) break;
390 404
391 float sample = m_directRead[index]; 405 float sample = m_directRead[index];
392 if (sample > max || got == 0) max = sample; 406 if (sample > max || got == 0) max = sample;
393 if (sample < min || got == 0) min = sample; 407 if (sample < min || got == 0) min = sample;
394 total += fabsf(sample); 408 total += fabsf(sample);
395 409
396 ++i; 410 ++i;
397 ++got; 411 ++got;
398 412
399 if (got == blockSize) { 413 if (got == blockSize) {
400 ranges.push_back(Range(min, max, total / float(got))); 414 ranges.push_back(Range(min, max, total / float(got)));
401 min = max = total = 0.0f; 415 min = max = total = 0.0f;
402 got = 0; 416 got = 0;
403 } 417 }
404 } 418 }
405 419
406 m_directReadMutex.unlock(); 420 m_directReadMutex.unlock();
407 421
408 if (got > 0) { 422 if (got > 0) {
409 ranges.push_back(Range(min, max, total / float(got))); 423 ranges.push_back(Range(min, max, total / float(got)));
410 } 424 }
411 425
412 return; 426 return;
413 427
414 } else { 428 } else {
415 429
416 QMutexLocker locker(&m_mutex); 430 QMutexLocker locker(&m_mutex);
417 431
418 const RangeBlock &cache = m_cache[cacheType]; 432 const RangeBlock &cache = m_cache[cacheType];
419 433
420 blockSize = roundedBlockSize; 434 blockSize = roundedBlockSize;
421 435
422 sv_frame_t cacheBlock, div; 436 sv_frame_t cacheBlock, div;
423 437
424 cacheBlock = (sv_frame_t(1) << m_zoomConstraint.getMinCachePower()); 438 cacheBlock = (sv_frame_t(1) << m_zoomConstraint.getMinCachePower());
425 if (cacheType == 1) { 439 if (cacheType == 1) {
426 cacheBlock = sv_frame_t(double(cacheBlock) * sqrt(2.) + 0.01); 440 cacheBlock = sv_frame_t(double(cacheBlock) * sqrt(2.) + 0.01);
427 } 441 }
428 div = blockSize / cacheBlock; 442 div = blockSize / cacheBlock;
429 443
430 sv_frame_t startIndex = start / cacheBlock; 444 sv_frame_t startIndex = start / cacheBlock;
431 sv_frame_t endIndex = (start + count) / cacheBlock; 445 sv_frame_t endIndex = (start + count) / cacheBlock;
432 446
433 float max = 0.0, min = 0.0, total = 0.0; 447 float max = 0.0, min = 0.0, total = 0.0;
434 sv_frame_t i = 0, got = 0; 448 sv_frame_t i = 0, got = 0;
435 449
436 #ifdef DEBUG_WAVE_FILE_MODEL 450 #ifdef DEBUG_WAVE_FILE_MODEL
437 cerr << "blockSize is " << blockSize << ", cacheBlock " << cacheBlock << ", start " << start << ", count " << count << " (frame count " << getFrameCount() << "), power is " << power << ", div is " << div << ", startIndex " << startIndex << ", endIndex " << endIndex << endl; 451 cerr << "blockSize is " << blockSize << ", cacheBlock " << cacheBlock << ", start " << start << ", count " << count << " (frame count " << getFrameCount() << "), power is " << power << ", div is " << div << ", startIndex " << startIndex << ", endIndex " << endIndex << endl;
438 #endif 452 #endif
439 453
440 for (i = 0; i <= endIndex - startIndex; ) { 454 for (i = 0; i <= endIndex - startIndex; ) {
441 455
442 sv_frame_t index = (i + startIndex) * channels + channel; 456 sv_frame_t index = (i + startIndex) * channels + channel;
443 if (!in_range_for(cache, index)) break; 457 if (!in_range_for(cache, index)) break;
444 458
445 const Range &range = cache[index]; 459 const Range &range = cache[index];
446 if (range.max() > max || got == 0) max = range.max(); 460 if (range.max() > max || got == 0) max = range.max();
447 if (range.min() < min || got == 0) min = range.min(); 461 if (range.min() < min || got == 0) min = range.min();
448 total += range.absmean(); 462 total += range.absmean();
449 463
450 ++i; 464 ++i;
451 ++got; 465 ++got;
452 466
453 if (got == div) { 467 if (got == div) {
454 ranges.push_back(Range(min, max, total / float(got))); 468 ranges.push_back(Range(min, max, total / float(got)));
455 min = max = total = 0.0f; 469 min = max = total = 0.0f;
456 got = 0; 470 got = 0;
457 } 471 }
458 } 472 }
459 473
460 if (got > 0) { 474 if (got > 0) {
461 ranges.push_back(Range(min, max, total / float(got))); 475 ranges.push_back(Range(min, max, total / float(got)));
462 } 476 }
463 } 477 }
464 478
465 #ifdef DEBUG_WAVE_FILE_MODEL 479 #ifdef DEBUG_WAVE_FILE_MODEL
466 cerr << "returning " << ranges.size() << " ranges" << endl; 480 cerr << "returning " << ranges.size() << " ranges" << endl;
467 #endif 481 #endif
542 556
543 void 557 void
544 ReadOnlyWaveFileModel::fillTimerTimedOut() 558 ReadOnlyWaveFileModel::fillTimerTimedOut()
545 { 559 {
546 if (m_fillThread) { 560 if (m_fillThread) {
547 sv_frame_t fillExtent = m_fillThread->getFillExtent(); 561 sv_frame_t fillExtent = m_fillThread->getFillExtent();
548 #ifdef DEBUG_WAVE_FILE_MODEL 562 #ifdef DEBUG_WAVE_FILE_MODEL
549 SVDEBUG << "ReadOnlyWaveFileModel::fillTimerTimedOut: extent = " << fillExtent << endl; 563 SVDEBUG << "ReadOnlyWaveFileModel::fillTimerTimedOut: extent = " << fillExtent << endl;
550 #endif 564 #endif
551 if (fillExtent > m_lastFillExtent) { 565 if (fillExtent > m_lastFillExtent) {
552 emit modelChangedWithin(m_lastFillExtent, fillExtent); 566 emit modelChangedWithin(m_lastFillExtent, fillExtent);
553 m_lastFillExtent = fillExtent; 567 m_lastFillExtent = fillExtent;
554 } 568 }
555 } else { 569 } else {
556 #ifdef DEBUG_WAVE_FILE_MODEL 570 #ifdef DEBUG_WAVE_FILE_MODEL
557 SVDEBUG << "ReadOnlyWaveFileModel::fillTimerTimedOut: no thread" << endl; 571 SVDEBUG << "ReadOnlyWaveFileModel::fillTimerTimedOut: no thread" << endl;
558 #endif 572 #endif
559 emit modelChanged(); 573 emit modelChanged();
560 } 574 }
561 } 575 }
562 576
563 void 577 void
564 ReadOnlyWaveFileModel::cacheFilled() 578 ReadOnlyWaveFileModel::cacheFilled()
587 cacheBlockSize[1] = (int((1 << m_model.m_zoomConstraint.getMinCachePower()) * 601 cacheBlockSize[1] = (int((1 << m_model.m_zoomConstraint.getMinCachePower()) *
588 sqrt(2.) + 0.01)); 602 sqrt(2.) + 0.01));
589 603
590 sv_frame_t frame = 0; 604 sv_frame_t frame = 0;
591 const sv_frame_t readBlockSize = 32768; 605 const sv_frame_t readBlockSize = 32768;
592 vector<float> block; 606 floatvec_t block;
593 607
594 if (!m_model.isOK()) return; 608 if (!m_model.isOK()) return;
595 609
596 int channels = m_model.getChannelCount(); 610 int channels = m_model.getChannelCount();
597 bool updating = m_model.m_reader->isUpdating(); 611 bool updating = m_model.m_reader->isUpdating();
641 sv_frame_t gotBlockSize = block.size() / channels; 655 sv_frame_t gotBlockSize = block.size() / channels;
642 656
643 m_model.m_mutex.lock(); 657 m_model.m_mutex.lock();
644 658
645 for (sv_frame_t i = 0; i < gotBlockSize; ++i) { 659 for (sv_frame_t i = 0; i < gotBlockSize; ++i) {
646 660
647 for (int ch = 0; ch < channels; ++ch) { 661 for (int ch = 0; ch < channels; ++ch) {
648 662
649 sv_frame_t index = channels * i + ch; 663 sv_frame_t index = channels * i + ch;
650 float sample = block[index]; 664 float sample = block[index];
651 665