annotate transform/ModelTransformer.h @ 1451:b40f67578976 streaming-csv-writer

Update getEndFrame so as to refer explicitly to final frame + 1 (consistent with selection semantics and existing wave model)
author Chris Cannam
date Tue, 17 Apr 2018 10:37:15 +0100
parents 1b888a85983b
children 565575463752
rev   line source
Chris@320 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@320 2
Chris@320 3 /*
Chris@320 4 Sonic Visualiser
Chris@320 5 An audio file viewer and annotation editor.
Chris@320 6 Centre for Digital Music, Queen Mary, University of London.
Chris@320 7 This file copyright 2006 Chris Cannam.
Chris@320 8
Chris@320 9 This program is free software; you can redistribute it and/or
Chris@320 10 modify it under the terms of the GNU General Public License as
Chris@320 11 published by the Free Software Foundation; either version 2 of the
Chris@320 12 License, or (at your option) any later version. See the file
Chris@320 13 COPYING included with this distribution for more information.
Chris@320 14 */
Chris@320 15
Chris@1367 16 #ifndef SV_MODEL_TRANSFORMER_H
Chris@1367 17 #define SV_MODEL_TRANSFORMER_H
Chris@320 18
Chris@320 19 #include "base/Thread.h"
Chris@320 20
Chris@320 21 #include "data/model/Model.h"
Chris@320 22
Chris@350 23 #include "Transform.h"
Chris@350 24
Chris@320 25 /**
Chris@331 26 * A ModelTransformer turns one data model into another.
Chris@320 27 *
Chris@331 28 * Typically in this application, a ModelTransformer might have a
Chris@320 29 * DenseTimeValueModel as its input (e.g. an audio waveform) and a
Chris@320 30 * SparseOneDimensionalModel (e.g. detected beats) as its output.
Chris@320 31 *
Chris@331 32 * The ModelTransformer typically runs in the background, as a
Chris@331 33 * separate thread populating the output model. The model is
Chris@331 34 * available to the user of the ModelTransformer immediately, but may
Chris@331 35 * be initially empty until the background thread has populated it.
Chris@320 36 */
Chris@320 37
Chris@331 38 class ModelTransformer : public Thread
Chris@320 39 {
Chris@320 40 public:
Chris@331 41 virtual ~ModelTransformer();
Chris@320 42
Chris@849 43 typedef std::vector<Model *> Models;
Chris@849 44
Chris@350 45 class Input {
Chris@350 46 public:
Chris@350 47 Input(Model *m) : m_model(m), m_channel(-1) { }
Chris@350 48 Input(Model *m, int c) : m_model(m), m_channel(c) { }
Chris@350 49
Chris@350 50 Model *getModel() const { return m_model; }
Chris@350 51 void setModel(Model *m) { m_model = m; }
Chris@350 52
Chris@350 53 int getChannel() const { return m_channel; }
Chris@350 54 void setChannel(int c) { m_channel = c; }
Chris@350 55
Chris@350 56 protected:
Chris@350 57 Model *m_model;
Chris@350 58 int m_channel;
Chris@350 59 };
Chris@350 60
Chris@361 61 /**
Chris@361 62 * Hint to the processing thread that it should give up, for
Chris@361 63 * example because the process is going to exit or we want to get
Chris@361 64 * rid of the input model. Caller should still wait() and/or
Chris@361 65 * delete the transform before assuming its input and output
Chris@361 66 * models are no longer required.
Chris@361 67 */
Chris@320 68 void abandon() { m_abandoned = true; }
Chris@320 69
Chris@361 70 /**
Chris@1079 71 * Return true if the processing thread is being or has been
Chris@1079 72 * abandoned, i.e. if abandon() has been called.
Chris@1079 73 */
Chris@1079 74 bool isAbandoned() const { return m_abandoned; }
Chris@1079 75
Chris@1079 76 /**
Chris@361 77 * Return the input model for the transform.
Chris@361 78 */
Chris@350 79 Model *getInputModel() { return m_input.getModel(); }
Chris@361 80
Chris@361 81 /**
Chris@361 82 * Return the input channel spec for the transform.
Chris@361 83 */
Chris@350 84 int getInputChannel() { return m_input.getChannel(); }
Chris@350 85
Chris@361 86 /**
Chris@849 87 * Return the set of output models created by the transform or
Chris@849 88 * transforms. Returns an empty list if any transform could not
Chris@849 89 * be initialised; an error message may be available via
Chris@849 90 * getMessage() in this situation.
Chris@361 91 */
Chris@1211 92 Models getOutputModels() {
Chris@1211 93 awaitOutputModels();
Chris@1211 94 return m_outputs;
Chris@1211 95 }
Chris@361 96
Chris@361 97 /**
Chris@849 98 * Return the set of output models, also detaching them from the
Chris@849 99 * transformer so that they will not be deleted when the
Chris@849 100 * transformer is. The caller takes ownership of the models.
Chris@361 101 */
Chris@1211 102 Models detachOutputModels() {
Chris@1211 103 awaitOutputModels();
Chris@877 104 m_detached = true;
Chris@1211 105 return m_outputs;
Chris@877 106 }
Chris@877 107
Chris@877 108 /**
Chris@877 109 * Return any additional models that were created during
Chris@877 110 * processing. This might happen if, for example, a transform was
Chris@877 111 * configured to split a multi-bin output into separate single-bin
Chris@877 112 * models as it processed. These should not be queried until after
Chris@877 113 * the transform has completed.
Chris@877 114 */
Chris@877 115 virtual Models getAdditionalOutputModels() { return Models(); }
Chris@877 116
Chris@877 117 /**
Chris@877 118 * Return true if the current transform is one that may produce
Chris@877 119 * additional models (to be retrieved through
Chris@877 120 * getAdditionalOutputModels above).
Chris@877 121 */
Chris@877 122 virtual bool willHaveAdditionalOutputModels() { return false; }
Chris@877 123
Chris@877 124 /**
Chris@877 125 * Return the set of additional models, also detaching them from
Chris@877 126 * the transformer. The caller takes ownership of the models.
Chris@877 127 */
Chris@877 128 virtual Models detachAdditionalOutputModels() {
Chris@877 129 m_detachedAdd = true;
Chris@877 130 return getAdditionalOutputModels();
Chris@877 131 }
Chris@320 132
Chris@361 133 /**
Chris@361 134 * Return a warning or error message. If getOutputModel returned
Chris@361 135 * a null pointer, this should contain a fatal error message for
Chris@361 136 * the transformer; otherwise it may contain a warning to show to
Chris@361 137 * the user about e.g. suboptimal block size or whatever.
Chris@361 138 */
Chris@361 139 QString getMessage() const { return m_message; }
Chris@361 140
Chris@320 141 protected:
Chris@350 142 ModelTransformer(Input input, const Transform &transform);
Chris@849 143 ModelTransformer(Input input, const Transforms &transforms);
Chris@320 144
Chris@1211 145 virtual void awaitOutputModels() = 0;
Chris@1211 146
Chris@849 147 Transforms m_transforms;
Chris@350 148 Input m_input; // I don't own the model in this
Chris@849 149 Models m_outputs; // I own this, unless...
Chris@320 150 bool m_detached; // ... this is true.
Chris@877 151 bool m_detachedAdd;
Chris@320 152 bool m_abandoned;
Chris@361 153 QString m_message;
Chris@320 154 };
Chris@320 155
Chris@320 156 #endif