diff main/Analyser.h @ 580:f52766aa747b

Rename src -> main for consistency with SV/Sonic Lineup
author Chris Cannam
date Wed, 14 Aug 2019 11:57:06 +0100
parents src/Analyser.h@335fd9b439a0
children 90ee5448c205
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main/Analyser.h	Wed Aug 14 11:57:06 2019 +0100
@@ -0,0 +1,266 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Tony
+    An intonation analysis and annotation tool
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2012 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef ANALYSER_H
+#define ANALYSER_H
+
+#include <QObject>
+#include <QRect>
+#include <QMutex>
+
+#include <map>
+#include <vector>
+
+#include "framework/Document.h"
+#include "base/Selection.h"
+#include "base/Clipboard.h"
+#include "data/model/WaveFileModel.h"
+
+class Pane;
+class PaneStack;
+class Layer;
+class TimeValueLayer;
+class Layer;
+
+class Analyser : public QObject,
+                 public Document::LayerCreationHandler
+{
+    Q_OBJECT
+
+public:
+    Analyser();
+    virtual ~Analyser();
+
+    // Process new main model, add derived layers; return "" on
+    // success or error string on failure
+    QString newFileLoaded(Document *newDocument,
+                          ModelId model,
+                          PaneStack *paneStack,
+                          Pane *pane);
+
+    // Remove any derived layers, process the main model, add derived
+    // layers; return "" on success or error string on failure
+    QString analyseExistingFile();
+
+    // Discard any layers etc associated with the current document
+    void fileClosed();
+		       
+    void setIntelligentActions(bool);
+
+    bool getDisplayFrequencyExtents(double &min, double &max);
+    bool setDisplayFrequencyExtents(double min, double max);
+
+    // Return completion %age for initial analysis -- 100 means it's done
+    int getInitialAnalysisCompletion();
+
+    enum Component {
+        Audio = 0,
+        PitchTrack = 1,
+        Notes = 2,
+        Spectrogram = 3,
+    };
+
+    bool isVisible(Component c) const;
+    void setVisible(Component c, bool v);
+    void toggleVisible(Component c) { setVisible(c, !isVisible(c)); }
+
+    bool isAudible(Component c) const;
+    void setAudible(Component c, bool v);
+    void toggleAudible(Component c) { setAudible(c, !isAudible(c)); }
+
+    void cycleStatus(Component c) {
+        if (isVisible(c)) {
+            if (isAudible(c)) {
+                setVisible(c, false);
+                setAudible(c, false);
+            } else {
+                setAudible(c, true);
+            }
+        } else {
+            setVisible(c, true);
+            setAudible(c, false);
+        }
+    }
+
+    ModelId getMainModelId() const {
+        return m_fileModel;
+    }
+    std::shared_ptr<WaveFileModel> getMainModel() const {
+        return ModelById::getAs<WaveFileModel>(m_fileModel);
+    }
+
+    float getGain(Component c) const;
+    void setGain(Component c, float gain);
+
+    float getPan(Component c) const;
+    void setPan(Component c, float pan);
+
+    void getEnclosingSelectionScope(sv_frame_t f, sv_frame_t &f0, sv_frame_t &f1);
+
+    struct FrequencyRange {
+        FrequencyRange() : min(0), max(0) { }
+        FrequencyRange(double min_, double max_) : min(min_), max(max_) { }
+        bool isConstrained() const { return min != max; }
+        double min;
+        double max;
+        bool operator==(const FrequencyRange &r) {
+            return min == r.min && max == r.max;
+        }
+    };
+
+    /**
+     * Analyse the selection and schedule asynchronous adds of
+     * candidate layers for the region it contains. Returns "" on
+     * success or a user-readable error string on failure. If the
+     * frequency range isConstrained(), analysis will be constrained
+     * to that range.
+     */
+    QString reAnalyseSelection(Selection sel, FrequencyRange range);
+
+    /**
+     * Return true if the analysed pitch candidates are currently
+     * visible (they are hidden from the call to reAnalyseSelection
+     * until they are requested through showPitchCandidates()). Note
+     * that this may return true even when no pitch candidate layers
+     * actually exist yet, because they are constructed
+     * asynchronously. If that is the case, then the layers will
+     * appear when they are created (otherwise they will remain hidden
+     * after creation).
+     */
+    bool arePitchCandidatesShown() const;
+
+    /**
+     * Show or hide the analysed pitch candidate layers. This is reset
+     * (to "hide") with each new call to reAnalyseSelection. Because
+     * the layers are created asynchronously, setting this to true
+     * does not guarantee that they appear immediately, only that they
+     * will appear once they have been created.
+     */
+    void showPitchCandidates(bool shown);
+
+    /**
+     * If a re-analysis has been activated, switch the selected area
+     * of the main pitch track to a different candidate from the
+     * analysis results.
+     */
+    void switchPitchCandidate(Selection sel, bool up);
+
+    /**
+     * Return true if it is possible to switch up to another pitch
+     * candidate. This may mean that the currently selected pitch
+     * candidate is not the highest, or it may mean that no alternate
+     * pitch candidate has been selected at all yet (but some are
+     * available).
+     */
+    bool haveHigherPitchCandidate() const;
+
+    /**
+     * Return true if it is possible to switch down to another pitch
+     * candidate. This may mean that the currently selected pitch
+     * candidate is not the lowest, or it may mean that no alternate
+     * pitch candidate has been selected at all yet (but some are
+     * available).
+     */
+    bool haveLowerPitchCandidate() const;
+
+    /**
+     * Delete the pitch estimates from the selected area of the main
+     * pitch track.
+     */
+    void deletePitches(Selection sel);
+
+    /**
+     * Move the main pitch track and any active analysis candidate
+     * tracks up or down an octave in the selected area.
+     */
+    void shiftOctave(Selection sel, bool up);
+
+    /**
+     * Remove any re-analysis layers and also reset the pitch track in
+     * the given selection to its state prior to the last re-analysis,
+     * abandoning any changes made since then. No re-analysis layers
+     * will be available until after the next call to
+     * reAnalyseSelection.
+     */
+    void abandonReAnalysis(Selection sel);
+
+    /**
+     * Remove any re-analysis layers, without any expectation of
+     * adding them later, unlike showPitchCandidates(false), and
+     * without changing the current pitch track, unlike
+     * abandonReAnalysis().
+     */
+    void clearReAnalysis();
+
+    /**
+     * Import the pitch track from the given layer into our
+     * pitch-track layer.
+     */
+    void takePitchTrackFrom(Layer *layer);
+
+    Pane *getPane() {
+        return m_pane;
+    }
+
+    Layer *getLayer(Component type) {
+        return m_layers[type];
+    }
+
+signals:
+    void layersChanged();
+    void initialAnalysisCompleted();
+
+protected slots:
+    void layerAboutToBeDeleted(Layer *);
+    void layerCompletionChanged(ModelId);
+    void reAnalyseRegion(sv_frame_t, sv_frame_t, float, float);
+    void materialiseReAnalysis();
+
+protected:
+    Document *m_document;
+    ModelId m_fileModel;
+    PaneStack *m_paneStack;
+    Pane *m_pane;
+
+    mutable std::map<Component, Layer *> m_layers;
+
+    Clipboard m_preAnalysis;
+    Selection m_reAnalysingSelection;
+    FrequencyRange m_reAnalysingRange;
+    std::vector<Layer *> m_reAnalysisCandidates;
+    int m_currentCandidate;
+    bool m_candidatesVisible;
+    Document::LayerCreationAsyncHandle m_currentAsyncHandle;
+    QMutex m_asyncMutex;
+
+    QString doAllAnalyses(bool withPitchTrack);
+
+    QString addVisualisations();
+    QString addWaveform();
+    QString addAnalyses();
+
+    void discardPitchCandidates();
+
+    void stackLayers();
+    
+    // Document::LayerCreationHandler method
+    void layersCreated(Document::LayerCreationAsyncHandle,
+                       std::vector<Layer *>, std::vector<Layer *>);
+
+    void saveState(Component c) const;
+    void loadState(Component c);
+};
+
+#endif