File: ModelTransformer.h

package info (click to toggle)
sonic-visualiser 5.2.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 24,744 kB
  • sloc: cpp: 158,888; ansic: 11,920; sh: 1,785; makefile: 517; xml: 64; perl: 31
file content (166 lines) | stat: -rw-r--r-- 5,460 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */

/*
    Sonic Visualiser
    An audio file viewer and annotation editor.
    Centre for Digital Music, Queen Mary, University of London.
    This file copyright 2006 Chris Cannam.
   
    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 SV_MODEL_TRANSFORMER_H
#define SV_MODEL_TRANSFORMER_H

#include "base/Thread.h"

#include "data/model/Model.h"

#include "Transform.h"

namespace sv {

/**
 * A ModelTransformer turns one data model into another.
 *
 * Typically in this application, a ModelTransformer might have a
 * DenseTimeValueModel as its input (e.g. an audio waveform) and a
 * SparseOneDimensionalModel (e.g. detected beats) as its output.
 *
 * The ModelTransformer typically runs in the background, as a
 * separate thread populating the output model.  The model is
 * available to the user of the ModelTransformer immediately, but may
 * be initially empty until the background thread has populated it.
 */
class ModelTransformer : public Thread
{
public:
    virtual ~ModelTransformer();

    typedef std::vector<ModelId> Models;

    class Input {
    public:
        Input(ModelId m) : m_model(m), m_channel(-1) { }
        Input(ModelId m, int c) : m_model(m), m_channel(c) { }

        ModelId getModel() const { return m_model; }
        void setModel(ModelId m) { m_model = m; }

        int getChannel() const { return m_channel; }
        void setChannel(int c) { m_channel = c; }

    protected:
        ModelId m_model;
        int m_channel;
    };

    /**
     * An interface that can be provided if synchronous reporting of
     * transform completion is required. Functions in this interface
     * may be called from any thread. Note that updates within a GUI
     * application are arguably better handled by connecting to the
     * completionChanged() and ready() signals of each output
     * Model. This mechanism is more useful in contexts without an
     * event loop.
     */     
    class CompletionReporter {
    public:
        /**
         * Report a change in transform completion. The percentage
         * will of course be in the range 0-100; a value of 100
         * indicates that the given model is complete and that
         * setCompletion will not be called for that model by this
         * transformer again.
         */  
        virtual void setCompletion(ModelId modelId, int percentage) = 0;
    };
    
    /**
     * Hint to the processing thread that it should give up, for
     * example because the process is going to exit or the
     * model/document context is being replaced.  Caller should still
     * wait() to be sure that processing has ended.
     */
    void abandon() { m_abandoned = true; }

    /**
     * Return true if the processing thread is being or has been
     * abandoned, i.e. if abandon() has been called.
     */
    bool isAbandoned() const { return m_abandoned; }
    
    /**
     * Return the input model for the transform.
     */
    ModelId getInputModel()  { return m_input.getModel(); }

    /**
     * Return the input channel spec for the transform.
     */
    int getInputChannel() { return m_input.getChannel(); }

    /**
     * Return the set of output model IDs created by the transform or
     * transforms. Returns an empty list if any transform could not be
     * initialised; an error message may be available via getMessage()
     * in this situation. The returned models have been added to
     * ModelById.
     */
    Models getOutputModels() {
        awaitOutputModels();
        return m_outputs;
    }

    /**
     * Return any additional models that were created during
     * processing. This might happen if, for example, a transform was
     * configured to split a multi-bin output into separate single-bin
     * models as it processed. These should not be queried until after
     * the transform has completed.
     */
    virtual Models getAdditionalOutputModels() { return Models(); }

    /**
     * Return true if the current transform is one that may produce
     * additional models (to be retrieved through
     * getAdditionalOutputModels above).
     */
    virtual bool willHaveAdditionalOutputModels() { return false; }

    /**
     * Return a warning or error message.  If getOutputModel returned
     * a null pointer, this should contain a fatal error message for
     * the transformer; otherwise it may contain a warning to show to
     * the user about e.g. suboptimal block size or whatever.  
     */
    QString getMessage() const { return m_message; }

protected:
    ModelTransformer(Input input,
                     const Transform &transform,
                     CompletionReporter *reporter = nullptr);
    ModelTransformer(Input input,
                     const Transforms &transforms,
                     CompletionReporter *reporter = nullptr);

    virtual void awaitOutputModels() = 0;
    
    Transforms m_transforms;
    Input m_input;
    Models m_outputs;
    CompletionReporter *m_reporter;
    bool m_abandoned;
    QString m_message;

private:
    void checkTransformsExist();
};

} // end namespace sv

#endif