r827: Fix a crash when no audio output device can be opened.
[cinelerra_cv.git] / cinelerra / module.C
blobe44feee09cf5bc727b3ac7dafffd4fa4c201ff9d
1 #include "attachmentpoint.h"
2 #include "bcsignals.h"
3 #include "commonrender.h"
4 #include "edl.h"
5 #include "edlsession.h"
6 #include "filexml.h"
7 #include "module.h"
8 #include "mwindow.h"
9 #include "patch.h"
10 #include "patchbay.h"
11 #include "plugin.h"
12 #include "pluginarray.h"
13 #include "pluginserver.h"
14 #include "renderengine.h"
15 #include "sharedlocation.h"
16 #include "track.h"
17 #include "tracks.h"
18 #include "transportque.h"
21 Module::Module(RenderEngine *renderengine, 
22         CommonRender *commonrender, 
23         PluginArray *plugin_array,
24         Track *track)
26         this->renderengine = renderengine;
27         this->commonrender = commonrender;
28         this->plugin_array = plugin_array;
29         this->track = track;
30         transition = 0;
31         transition_server = 0;
32         attachments = 0;
33         total_attachments = 0;
34         new_total_attachments = 0;
35         new_attachments = 0;
38 Module::~Module()
40         if(attachments)
41         {
42                 for(int i = 0; i < track->plugin_set.total; i++)
43                 {
44                         if(attachments[i])
45                         {
46 // For some reason it isn't used here.
47 //                              attachments[i]->render_stop(0);
48                                 delete attachments[i];
49                         }
50                 }
51                 delete [] attachments;
52         }
53         if(transition_server)
54         {
55                 transition_server->close_plugin();
56                 delete transition_server;
57         }
60 void Module::create_objects()
62         create_new_attachments();
63         swap_attachments();
66 EDL* Module::get_edl()
68         if(renderengine) 
69                 return renderengine->edl;
70         else
71                 return edl;
74 void Module::create_new_attachments()
76 // Not used in pluginarray
77         if(commonrender)
78         {
79                 new_total_attachments = track->plugin_set.total;
80                 if(new_total_attachments)
81                 {
82                         new_attachments = new AttachmentPoint*[new_total_attachments];
83                         for(int i = 0; i < new_total_attachments; i++)
84                         {
85                                 Plugin *plugin = 
86                                         track->get_current_plugin(commonrender->current_position, 
87                                                 i, 
88                                                 renderengine->command->get_direction(),
89                                                 0,
90                                                 1);
92                                 if(plugin && plugin->plugin_type != PLUGIN_NONE && plugin->on)
93                                         new_attachments[i] = new_attachment(plugin);
94                                 else
95                                         new_attachments[i] = 0;
96                         }
97                 }
98                 else
99                         new_attachments = 0;
101 // Create plugin servers in virtual console expansion
102         }
105 void Module::swap_attachments()
107 // None of this is used in a pluginarray
108         for(int i = 0; 
109                 i < new_total_attachments &&
110                 i < total_attachments; 
111                 i++)
112         {
113 // Delete new attachment which is identical to the old one and copy
114 // old attachment.
115                 if(new_attachments[i] &&
116                         attachments[i] &&
117                         new_attachments[i]->identical(attachments[i]))
118                 {
119                         delete new_attachments[i];
120                         new_attachments[i] = attachments[i];
121                         attachments[i] = 0;
122                 }
123         }
125 // Delete old attachments which weren't identical to new ones
126         for(int i = 0; i < total_attachments; i++)
127         {
128                 if(attachments[i]) delete attachments[i];
129         }
131         if(attachments)
132         {
133                 delete [] attachments;
134         }
136         attachments = new_attachments;
137         total_attachments = new_total_attachments;
140 int Module::render_init()
142         for(int i = 0; i < total_attachments; i++)
143         {
144                 if(attachments[i])
145                         attachments[i]->render_init();
146         }
148         return 0;
151 AttachmentPoint* Module::attachment_of(Plugin *plugin)
153 //printf("Module::attachment_of 1 %d\n", total_attachments);
154         for(int i = 0; i < total_attachments; i++)
155         {
156 //printf("Module::attachment_of 2 %p\n", attachments[i]);
157                 if(attachments[i] && 
158                         attachments[i]->plugin == plugin) return attachments[i];
159         }
160         return 0;
163 AttachmentPoint* Module::get_attachment(int number)
165         if(number < total_attachments)
166                 return attachments[number];
167         else
168                 return 0;
171 void Module::reset_attachments()
173 //printf("Module::reset_attachments 1 %d\n", total_attachments);
174         for(int i = 0; i < total_attachments; i++)
175         {
176 //printf("Module::reset_attachments 2 %p\n", attachments[i]);
177                 AttachmentPoint *attachment = attachments[i];
178                 if(attachment) attachment->reset_status();
179         }
182 // Test plugins for reconfiguration.
183 // Used in playback
184 int Module::test_plugins()
186         if(total_attachments != track->plugin_set.total) return 1;
188         for(int i = 0; i < total_attachments; i++)
189         {
190                 AttachmentPoint *attachment = attachments[i];
191                 Plugin *plugin = track->get_current_plugin(
192                         commonrender->current_position, 
193                         i, 
194                         renderengine->command->get_direction(),
195                         0,
196                         1);
197 // One exists and one doesn't
198                 int use_plugin = plugin &&
199                         plugin->plugin_type != PLUGIN_NONE &&
200                         plugin->on;
202                 if((attachment && !use_plugin) || 
203                         (!attachment && use_plugin)) return 1;
205 // Plugin not the same
206                 if(plugin && 
207                         attachment &&
208                         attachment->plugin && 
209                         !plugin->identical(attachment->plugin)) return 1;
210         }
212         return 0;
215 void Module::update_transition(int64_t current_position, 
216         int direction)
218 SET_TRACE
219         transition = track->get_current_transition(current_position, 
220                 direction,
221                 0,
222                 0); // position is already nudged in amodule.C and vmodule.C before calling update_transition!
224 SET_TRACE
225 // for situations where we had transition and have no more, we keep the server open:
226 // maybe the same transition will follow and we won't need to reinit... (happens a lot while scrubbing over transitions left and right)
227 //      if((prev_transition && !transition) ||
228         if ((transition && transition_server && strcmp(transition->title, transition_server->plugin->title)))
229         {
230                 transition_server->close_plugin();
231                 delete transition_server;
232                 transition_server = 0;
233         }
234 SET_TRACE
236         if(transition && !transition_server)
237         {
238 SET_TRACE
240                 if(renderengine)
241                 {
242                         PluginServer *plugin_server = renderengine->scan_plugindb(transition->title,
243                                 track->data_type);
244                         transition_server = new PluginServer(*plugin_server);
245                         transition_server->open_plugin(0, 
246                                 renderengine->preferences, 
247                                 get_edl(), 
248                                 transition,
249                                 -1);
250                         transition_server->init_realtime(
251                                 get_edl()->session->real_time_playback &&
252                                 renderengine->command->realtime,
253                                 1,
254                                 get_buffer_size());
255                 }
256                 else
257                 if(plugin_array)
258                 {
259 SET_TRACE
260                         PluginServer *plugin_server = plugin_array->scan_plugindb(transition->title);
261 SET_TRACE
262                         transition_server = new PluginServer(*plugin_server);
263 SET_TRACE
264                         transition_server->open_plugin(0, 
265                                 plugin_array->mwindow->preferences,
266                                 get_edl(), 
267                                 transition,
268                                 -1);
269 SET_TRACE
270                         transition_server->init_realtime(
271                                 0,
272                                 1,
273                                 get_buffer_size());
274 SET_TRACE
275                 }
276         }
280 void Module::dump()
282         printf("  Module title=%s\n", track->title);
283         printf("   Plugins total_attachments=%d\n", total_attachments);
284         for(int i = 0; i < total_attachments; i++)
285         {
286                 attachments[i]->dump();
287         }