annotate trunk/src/Support/Module.h @ 402:69466da9745e

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