annotate src/Support/Module.h @ 121:3cdaa81c3aca

- Massive refactoring to make module tree stuff work. In theory we now support configuration files again. The graphics stuff is untested as yet.
author tomwalters
date Mon, 18 Oct 2010 04:42:28 +0000
parents 89e4facffd93
children bbf4728ffa0e
rev   line source
tomwalters@0 1 // Copyright 2010, Thomas Walters
tomwalters@0 2 //
tomwalters@0 3 // AIM-C: A C++ implementation of the Auditory Image Model
tomwalters@0 4 // http://www.acousticscale.org/AIMC
tomwalters@0 5 //
tomwalters@45 6 // Licensed under the Apache License, Version 2.0 (the "License");
tomwalters@45 7 // you may not use this file except in compliance with the License.
tomwalters@45 8 // You may obtain a copy of the License at
tomwalters@0 9 //
tomwalters@45 10 // http://www.apache.org/licenses/LICENSE-2.0
tomwalters@0 11 //
tomwalters@45 12 // Unless required by applicable law or agreed to in writing, software
tomwalters@45 13 // distributed under the License is distributed on an "AS IS" BASIS,
tomwalters@45 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
tomwalters@45 15 // See the License for the specific language governing permissions and
tomwalters@45 16 // limitations under the License.
tomwalters@0 17
tomwalters@0 18 /*! \file
tomwalters@0 19 * \brief Base class for all AIM-C modules.
tomwalters@0 20 */
tomwalters@0 21
tomwalters@0 22 /*! \author: Thomas Walters <tom@acousticscale.org>
tomwalters@0 23 * \date 2010/01/23
tomwalters@23 24 * \version \$Id$
tomwalters@0 25 */
tomwalters@0 26
tomwalters@11 27 #ifndef AIMC_SUPPORT_MODULE_H_
tomwalters@11 28 #define AIMC_SUPPORT_MODULE_H_
tomwalters@0 29
tomwalters@52 30 // Several modules expect the M_PI macro and isnan() to be defined
tomwalters@52 31 #ifdef _MSC_VER
tomwalters@52 32 #define M_PI 3.14159265359
tomwalters@52 33 #define isnan _isnan
tomwalters@52 34 #define isinf _isinf
tomwalters@52 35 #endif
tomwalters@52 36
tomwalters@49 37 #include <iostream>
tomwalters@0 38 #include <set>
tomwalters@0 39 #include <string>
tomwalters@0 40
tomwalters@0 41 #include "Support/Common.h"
tomwalters@0 42 #include "Support/Parameters.h"
tomwalters@0 43 #include "Support/SignalBank.h"
tomwalters@0 44
tomwalters@0 45 namespace aimc {
tomwalters@49 46 using std::ostream;
tomwalters@0 47 using std::set;
tomwalters@0 48 using std::string;
tomwalters@9 49
tomwalters@9 50 /*! \brief Base class for all AIM-C modules.
tomwalters@9 51 *
tomwalters@9 52 * Module() is a base class, from which all AIM-C modules are derived.
tomwalters@9 53 * Classes deriving from module need to implement, at minimum, the pure
tomwalters@9 54 * virtual public function Module::Process() and the pure virtual private
tomwalters@9 55 * functions Module::InitializeInternal() and Module::ResetInternal().
tomwalters@9 56 * (Note: this is in contravention of
tomwalters@9 57 * <a href="http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Inheritance#Inheritance">
tomwalters@9 58 * this rule on inheritance</a> in the Google style guide, but it is designed
tomwalters@9 59 * to make the implementation of modules as simple as possible.)
tomwalters@9 60 *
tomwalters@9 61 * The module constructor is called with a pointer to a set of Parameters.
tomwalters@9 62 * In the constructor, the module sets the defaults for its various
tomwalters@9 63 * parameters.
tomwalters@9 64 * A module is initialized with a reference to a valid SignalBank. After the
tomwalters@9 65 * Initialize(SignalBank*) function has been called, a call to GetOutputBank()
tomwalters@9 66 * returns a pointer to a SignalBank in which the results
tomwalters@9 67 * of the module's processing will be placed. Modules can use the output_
tomwalters@9 68 * SignalBank to store their output, or leave it uninitialized if they do not
tomwalters@9 69 * produce an output.
tomwalters@9 70 * At each call to Process(input), the module takes the
tomwalters@9 71 * SignalBank 'input' (which must, unless otherwise specified, have the same
tomwalters@9 72 * number of channels, sample rate, buffer size and centre frequencies as the
tomwalters@9 73 * SignalBank which was passed to Initialize()), processes it, and places the
tomwalters@9 74 * output in the internal SignalBank output_.
tomwalters@9 75 * Modules can have an arbitrary number of unique targets. Each
tomwalters@9 76 * completed output frame is 'pushed' to all of the targets of the module
tomwalters@9 77 * in turn when PushOutput() is called. To achieve this, after each complete
tomwalters@9 78 * output SignalBank is filled, the module calls the Process() function of
tomwalters@9 79 * each of its targets in turn.
tomwalters@9 80 * When Initialize() is first called. The module Initialize()s all of its
tomwalters@9 81 * targets with its ouptut_ SignalBank, if its output bank has been set up.
tomwalters@9 82 *
tomwalters@9 83 */
tomwalters@0 84 class Module {
tomwalters@0 85 public:
tomwalters@0 86 explicit Module(Parameters *parameters);
tomwalters@0 87
tomwalters@0 88 virtual ~Module();
tomwalters@0 89
tomwalters@9 90 /* \brief Initialize the module, including calling InitializeInternal().
tomwalters@9 91 * Validate this module's output SignalBank, and initialize
tomwalters@0 92 * any targets of the module if necessary.
tomwalters@0 93 * \param input Input SignalBank.
tomwalters@9 94 * \return true on success, false on failure.
tomwalters@3 95 *
tomwalters@9 96 * A call to Initialize() will first validate the input SignalBank passed to
tomwalters@9 97 * it. If this SignalBank is valid, then it will call the
tomwalters@9 98 * InitializeInternal() function of the child class; this will set up the
tomwalters@9 99 * child class, and may, if the module produces an output, initialize the
tomwalters@9 100 * member variable SignalBank output_. If output_ is initialized after the
tomwalters@9 101 * call to InitializeInternal(), the module will Initialize its targets with
tomwalters@9 102 * the output. In this way, it is possible to initialize an entire module
tomwalters@9 103 * tree with a single call to the Initialize() function of the root.
tomwalters@9 104 *
tomwalters@9 105 * This function is declared virtual in order to deal with the edge case of
tomwalters@9 106 * input modules which do not take a SignalBank as input, but rather
tomwalters@9 107 * generate their own input. In this case, it is better to be able to
tomwalters@9 108 * override the default Initialize function. When creating a new module, do
tomwalters@9 109 * not create a new version of Initialize uness you're sure you know what
tomwalters@9 110 * you're doing!
tomwalters@120 111 *
tomwalters@120 112 * global_parameters stores things like the input filename, output filenames
tomwalters@120 113 * and any other metadata that modules might want to share. If present, it
tomwalters@120 114 * is propagated to all children. These parameters are mutable and may
tomwalters@120 115 * change.
tomwalters@0 116 */
tomwalters@120 117 virtual bool Initialize(const SignalBank &input,
tomwalters@120 118 Parameters *global_parameters);
tomwalters@0 119
tomwalters@9 120 /*! \brief Returns true if the module has been correctly initialized
tomwalters@9 121 * \return true if module has been initialized, false otherwise
tomwalters@0 122 */
tomwalters@0 123 bool initialized() const;
tomwalters@0 124
tomwalters@0 125 /* \brief Add a target to this module. Whenever it generates a new
tomwalters@0 126 * output, this module will push its output to all its targets.
tomwalters@9 127 * \param target_module Pointer to a target Module to add.
tomwalters@9 128 * \return true on success, false on failure.
tomwalters@9 129 *
tomwalters@9 130 * When a pointer is passed as a target to the module, the caller retains
tomwalters@9 131 * ownership of the module that it points to. The pointed-to module must
tomwalters@9 132 * continue to exist until it is deleted from the target list by a call
tomwalters@9 133 * to DeleteTarget() or DeleteAllTargets(), or the current module is
tomwalters@9 134 * destroyed. Bad things will happen if the Module pointed to is deleted
tomwalters@9 135 * and Initialize(), Reset() or Process() is subsequently called.
tomwalters@0 136 */
tomwalters@0 137 bool AddTarget(Module* target_module);
tomwalters@0 138
tomwalters@9 139 /*! \brief Remove a previously added target module from the list of targets
tomwalters@9 140 * for this module.
tomwalters@9 141 * \param target_module Pointer to the module to remove. This must be a
tomwalters@9 142 * pointer that was previously passed to AddTarget()
tomwalters@9 143 * \return true on success, false on failure.
tomwalters@0 144 */
tomwalters@9 145 bool RemoveTarget(Module* target_module);
tomwalters@0 146
tomwalters@9 147 /*! \brief Remove all previously added target modules from the list of
tomwalters@9 148 * targets for this module.
tomwalters@0 149 */
tomwalters@9 150 void RemoveAllTargets();
tomwalters@0 151
tomwalters@9 152 /*! \brief Process a buffer.
tomwalters@9 153 * \param input SignalBank of the form which was passed to Initialize()
tomwalters@9 154 *
tomwalters@9 155 * Process is called once for each input SignalBank. When implemented in
tomwalters@9 156 * classes inheriting from aimc::Module, P
tomwalters@9 157 * this SignalBank contains the (read-only) input to the module. It is
tomwalters@9 158 * expected that the input SignalBank will have the same number of channels,
tomwalters@9 159 * buffer length and sample rate as the SignalBank passed to Initialize.
tomwalters@0 160 */
tomwalters@0 161 virtual void Process(const SignalBank &input) = 0;
tomwalters@0 162
tomwalters@3 163 /*! \brief Reset the internal state of this module and all its children to
tomwalters@3 164 * their initial state.
tomwalters@9 165 *
tomwalters@9 166 * Like a call to Initialize() will cause all target modules to be
tomwalters@9 167 * initialized, a call to Reset() will cause all target modules to be reset.
tomwalters@0 168 */
tomwalters@8 169 void Reset();
tomwalters@0 170
tomwalters@9 171 /*! \brief Return a pointer to the output SignalBank_ for this class.
tomwalters@9 172 * \return pointer to the SignalBank that this module uses to store its
tomwalters@9 173 * output.
tomwalters@0 174 */
tomwalters@0 175 const SignalBank* GetOutputBank() const;
tomwalters@0 176
tomwalters@49 177 void PrintTargets(ostream &out);
tomwalters@121 178 void PrintTargetsForDot(ostream &out);
tomwalters@121 179 void PrintConfiguration(ostream &out);
tomwalters@49 180
tomwalters@23 181 string version() const {
tomwalters@23 182 return module_version_;
tomwalters@23 183 }
tomwalters@23 184
tomwalters@23 185 string id() const {
tomwalters@23 186 return module_identifier_;
tomwalters@23 187 }
tomwalters@23 188
tomwalters@23 189 string description() const {
tomwalters@23 190 return module_description_;
tomwalters@23 191 }
tomwalters@23 192
tomwalters@23 193 string type() const {
tomwalters@23 194 return module_type_;
tomwalters@23 195 }
tomwalters@121 196
tomwalters@121 197 bool done() {
tomwalters@121 198 return done_;
tomwalters@121 199 }
tomwalters@121 200
tomwalters@121 201 void set_instance_name(string instance_name) {
tomwalters@121 202 instance_name_ = instance_name;
tomwalters@121 203 }
tomwalters@121 204
tomwalters@121 205 string instance_name() {
tomwalters@121 206 return instance_name_;
tomwalters@121 207 }
tomwalters@23 208
tomwalters@0 209 protected:
tomwalters@0 210 void PushOutput();
tomwalters@0 211
tomwalters@3 212 virtual void ResetInternal() = 0;
tomwalters@3 213
tomwalters@0 214 virtual bool InitializeInternal(const SignalBank &input) = 0;
tomwalters@0 215
tomwalters@0 216 bool initialized_;
tomwalters@121 217 bool done_;
tomwalters@0 218 set<Module*> targets_;
tomwalters@0 219 SignalBank output_;
tomwalters@0 220 Parameters* parameters_;
tomwalters@120 221 Parameters* global_parameters_;
tomwalters@0 222
tomwalters@0 223 string module_identifier_;
tomwalters@0 224 string module_type_;
tomwalters@0 225 string module_description_;
tomwalters@0 226 string module_version_;
tomwalters@121 227
tomwalters@121 228 string instance_name_;
tomwalters@0 229
tomwalters@0 230 private:
tomwalters@0 231 DISALLOW_COPY_AND_ASSIGN(Module);
tomwalters@0 232 };
tomwalters@0 233 }
tomwalters@0 234
tomwalters@11 235 #endif // AIMC_SUPPORT_MODULE_H_