Mercurial > hg > tony
comparison src/Analyser.cpp @ 572:3f0b44418a19 by-id
Toward using ModelById logic (incomplete)
author | Chris Cannam |
---|---|
date | Mon, 08 Jul 2019 14:12:08 +0100 |
parents | c6c8c1645ab6 |
children | 5c14493026da |
comparison
equal
deleted
inserted
replaced
571:2cf4978eb724 | 572:3f0b44418a19 |
---|---|
39 | 39 |
40 using std::vector; | 40 using std::vector; |
41 | 41 |
42 Analyser::Analyser() : | 42 Analyser::Analyser() : |
43 m_document(0), | 43 m_document(0), |
44 m_fileModel(0), | |
45 m_paneStack(0), | 44 m_paneStack(0), |
46 m_pane(0), | 45 m_pane(0), |
47 m_currentCandidate(-1), | 46 m_currentCandidate(-1), |
48 m_candidatesVisible(false), | 47 m_candidatesVisible(false), |
49 m_currentAsyncHandle(0) | 48 m_currentAsyncHandle(0) |
67 Analyser::~Analyser() | 66 Analyser::~Analyser() |
68 { | 67 { |
69 } | 68 } |
70 | 69 |
71 QString | 70 QString |
72 Analyser::newFileLoaded(Document *doc, WaveFileModel *model, | 71 Analyser::newFileLoaded(Document *doc, ModelId model, |
73 PaneStack *paneStack, Pane *pane) | 72 PaneStack *paneStack, Pane *pane) |
74 { | 73 { |
75 m_document = doc; | 74 m_document = doc; |
76 m_fileModel = model; | 75 m_fileModel = model; |
77 m_paneStack = paneStack; | 76 m_paneStack = paneStack; |
78 m_pane = pane; | 77 m_pane = pane; |
79 | 78 |
80 if (!m_fileModel) return "Internal error: Analyser::newFileLoaded() called with no model present"; | 79 if (!ModelById::isa<WaveFileModel>(m_fileModel)) { |
80 return "Internal error: Analyser::newFileLoaded() called with no model, or a non-WaveFileModel"; | |
81 } | |
81 | 82 |
82 connect(doc, SIGNAL(layerAboutToBeDeleted(Layer *)), | 83 connect(doc, SIGNAL(layerAboutToBeDeleted(Layer *)), |
83 this, SLOT(layerAboutToBeDeleted(Layer *))); | 84 this, SLOT(layerAboutToBeDeleted(Layer *))); |
84 | 85 |
85 QSettings settings; | 86 QSettings settings; |
95 { | 96 { |
96 if (!m_document) return "Internal error: Analyser::analyseExistingFile() called with no document present"; | 97 if (!m_document) return "Internal error: Analyser::analyseExistingFile() called with no document present"; |
97 | 98 |
98 if (!m_pane) return "Internal error: Analyser::analyseExistingFile() called with no pane present"; | 99 if (!m_pane) return "Internal error: Analyser::analyseExistingFile() called with no pane present"; |
99 | 100 |
100 if (!m_fileModel) return "Internal error: Analyser::analyseExistingFile() called with no model present"; | 101 if (m_fileModel.isNone()) return "Internal error: Analyser::analyseExistingFile() called with no model present"; |
101 | 102 |
102 if (m_layers[PitchTrack]) { | 103 if (m_layers[PitchTrack]) { |
103 m_document->removeLayerFromView(m_pane, m_layers[PitchTrack]); | 104 m_document->removeLayerFromView(m_pane, m_layers[PitchTrack]); |
104 m_layers[PitchTrack] = 0; | 105 m_layers[PitchTrack] = 0; |
105 } | 106 } |
227 } | 228 } |
228 | 229 |
229 QString | 230 QString |
230 Analyser::addVisualisations() | 231 Analyser::addVisualisations() |
231 { | 232 { |
232 if (!m_fileModel) return "Internal error: Analyser::addVisualisations() called with no model present"; | 233 if (m_fileModel.isNone()) return "Internal error: Analyser::addVisualisations() called with no model present"; |
233 | 234 |
234 // A spectrogram, off by default. Must go at the back because it's | 235 // A spectrogram, off by default. Must go at the back because it's |
235 // opaque | 236 // opaque |
236 | 237 |
237 /* This is roughly what we'd do for a constant-Q spectrogram, but it | 238 /* This is roughly what we'd do for a constant-Q spectrogram, but it |
327 } | 328 } |
328 | 329 |
329 QString | 330 QString |
330 Analyser::addAnalyses() | 331 Analyser::addAnalyses() |
331 { | 332 { |
333 auto waveFileModel = ModelById::getAs<WaveFileModel>(m_fileModel); | |
334 if (!waveFileModel) { | |
335 return "Internal error: Analyser::addAnalyses() called with no model present"; | |
336 } | |
337 | |
332 // As with the spectrogram above, if these layers exist we use | 338 // As with the spectrogram above, if these layers exist we use |
333 // them | 339 // them |
334 TimeValueLayer *existingPitch = 0; | 340 TimeValueLayer *existingPitch = 0; |
335 FlexiNoteLayer *existingNotes = 0; | 341 FlexiNoteLayer *existingNotes = 0; |
336 for (int i = 0; i < m_pane->getLayerCount(); ++i) { | 342 for (int i = 0; i < m_pane->getLayerCount(); ++i) { |
393 bool onset = settings.value("onset-analysis", true).toBool(); // should these be the same as in MainWindow.cpp? | 399 bool onset = settings.value("onset-analysis", true).toBool(); // should these be the same as in MainWindow.cpp? |
394 bool prune = settings.value("prune-analysis", true).toBool(); | 400 bool prune = settings.value("prune-analysis", true).toBool(); |
395 settings.endGroup(); | 401 settings.endGroup(); |
396 | 402 |
397 Transform t = tf->getDefaultTransformFor | 403 Transform t = tf->getDefaultTransformFor |
398 (base + f0out, m_fileModel->getSampleRate()); | 404 (base + f0out, waveFileModel->getSampleRate()); |
399 t.setStepSize(256); | 405 t.setStepSize(256); |
400 t.setBlockSize(2048); | 406 t.setBlockSize(2048); |
401 | 407 |
402 if (precise) { | 408 if (precise) { |
403 cerr << "setting parameters for precise mode" << endl; | 409 cerr << "setting parameters for precise mode" << endl; |
506 QString | 512 QString |
507 Analyser::reAnalyseSelection(Selection sel, FrequencyRange range) | 513 Analyser::reAnalyseSelection(Selection sel, FrequencyRange range) |
508 { | 514 { |
509 QMutexLocker locker(&m_asyncMutex); | 515 QMutexLocker locker(&m_asyncMutex); |
510 | 516 |
517 auto waveFileModel = ModelById::getAs<WaveFileModel>(m_fileModel); | |
518 if (!waveFileModel) { | |
519 return "Internal error: Analyser::reAnalyseSelection() called with no model present"; | |
520 } | |
521 | |
511 if (!m_reAnalysingSelection.isEmpty()) { | 522 if (!m_reAnalysingSelection.isEmpty()) { |
512 if (sel == m_reAnalysingSelection && range == m_reAnalysingRange) { | 523 if (sel == m_reAnalysingSelection && range == m_reAnalysingRange) { |
513 cerr << "selection & range are same as current analysis, ignoring" << endl; | 524 cerr << "selection & range are same as current analysis, ignoring" << endl; |
514 return ""; | 525 return ""; |
515 } | 526 } |
556 if (!tf->haveTransform(base + out)) { | 567 if (!tf->haveTransform(base + out)) { |
557 return notFound.arg(base + out).arg(plugname1).arg(plugname2); | 568 return notFound.arg(base + out).arg(plugname1).arg(plugname2); |
558 } | 569 } |
559 | 570 |
560 Transform t = tf->getDefaultTransformFor | 571 Transform t = tf->getDefaultTransformFor |
561 (base + out, m_fileModel->getSampleRate()); | 572 (base + out, waveFileModel->getSampleRate()); |
562 t.setStepSize(256); | 573 t.setStepSize(256); |
563 t.setBlockSize(2048); | 574 t.setBlockSize(2048); |
564 | 575 |
565 if (range.isConstrained()) { | 576 if (range.isConstrained()) { |
566 t.setParameter("minfreq", float(range.min)); | 577 t.setParameter("minfreq", float(range.min)); |
578 startSample -= 4*grid; // 4*256 is for 4 frames offset due to timestamp shift | 589 startSample -= 4*grid; // 4*256 is for 4 frames offset due to timestamp shift |
579 endSample -= 4*grid; | 590 endSample -= 4*grid; |
580 } else { | 591 } else { |
581 endSample -= 9*grid; // MM says: not sure what the CHP plugin does there | 592 endSample -= 9*grid; // MM says: not sure what the CHP plugin does there |
582 } | 593 } |
583 RealTime start = RealTime::frame2RealTime(startSample, m_fileModel->getSampleRate()); | 594 RealTime start = RealTime::frame2RealTime(startSample, waveFileModel->getSampleRate()); |
584 RealTime end = RealTime::frame2RealTime(endSample, m_fileModel->getSampleRate()); | 595 RealTime end = RealTime::frame2RealTime(endSample, waveFileModel->getSampleRate()); |
585 | 596 |
586 RealTime duration; | 597 RealTime duration; |
587 | 598 |
588 if (sel.getEndFrame() > sel.getStartFrame()) { | 599 if (sel.getEndFrame() > sel.getStartFrame()) { |
589 duration = end - start; | 600 duration = end - start; |
600 t.setDuration(duration); | 611 t.setDuration(duration); |
601 | 612 |
602 transforms.push_back(t); | 613 transforms.push_back(t); |
603 | 614 |
604 m_currentAsyncHandle = | 615 m_currentAsyncHandle = |
605 m_document->createDerivedLayersAsync(transforms, m_fileModel, this); | 616 m_document->createDerivedLayersAsync(transforms, ModelId, this); |
606 | 617 |
607 return ""; | 618 return ""; |
608 } | 619 } |
609 | 620 |
610 bool | 621 bool |