comparison data/fileio/CodedAudioFileReader.cpp @ 1126:39019ce29178 tony-2.0-integration

Merge through to branch for Tony 2.0
author Chris Cannam
date Thu, 20 Aug 2015 14:54:21 +0100
parents 457a1a619c5f
children 6877f4200912
comparison
equal deleted inserted replaced
1119:e22bfe8ca248 1126:39019ce29178
19 #include "base/TempDirectory.h" 19 #include "base/TempDirectory.h"
20 #include "base/Exceptions.h" 20 #include "base/Exceptions.h"
21 #include "base/Profiler.h" 21 #include "base/Profiler.h"
22 #include "base/Serialiser.h" 22 #include "base/Serialiser.h"
23 #include "base/Resampler.h" 23 #include "base/Resampler.h"
24 #include "base/StorageAdviser.h"
24 25
25 #include <stdint.h> 26 #include <stdint.h>
26 #include <iostream> 27 #include <iostream>
27 #include <QDir> 28 #include <QDir>
28 #include <QMutexLocker> 29 #include <QMutexLocker>
30
31 using namespace std;
29 32
30 CodedAudioFileReader::CodedAudioFileReader(CacheMode cacheMode, 33 CodedAudioFileReader::CodedAudioFileReader(CacheMode cacheMode,
31 sv_samplerate_t targetRate, 34 sv_samplerate_t targetRate,
32 bool normalised) : 35 bool normalised) :
33 m_cacheMode(cacheMode), 36 m_cacheMode(cacheMode),
55 CodedAudioFileReader::~CodedAudioFileReader() 58 CodedAudioFileReader::~CodedAudioFileReader()
56 { 59 {
57 QMutexLocker locker(&m_cacheMutex); 60 QMutexLocker locker(&m_cacheMutex);
58 61
59 endSerialised(); 62 endSerialised();
60 63
61 if (m_cacheFileWritePtr) sf_close(m_cacheFileWritePtr); 64 if (m_cacheFileWritePtr) sf_close(m_cacheFileWritePtr);
62 65
63 SVDEBUG << "CodedAudioFileReader::~CodedAudioFileReader: deleting cache file reader" << endl; 66 SVDEBUG << "CodedAudioFileReader::~CodedAudioFileReader: deleting cache file reader" << endl;
64 67
65 delete m_cacheFileReader; 68 delete m_cacheFileReader;
71 } 74 }
72 } 75 }
73 76
74 delete m_resampler; 77 delete m_resampler;
75 delete[] m_resampleBuffer; 78 delete[] m_resampleBuffer;
79
80 if (!m_data.empty()) {
81 StorageAdviser::notifyDoneAllocation
82 (StorageAdviser::MemoryAllocation,
83 (m_data.size() * sizeof(float)) / 1024);
84 }
76 } 85 }
77 86
78 void 87 void
79 CodedAudioFileReader::startSerialised(QString id) 88 CodedAudioFileReader::startSerialised(QString id)
80 { 89 {
240 } 249 }
241 } 250 }
242 } 251 }
243 252
244 void 253 void
245 CodedAudioFileReader::addSamplesToDecodeCache(const SampleBlock &samples) 254 CodedAudioFileReader::addSamplesToDecodeCache(const vector<float> &samples)
246 { 255 {
247 QMutexLocker locker(&m_cacheMutex); 256 QMutexLocker locker(&m_cacheMutex);
248 257
249 if (!m_initialised) return; 258 if (!m_initialised) return;
250 259
290 299
291 delete m_resampler; 300 delete m_resampler;
292 m_resampler = 0; 301 m_resampler = 0;
293 302
294 if (m_cacheMode == CacheInTemporaryFile) { 303 if (m_cacheMode == CacheInTemporaryFile) {
304
295 sf_close(m_cacheFileWritePtr); 305 sf_close(m_cacheFileWritePtr);
296 m_cacheFileWritePtr = 0; 306 m_cacheFileWritePtr = 0;
297 if (m_cacheFileReader) m_cacheFileReader->updateFrameCount(); 307 if (m_cacheFileReader) m_cacheFileReader->updateFrameCount();
308
309 } else {
310 // I know, I know, we already allocated it...
311 StorageAdviser::notifyPlannedAllocation
312 (StorageAdviser::MemoryAllocation,
313 (m_data.size() * sizeof(float)) / 1024);
298 } 314 }
299 } 315 }
300 316
301 void 317 void
302 CodedAudioFileReader::pushBuffer(float *buffer, sv_frame_t sz, bool final) 318 CodedAudioFileReader::pushBuffer(float *buffer, sv_frame_t sz, bool final)
349 throw InsufficientDiscSpace(TempDirectory::getInstance()->getPath()); 365 throw InsufficientDiscSpace(TempDirectory::getInstance()->getPath());
350 } 366 }
351 break; 367 break;
352 368
353 case CacheInMemory: 369 case CacheInMemory:
354 m_dataLock.lockForWrite(); 370 m_dataLock.lock();
355 for (sv_frame_t s = 0; s < count; ++s) { 371 m_data.insert(m_data.end(), buffer, buffer + count);
356 m_data.push_back(buffer[s]);
357 }
358 m_dataLock.unlock(); 372 m_dataLock.unlock();
359 break; 373 break;
360 } 374 }
361 } 375 }
362 376
406 pushBufferNonResampling(m_resampleBuffer, out); 420 pushBufferNonResampling(m_resampleBuffer, out);
407 delete[] padding; 421 delete[] padding;
408 } 422 }
409 } 423 }
410 424
411 SampleBlock 425 vector<float>
412 CodedAudioFileReader::getInterleavedFrames(sv_frame_t start, sv_frame_t count) const 426 CodedAudioFileReader::getInterleavedFrames(sv_frame_t start, sv_frame_t count) const
413 { 427 {
414 // Lock is only required in CacheInMemory mode (the cache file 428 // Lock is only required in CacheInMemory mode (the cache file
415 // reader is expected to be thread safe and manage its own 429 // reader is expected to be thread safe and manage its own
416 // locking) 430 // locking)
417 431
418 if (!m_initialised) { 432 if (!m_initialised) {
419 SVDEBUG << "CodedAudioFileReader::getInterleavedFrames: not initialised" << endl; 433 SVDEBUG << "CodedAudioFileReader::getInterleavedFrames: not initialised" << endl;
420 return SampleBlock(); 434 return {};
421 } 435 }
422 436
423 SampleBlock frames; 437 vector<float> frames;
424 438
425 switch (m_cacheMode) { 439 switch (m_cacheMode) {
426 440
427 case CacheInTemporaryFile: 441 case CacheInTemporaryFile:
428 if (m_cacheFileReader) { 442 if (m_cacheFileReader) {
430 } 444 }
431 break; 445 break;
432 446
433 case CacheInMemory: 447 case CacheInMemory:
434 { 448 {
435 if (!isOK()) return SampleBlock(); 449 if (!isOK()) return {};
436 if (count == 0) return SampleBlock(); 450 if (count == 0) return {};
437 451
438 sv_frame_t idx = start * m_channelCount; 452 sv_frame_t ix0 = start * m_channelCount;
439 sv_frame_t i = 0; 453 sv_frame_t ix1 = ix0 + (count * m_channelCount);
440 sv_frame_t n = count * m_channelCount; 454
441 455
442 frames.resize(n); 456 // This lock used to be a QReadWriteLock, but it appears that
443 457 // its lock mechanism is significantly slower than QMutex so
444 m_dataLock.lockForRead(); 458 // it's not a good idea in cases like this where we don't
445 while (i < n && in_range_for(m_data, idx)) { 459 // really have threads taking a long time to read concurrently
446 frames[i++] = m_data[idx++]; 460 m_dataLock.lock();
447 } 461 sv_frame_t n = sv_frame_t(m_data.size());
462 if (ix1 > n) ix1 = n;
463 frames = vector<float>(m_data.begin() + ix0, m_data.begin() + ix1);
448 m_dataLock.unlock(); 464 m_dataLock.unlock();
449
450 frames.resize(i);
451 } 465 }
452 } 466 }
453 467
454 if (m_normalised) { 468 if (m_normalised) {
455 for (auto &f: frames) f *= m_gain; 469 for (auto &f: frames) f *= m_gain;