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