r802: Remove renderframfsclient and renderfarmfsserver .h and .C from Makefile.am...
[cinelerra_cv/mob.git] / cinelerra / amodule.C
blob60684da423241e1e09e4f4938a4efbda388e362a
1 #include "aattachmentpoint.h"
2 #include "aedit.h"
3 #include "amodule.h"
4 #include "aplugin.h"
5 #include "arender.h"
6 #include "asset.h"
7 #include "atrack.h"
8 #include "bcsignals.h"
9 #include "cache.h"
10 #include "edits.h"
11 #include "edl.h"
12 #include "edlsession.h"
13 #include "file.h"
14 #include "filexml.h"
15 #include "floatautos.h"
16 #include "language.h"
17 #include "module.h"
18 #include "patch.h"
19 #include "plugin.h"
20 #include "pluginarray.h"
21 #include "preferences.h"
22 #include "renderengine.h"
23 #include "mainsession.h"
24 #include "sharedlocation.h"
25 #include "theme.h"
26 #include "transition.h"
27 #include "transportque.h"
28 #include <string.h>
32 AModule::AModule(RenderEngine *renderengine, 
33         CommonRender *commonrender, 
34         PluginArray *plugin_array,
35         Track *track)
36  : Module(renderengine, commonrender, plugin_array, track)
38         data_type = TRACK_AUDIO;
39         transition_temp = 0;
40         transition_temp_alloc = 0;
41         level_history = 0;
42         current_level = 0;
48 AModule::~AModule()
50         if(transition_temp) delete [] transition_temp;
51         if(level_history)
52         {
53                 delete [] level_history;
54                 delete [] level_samples;
55         }
58 AttachmentPoint* AModule::new_attachment(Plugin *plugin)
60         return new AAttachmentPoint(renderengine, plugin);
64 void AModule::create_objects()
66         Module::create_objects();
67 // Not needed in pluginarray
68         if(commonrender)
69         {
70                 level_history = new double[((ARender*)commonrender)->total_peaks];
71                 level_samples = new int64_t[((ARender*)commonrender)->total_peaks];
72                 current_level = 0;
74                 for(int i = 0; i < ((ARender*)commonrender)->total_peaks; i++)
75                 {
76                         level_history[i] = 0;
77                         level_samples[i] = -1;
78                 }
79         }
82 int AModule::get_buffer_size()
84         if(renderengine)
85                 return renderengine->fragment_len;
86         else
87                 return plugin_array->get_bufsize();
90 void AModule::reverse_buffer(double *buffer, int64_t len)
92         int start, end;
93         double temp;
95         for(start = 0, end = len - 1; end > start; start++, end--)
96         {
97                 temp = buffer[start];
98                 buffer[start] = buffer[end];
99                 buffer[end] = temp;
100         }
104 CICache* AModule::get_cache()
106         if(renderengine)
107                 return renderengine->get_acache();
108         else
109                 return cache;
112 int AModule::render(double *buffer, 
113         int64_t input_position,
114         int input_len, 
115         int direction,
116         int sample_rate,
117         int use_nudge)
119         int64_t edl_rate = get_edl()->session->sample_rate;
120         if(use_nudge) 
121                 input_position += track->nudge * 
122                         sample_rate /
123                         edl_rate;
125         AEdit *playable_edit;
126         int64_t start_project = input_position;
127         int64_t end_project = input_position + input_len;
128         int64_t buffer_offset = 0;
129         int result = 0;
132 // Flip range around so start_project < end_project
133         if(direction == PLAY_REVERSE)
134         {
135                 start_project -= input_len;
136                 end_project -= input_len;
137         }
139 SET_TRACE
141 // Clear buffer
142         bzero(buffer, input_len * sizeof(double));
144 SET_TRACE
145 // The EDL is normalized to the requested sample rate because the requested rate may
146 // be the project sample rate and a sample rate 
147 // might as well be directly from the source rate to the requested rate.
148 // Get first edit containing the range
149         for(playable_edit = (AEdit*)track->edits->first; 
150                 playable_edit;
151                 playable_edit = (AEdit*)playable_edit->next)
152         {
153                 int64_t edit_start = playable_edit->startproject;
154                 int64_t edit_end = playable_edit->startproject + playable_edit->length;
155 // Normalize to requested rate
156                 edit_start = edit_start * sample_rate / edl_rate;
157                 edit_end = edit_end * sample_rate / edl_rate;
159                 if(start_project < edit_end && start_project + input_len > edit_start)
160                 {
161                         break;
162                 }
163         }
168 SET_TRACE
172 // Fill output one fragment at a time
173         while(start_project < end_project)
174         {
175 SET_TRACE
176                 int64_t fragment_len = input_len;
179                 if(fragment_len + start_project > end_project)
180                         fragment_len = end_project - start_project;
182 SET_TRACE
183 // Normalize position here since update_transition is a boolean operation.
184                 update_transition(start_project * 
185                                 edl_rate / 
186                                 sample_rate, 
187                         PLAY_FORWARD);
189 SET_TRACE
190                 if(playable_edit)
191                 {
192 // Normalize EDL positions to requested rate
193                         int64_t edit_startproject = playable_edit->startproject;
194                         int64_t edit_endproject = playable_edit->startproject + playable_edit->length;
195                         int64_t edit_startsource = playable_edit->startsource;
196 //printf("AModule::render 52 %lld\n", fragment_len);
198                         edit_startproject = edit_startproject * sample_rate / edl_rate;
199                         edit_endproject = edit_endproject * sample_rate / edl_rate;
200                         edit_startsource = edit_startsource * sample_rate / edl_rate;
201 //printf("AModule::render 53 %lld\n", fragment_len);
205 // Trim fragment_len
206                         if(fragment_len + start_project > edit_endproject)
207                                 fragment_len = edit_endproject - start_project;
208 //printf("AModule::render 56 %lld\n", fragment_len);
210                         if(playable_edit->asset)
211                         {
212                                 File *source;
213                                 get_cache()->age();
217                                 if(!(source = get_cache()->check_out(playable_edit->asset)))
218                                 {
219 // couldn't open source file / skip the edit
220                                         result = 1;
221                                         printf(_("VirtualAConsole::load_track Couldn't open %s.\n"), playable_edit->asset->path);
222                                 }
223                                 else
224                                 {
225                                         int result = 0;
227                                         source->set_channel(playable_edit->channel);
229                                         result = source->set_audio_position(start_project - 
230                                                         edit_startproject + 
231                                                         edit_startsource, 
232                                                 sample_rate);
234 //                                      if(result) printf("AModule::render start_project=%d playable_edit->startproject=%d playable_edit->startsource=%d\n"
235 //                                              "source=%p playable_edit=%p edl=%p edlsession=%p sample_rate=%d\n",
236 //                                              start_project, playable_edit->startproject, playable_edit->startsource, 
237 //                                              source, playable_edit, get_edl(), get_edl()->session, get_edl()->session->sample_rate);
238                                         source->read_samples(buffer + buffer_offset, 
239                                                 fragment_len,
240                                                 sample_rate);
242                                         get_cache()->check_in(playable_edit->asset);
243                                 }
244                         }
248 SET_TRACE
251 // Read transition into temp and render
252                         AEdit *previous_edit = (AEdit*)playable_edit->previous;
253                         if(transition && previous_edit)
254                         {
255                                 int64_t transition_len = transition->length * 
256                                         sample_rate / 
257                                         edl_rate;
258                                 int64_t previous_startproject = previous_edit->startproject *
259                                         sample_rate /
260                                         edl_rate;
261                                 int64_t previous_startsource = previous_edit->startsource *
262                                         sample_rate /
263                                         edl_rate;
265 // Read into temp buffers
266 // Temp + master or temp + temp ? temp + master
267                                 if(transition_temp && transition_temp_alloc < fragment_len)
268                                 {
269                                         delete [] transition_temp;
270                                         transition_temp = 0;
271                                 }
273                                 if(!transition_temp)
274                                 {
275                                         transition_temp = new double[fragment_len];
276                                         transition_temp_alloc = fragment_len;
277                                 }
281 // Trim transition_len
282                                 int transition_fragment_len = fragment_len;
283                                 if(fragment_len + start_project > 
284                                         edit_startproject + transition_len)
285                                         fragment_len = edit_startproject + transition_len - start_project;
286 //printf("AModule::render 54 %lld\n", fragment_len);
288                                 if(transition_fragment_len > 0)
289                                 {
290                                         if(previous_edit->asset)
291                                         {
292                                                 File *source;
293                                                 get_cache()->age();
294                                                 if(!(source = get_cache()->check_out(previous_edit->asset)))
295                                                 {
296 // couldn't open source file / skip the edit
297                                                         printf(_("VirtualAConsole::load_track Couldn't open %s.\n"), playable_edit->asset->path);
298                                                         result = 1;
299                                                 }
300                                                 else
301                                                 {
302                                                         int result = 0;
304                                                         source->set_channel(previous_edit->channel);
306                                                         result = source->set_audio_position(start_project - 
307                                                                         previous_startproject + 
308                                                                         previous_startsource, 
309                                                                 get_edl()->session->sample_rate);
311 //                                                      if(result) printf("AModule::render start_project=%d playable_edit->startproject=%d playable_edit->startsource=%d\n"
312 //                                                              "source=%p playable_edit=%p edl=%p edlsession=%p sample_rate=%d\n",
313 //                                                              start_project, 
314 //                                                              previous_edit->startproject, 
315 //                                                              previous_edit->startsource, 
316 //                                                              source, 
317 //                                                              playable_edit, 
318 //                                                              get_edl(), 
319 //                                                              get_edl()->session, 
320 //                                                              get_edl()->session->sample_rate);
321                                                         source->read_samples(transition_temp, 
322                                                                 transition_fragment_len,
323                                                                 sample_rate);
325                                                         get_cache()->check_in(previous_edit->asset);
326                                                 }
327                                         }
328                                         else
329                                         {
330                                                 bzero(transition_temp, transition_fragment_len * sizeof(double));
331                                         }
333                                         double *output = buffer + buffer_offset;
334                                         transition_server->process_transition(
335                                                 transition_temp,
336                                                 output,
337                                                 start_project - edit_startproject,
338                                                 transition_fragment_len,
339                                                 transition->length);
340                                 }
341                         }
342 SET_TRACE
344                         if(playable_edit && start_project + fragment_len >= edit_endproject)
345                                 playable_edit = (AEdit*)playable_edit->next;
346                 }
348 SET_TRACE
349                 buffer_offset += fragment_len;
350                 start_project += fragment_len;
351         }
354 // Reverse buffer here so plugins always render forward.
355         if(direction == PLAY_REVERSE)
356                 reverse_buffer(buffer, input_len);
358 SET_TRACE
360         return result;