1 #ifndef INCLUDED_ECA_ENGINE_H 2 #define INCLUDED_ECA_ENGINE_H 3 4 #include <vector> 5 #include "sample-specs.h" 6 #include "eca-engine-driver.h" 7 #include "eca-chainsetup-edit.h" 8 9 class AUDIO_IO; 10 class AUDIO_IO_DB_CLIENT; 11 class AUDIO_IO_DEVICE; 12 class CHAIN; 13 class CHAIN_OPERATOR; 14 class ECA_CHAINSETUP; 15 class ECA_ENGINE; 16 class ECA_ENGINE_impl; 17 class SAMPLE_BUFFER; 18 19 /** 20 * Default engine driver 21 */ 22 class ECA_ENGINE_DEFAULT_DRIVER : public ECA_ENGINE_DRIVER { 23 24 public: 25 26 virtual int exec(ECA_ENGINE* engine, ECA_CHAINSETUP* csetup); 27 virtual void start(void); 28 virtual void stop(bool drain = false); 29 virtual void exit(void); 30 31 private: 32 33 ECA_ENGINE* engine_repp; 34 bool exit_request_rep; 35 36 }; 37 38 /** 39 * ECA_ENGINE is the actual processing engine. 40 * It is initialized with a pointer to a 41 * ECA_CHAINSETUP object, which has all information 42 * needed at runtime. In other words ECA_ENGINE is 43 * used to execute the chainsetup. You could say 44 * ECA_ENGINE renders the final product according 45 * to instruction given in ECA_CHAINSETUP. 46 * 47 * In most use cases ECA_ENGINE operation 48 * involves multiple threads. The main thread 49 * contexts are: 50 * 51 * - control context in which 52 * ECA_ENGINE::exec() is executed 53 * 54 * - driver context; depending on the 55 * used driver, this can be either 56 * a separate thread or same as the 57 * control thread 58 * 59 * - external context; other threads 60 * sending commands to the engine 61 * 62 * Notes: This class is closely tied to 63 * ECA_CHAINSETUP. Its private data and 64 * function members can be accessed by 65 * ECA_ENGINE through friend-access. 66 */ 67 class ECA_ENGINE { 68 69 public: 70 71 /** @name Public type definitions and constants */ 72 /*@{*/ 73 74 /** 75 * Engine operation states 76 */ 77 enum Engine_status { engine_status_running, 78 engine_status_stopped, 79 engine_status_finished, 80 engine_status_error, 81 engine_status_notready }; 82 typedef enum Engine_status Engine_status_t; 83 84 /** 85 * Commands used in ECA_ENGINE<->ECA_CONTROL communication. 86 */ 87 enum Engine_command { 88 ep_prepare = 0, 89 ep_start, 90 ep_stop, 91 ep_stop_with_drain, 92 ep_debug, 93 ep_exit, 94 // -- 95 ep_exec_edit, 96 // -- 97 ep_rewind, 98 ep_forward, 99 ep_setpos, 100 ep_setpos_samples, 101 ep_setpos_live_samples, 102 }; 103 typedef enum Engine_command Engine_command_t; 104 105 struct complex_command { 106 Engine_command_t type; 107 union { 108 struct { 109 double value; 110 } engine; 111 112 struct { 113 int chain; 114 int op; 115 int param; 116 double value; 117 } legacy; 118 119 } m; 120 121 ECA::chainsetup_edit_t cs; 122 }; 123 typedef struct complex_command complex_command_t; 124 125 /*@}*/ 126 127 /** @name Public functions */ 128 /*@{*/ 129 130 ECA_ENGINE(ECA_CHAINSETUP* eparam); 131 ~ECA_ENGINE(void); 132 133 int exec(bool batch_mode); 134 void command(Engine_command_t cmd, double arg); 135 void command(complex_command_t ccmd); 136 void wait_for_stop(int timeout); 137 void wait_for_exit(int timeout); 138 139 /*@}*/ 140 141 /** @name Public functions for observing engine status information */ 142 /*@{*/ 143 144 bool is_valid(void) const; 145 bool is_finite_length(void) const; 146 Engine_status_t status(void) const; 147 148 /*@}*/ 149 150 /** @name API for engine driver objects (@see ECA_ENGINE_DRIVER) */ 151 /*@{*/ 152 153 void check_command_queue(void); 154 void wait_for_commands(void); 155 void init_engine_state(void); 156 void update_engine_state(void); 157 void engine_iteration(void); 158 159 void prepare_operation(void); 160 void start_operation(void); 161 void stop_operation(bool drain = false); 162 163 void update_cache_chain_connections(void); 164 void update_cache_latency_values(void); 165 166 bool is_prepared(void) const; 167 bool is_running(void) const; batch_mode(void)168 bool batch_mode(void) const { return(batchmode_enabled_rep); } 169 170 SAMPLE_SPECS::sample_pos_t current_position_in_samples(void) const; 171 double current_position_in_seconds_exact(void) const; 172 connected_chainsetup(void)173 const ECA_CHAINSETUP* connected_chainsetup(void) const { return(csetup_repp); } 174 175 /*@}*/ 176 177 private: 178 179 /** @name Private data and functions */ 180 /*@{*/ 181 182 /** 183 * Number of sample-frames of data is prefilled to 184 * rt-outputs before starting processing. 185 */ 186 static const long int prefill_threshold_constant = 16348; 187 static const int prefill_blocks_constant = 3; 188 189 ECA_ENGINE_impl* impl_repp; 190 191 bool use_midi_rep; 192 bool batchmode_enabled_rep; 193 bool processing_range_set_rep; 194 195 bool prepared_rep; 196 bool running_rep; 197 bool started_rep; 198 bool was_running_rep; 199 bool driver_local; 200 201 bool finished_rep; 202 int outputs_finished_rep; 203 int driver_errors_rep; 204 int inputs_not_finished_rep; 205 206 long int prefill_threshold_rep; 207 long int preroll_samples_rep; 208 long int recording_offset_rep; 209 210 /*@}*/ 211 212 /** @name Pointers to connected chainsetup */ 213 /*@{*/ 214 215 ECA_CHAINSETUP* csetup_repp; 216 ECA_ENGINE_DRIVER* driver_repp; 217 218 std::vector<CHAIN*>* chains_repp; 219 std::vector<AUDIO_IO*>* inputs_repp; 220 std::vector<AUDIO_IO*>* outputs_repp; 221 222 /*@}*/ 223 224 /** @name Audio data buffers */ 225 /*@{*/ 226 227 SAMPLE_BUFFER* mixslot_repp; 228 std::vector<SAMPLE_BUFFER*> cslots_rep; 229 230 /*@}*/ 231 232 /** 233 * @name Various audio object maps. 234 * 235 * The main purpose of these maps is to make 236 * it easier to iterate audio objects with 237 * certain attributes. 238 */ 239 /*@{*/ 240 241 std::vector<AUDIO_IO_DEVICE*> realtime_inputs_rep; 242 std::vector<AUDIO_IO_DEVICE*> realtime_outputs_rep; 243 std::vector<AUDIO_IO_DEVICE*> realtime_objects_rep; 244 std::vector<AUDIO_IO*> non_realtime_inputs_rep; 245 std::vector<AUDIO_IO*> non_realtime_outputs_rep; 246 std::vector<AUDIO_IO*> non_realtime_objects_rep; 247 248 /*@}*/ 249 250 /** @name Cache objects for chainsetup and audio 251 * object information */ 252 /*@{*/ 253 254 std::vector<int> input_chain_count_rep; 255 std::vector<int> output_chain_count_rep; 256 257 /** @name Attribute functions */ 258 /*@{*/ 259 260 long int buffersize(void) const; 261 int max_channels(void) const; 262 263 /*@}*/ 264 265 /** @name Private functions for transport control */ 266 /*@{*/ 267 268 void request_start(void); 269 void request_stop(bool drain = false); 270 void signal_stop(void); 271 void signal_exit(void); 272 void signal_editlock(void); 273 void conditional_start(void); 274 void conditional_stop(void); 275 276 void start_servers(void); 277 void stop_servers(void); 278 279 void prepare_realtime_objects(void); 280 void start_realtime_objects(void); 281 void reset_realtime_devices(void); 282 283 void start_forked_objects(void); 284 void stop_forked_objects(void); 285 286 void state_change_to_finished(void); 287 288 /*@}*/ 289 290 /** @name Private functions for observing and modifying position */ 291 /*@{*/ 292 293 void set_position(double seconds); set_position(int seconds)294 void set_position(int seconds) { set_position((double)seconds); } 295 void set_position_samples(SAMPLE_SPECS::sample_pos_t samples); 296 void set_position_samples_live(SAMPLE_SPECS::sample_pos_t samples); 297 void change_position(double seconds); 298 299 void prehandle_control_position(void); 300 void posthandle_control_position(void); 301 302 /*@}*/ 303 304 /** @name Private functions for command queue handling */ 305 /*@{*/ 306 307 void interpret_queue(void); 308 309 /*@}*/ 310 311 /** @name Private functions for setup and cleanup */ 312 /*@{*/ 313 314 void init_variables(void); 315 void init_connection_to_chainsetup(void); 316 void init_driver(void); 317 void init_prefill(void); 318 void init_servers(void); 319 void init_chains(void); 320 void cleanup(void); 321 322 void reinit_chains(bool force = false); 323 324 void create_cache_object_lists(void); 325 326 void init_profiling(void); 327 void dump_profile_info(void); 328 329 /*@}*/ 330 331 /** @name Private functions for signal routing */ 332 /*@{*/ 333 334 void inputs_to_chains(void); 335 void process_chains(void); 336 void mix_to_outputs(bool skip_realtime_target_outputs); 337 338 /*@}*/ 339 340 /** @name Hidden/unimplemented functions */ 341 /*@{*/ 342 343 ECA_ENGINE& operator=(const ECA_ENGINE& x) { return *this; } 344 345 /*@}*/ 346 }; 347 348 #endif 349