comparison data/model/WaveFileModel.cpp @ 175:b0f4555b625e

* Introduce WritableWaveFileModel, and use it as an output model for audio real-time plugin transforms. Updates aren't working correctly yet.
author Chris Cannam
date Tue, 03 Oct 2006 14:17:37 +0000
parents 4148ad087959
children 570794f6f6a7
comparison
equal deleted inserted replaced
174:f8cf055dbf34 175:b0f4555b625e
33 using std::cerr; 33 using std::cerr;
34 using std::endl; 34 using std::endl;
35 35
36 WaveFileModel::WaveFileModel(QString path) : 36 WaveFileModel::WaveFileModel(QString path) :
37 m_path(path), 37 m_path(path),
38 m_myReader(true),
38 m_fillThread(0), 39 m_fillThread(0),
39 m_updateTimer(0), 40 m_updateTimer(0),
40 m_lastFillExtent(0), 41 m_lastFillExtent(0),
41 m_exiting(false) 42 m_exiting(false)
42 { 43 {
43 m_reader = AudioFileReaderFactory::createReader(path); 44 m_reader = AudioFileReaderFactory::createReader(path);
45 connect(m_reader, SIGNAL(frameCountChanged()),
46 this, SLOT(frameCountChanged()));
44 setObjectName(QFileInfo(path).fileName()); 47 setObjectName(QFileInfo(path).fileName());
45 if (isOK()) fillCache(); 48 if (isOK()) fillCache();
46 } 49 }
47 50
51 WaveFileModel::WaveFileModel(QString path, AudioFileReader *reader) :
52 m_path(path),
53 m_myReader(false),
54 m_fillThread(0),
55 m_updateTimer(0),
56 m_lastFillExtent(0),
57 m_exiting(false)
58 {
59 m_reader = reader;
60 connect(m_reader, SIGNAL(frameCountChanged()),
61 this, SLOT(frameCountChanged()));
62 setObjectName(QFileInfo(path).fileName());
63 if (isOK()) fillCache();
64 }
65
48 WaveFileModel::~WaveFileModel() 66 WaveFileModel::~WaveFileModel()
49 { 67 {
50 m_exiting = true; 68 m_exiting = true;
51 if (m_fillThread) m_fillThread->wait(); 69 if (m_fillThread) m_fillThread->wait();
52 delete m_reader; 70 if (m_myReader) delete m_reader;
53 m_reader = 0; 71 m_reader = 0;
54 } 72 }
55 73
56 bool 74 bool
57 WaveFileModel::isOK() const 75 WaveFileModel::isOK() const
109 << end << " < " << start << ")" << std::endl; 127 << end << " < " << start << ")" << std::endl;
110 assert(end >= start); 128 assert(end >= start);
111 } 129 }
112 130
113 if (!m_reader || !m_reader->isOK()) return 0; 131 if (!m_reader || !m_reader->isOK()) return 0;
132
133 // std::cerr << "WaveFileModel::getValues(" << channel << ", "
134 // << start << ", " << end << "): calling reader" << std::endl;
114 135
115 SampleBlock frames; 136 SampleBlock frames;
116 m_reader->getInterleavedFrames(start, end - start, frames); 137 m_reader->getInterleavedFrames(start, end - start, frames);
117 138
118 size_t i = 0; 139 size_t i = 0;
355 m_updateTimer->start(100); 376 m_updateTimer->start(100);
356 m_fillThread = new RangeCacheFillThread(*this); 377 m_fillThread = new RangeCacheFillThread(*this);
357 connect(m_fillThread, SIGNAL(finished()), this, SLOT(cacheFilled())); 378 connect(m_fillThread, SIGNAL(finished()), this, SLOT(cacheFilled()));
358 m_mutex.unlock(); 379 m_mutex.unlock();
359 m_fillThread->start(); 380 m_fillThread->start();
381 std::cerr << "WaveFileModel::fillCache: started fill thread" << std::endl;
360 } 382 }
383
384 void
385 WaveFileModel::frameCountChanged()
386 {
387 m_mutex.lock();
388 if (m_updateTimer) {
389 std::cerr << "WaveFileModel::frameCountChanged: updating existing fill thread" << std::endl;
390 m_fillThread->frameCountChanged();
391 m_mutex.unlock();
392 } else {
393 std::cerr << "WaveFileModel::frameCountChanged: restarting [inefficient]" << std::endl;
394 m_cache[0].clear();
395 m_cache[1].clear();
396 m_mutex.unlock();
397 fillCache();
398 }
399 }
361 400
362 void 401 void
363 WaveFileModel::fillTimerTimedOut() 402 WaveFileModel::fillTimerTimedOut()
364 { 403 {
365 if (m_fillThread) { 404 if (m_fillThread) {
366 size_t fillExtent = m_fillThread->getFillExtent(); 405 size_t fillExtent = m_fillThread->getFillExtent();
406 cerr << "WaveFileModel::fillTimerTimedOut: extent = " << fillExtent << endl;
367 if (fillExtent > m_lastFillExtent) { 407 if (fillExtent > m_lastFillExtent) {
368 emit modelChanged(m_lastFillExtent, fillExtent); 408 emit modelChanged(m_lastFillExtent, fillExtent);
369 m_lastFillExtent = fillExtent; 409 m_lastFillExtent = fillExtent;
370 } 410 }
371 } else { 411 } else {
412 cerr << "WaveFileModel::fillTimerTimedOut: no thread" << std::endl;
372 emit modelChanged(); 413 emit modelChanged();
373 } 414 }
374 } 415 }
375 416
376 void 417 void
381 m_fillThread = 0; 422 m_fillThread = 0;
382 delete m_updateTimer; 423 delete m_updateTimer;
383 m_updateTimer = 0; 424 m_updateTimer = 0;
384 m_mutex.unlock(); 425 m_mutex.unlock();
385 emit modelChanged(); 426 emit modelChanged();
386 // cerr << "WaveFileModel::cacheFilled" << endl; 427 cerr << "WaveFileModel::cacheFilled" << endl;
428 }
429
430 void
431 WaveFileModel::RangeCacheFillThread::frameCountChanged()
432 {
433 m_frameCount = m_model.getFrameCount();
387 } 434 }
388 435
389 void 436 void
390 WaveFileModel::RangeCacheFillThread::run() 437 WaveFileModel::RangeCacheFillThread::run()
391 { 438 {
399 SampleBlock block; 446 SampleBlock block;
400 447
401 if (!m_model.isOK()) return; 448 if (!m_model.isOK()) return;
402 449
403 size_t channels = m_model.getChannelCount(); 450 size_t channels = m_model.getChannelCount();
404 size_t frames = m_model.getFrameCount();
405 451
406 Range *range = new Range[2 * channels]; 452 Range *range = new Range[2 * channels];
407 size_t count[2]; 453 size_t count[2];
408 count[0] = count[1] = 0; 454 count[0] = count[1] = 0;
409 455
410 while (frame < frames) { 456 while (frame < m_frameCount) {
457
458 std::cerr << "WaveFileModel::fill: frame = " << frame << ", count = " << m_frameCount << std::endl;
411 459
412 m_model.m_reader->getInterleavedFrames(frame, readBlockSize, block); 460 m_model.m_reader->getInterleavedFrames(frame, readBlockSize, block);
413 461
414 for (size_t i = 0; i < readBlockSize; ++i) { 462 for (size_t i = 0; i < readBlockSize; ++i) {
415 463
470 MUNLOCK(&rr, m_model.m_cache[ct].capacity() * sizeof(Range)); 518 MUNLOCK(&rr, m_model.m_cache[ct].capacity() * sizeof(Range));
471 } 519 }
472 520
473 delete[] range; 521 delete[] range;
474 522
475 m_fillExtent = frames; 523 m_fillExtent = m_frameCount;
476 524
477 // for (size_t ct = 0; ct < 2; ++ct) { 525 for (size_t ct = 0; ct < 2; ++ct) {
478 // cerr << "Cache type " << ct << " now contains " << m_model.m_cache[ct].size() << " ranges" << endl; 526 cerr << "Cache type " << ct << " now contains " << m_model.m_cache[ct].size() << " ranges" << endl;
479 // } 527 }
480 } 528 }
481 529
482 void 530 void
483 WaveFileModel::toXml(QTextStream &out, 531 WaveFileModel::toXml(QTextStream &out,
484 QString indent, 532 QString indent,