r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / amodule.C
blobbae07a34bd0425ec4a1131b65193ca1fb8bd0e40
1 #include "aattachmentpoint.h"
2 #include "aedit.h"
3 #include "amodule.h"
4 #include "aplugin.h"
5 #include "arender.h"
6 #include "assets.h"
7 #include "atrack.h"
8 #include "cache.h"
9 #include "edits.h"
10 #include "edl.h"
11 #include "edlsession.h"
12 #include "file.h"
13 #include "filexml.h"
14 #include "floatautos.h"
15 #include "module.h"
16 #include "patch.h"
17 #include "plugin.h"
18 #include "preferences.h"
19 #include "renderengine.h"
20 #include "mainsession.h"
21 #include "sharedlocation.h"
22 #include "theme.h"
23 #include "transition.h"
24 #include "transportque.h"
25 #include <string.h>
27 #include <libintl.h>
28 #define _(String) gettext(String)
29 #define gettext_noop(String) String
30 #define N_(String) gettext_noop (String)
33 AModule::AModule(RenderEngine *renderengine, 
34         CommonRender *commonrender, 
35         PluginArray *plugin_array,
36         Track *track)
37  : Module(renderengine, commonrender, plugin_array, track)
39         data_type = TRACK_AUDIO;
40         transition_temp = 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)->history_size()];
71                 level_samples = new int64_t[((ARender*)commonrender)->history_size()];
72                 current_level = 0;
74                 for(int i = 0; i < ((ARender*)commonrender)->history_size(); i++)
75                 {
76                         level_history[i] = 0;
77                         level_samples[i] = -1;
78                 }
79         }
82 int AModule::get_buffer_size()
84 //printf("AModule::get_buffer_size 1 %p\n", get_edl());
85         return get_edl()->session->audio_module_fragment;
88 void AModule::reverse_buffer(double *buffer, int64_t len)
90         register int64_t start, end;
91         double temp;
93         for(start = 0, end = len - 1; end > start; start++, end--)
94         {
95                 temp = buffer[start];
96                 buffer[start] = buffer[end];
97                 buffer[end] = temp;
98         }
102 CICache* AModule::get_cache()
104         if(renderengine) 
105                 return renderengine->get_acache();
106         else
107                 return cache;
110 int AModule::render(double *buffer, 
111         int64_t input_len, 
112         int64_t input_position,
113         int direction)
115         AEdit *playable_edit;
116         int64_t start_project = input_position;
117         int64_t end_project = input_position + input_len;
118         int64_t buffer_offset = 0;
119         int result = 0;
122 //printf("AModule::render 1 %d %d\n", input_position, input_len);
124 // Flip range around so start_project < end_project
125         if(direction == PLAY_REVERSE)
126         {
127                 start_project -= input_len;
128                 end_project -= input_len;
129         }
131         bzero(buffer, input_len * sizeof(double));
133 //printf("AModule::render 2\n");
135 // Get first edit containing range
136         for(playable_edit = (AEdit*)track->edits->first; 
137                 playable_edit;
138                 playable_edit = (AEdit*)playable_edit->next)
139         {
140                 double edit_start = playable_edit->startproject;
141                 double edit_end = playable_edit->startproject + playable_edit->length;
143                 if(start_project < edit_end && start_project + input_len > edit_start)
144                 {
145                         break;
146                 }
147         }
153 //printf("AModule::render 3\n");
156 // Fill output one fragment at a time
157         while(start_project < end_project)
158         {
159                 int64_t fragment_len = input_len;
161 //printf("AModule::render 4 %d\n", fragment_len);
162                 if(fragment_len + start_project > end_project)
163                         fragment_len = end_project - start_project;
165 //printf("AModule::render 5 %d\n", fragment_len);
166                 update_transition(start_project, PLAY_FORWARD);
169                 if(playable_edit)
170                 {
171 //printf("AModule::render 6\n");
174 // Trim fragment_len
175                         if(fragment_len + start_project > 
176                                 playable_edit->startproject + playable_edit->length)
177                                 fragment_len = playable_edit->startproject + 
178                                         playable_edit->length - start_project;
180 //printf("AModule::render 8 %d\n", fragment_len);
182                         if(playable_edit->asset)
183                         {
184                                 File *source;
186 //printf("AModule::render 9\n");
189                                 if(!(source = get_cache()->check_out(playable_edit->asset)))
190                                 {
191 // couldn't open source file / skip the edit
192                                         result = 1;
193                                         printf(_("VirtualAConsole::load_track Couldn't open %s.\n"), playable_edit->asset->path);
194                                 }
195                                 else
196                                 {
197                                         int result = 0;
199 //printf("AModule::render 10\n");
201 //printf("AModule::load_track 7 %d\n", start_project - 
202 //                                                      playable_edit->startproject + 
203 //                                                      playable_edit->startsource);
205                                         result = source->set_audio_position(start_project - 
206                                                         playable_edit->startproject + 
207                                                         playable_edit->startsource, 
208                                                 get_edl()->session->sample_rate);
209 //printf("AModule::render 10\n");
211                                         if(result) printf("AModule::render start_project=%d playable_edit->startproject=%d playable_edit->startsource=%d\n"
212                                                 "source=%p playable_edit=%p edl=%p edlsession=%p sample_rate=%d\n",
213                                                 start_project, playable_edit->startproject, playable_edit->startsource, 
214                                                 source, playable_edit, get_edl(), get_edl()->session, get_edl()->session->sample_rate);
216                                         source->set_channel(playable_edit->channel);
218 // printf("AModule::render 11 %p %p %d %d\n", 
219 //      source, 
220 //      buffer, 
221 //      buffer_offset, 
222 //      fragment_len);
223 //printf("AModule::render 10 %p %p\n", source, playable_edit);
224                                         source->read_samples(buffer + buffer_offset, 
225                                                 fragment_len,
226                                                 get_edl()->session->sample_rate);
228 //printf("AModule::render 12 %d %d\n", fragment_len, get_edl()->session->sample_rate);
229                                         get_cache()->check_in(playable_edit->asset);
230 //printf("AModule::render 13\n");
231                                 }
232                         }
239 // Read transition into temp and render
240                         AEdit *previous_edit = (AEdit*)playable_edit->previous;
241                         if(transition && previous_edit)
242                         {
244 // Read into temp buffers
245 // Temp + master or temp + temp ? temp + master
246                                 if(!transition_temp)
247                                 {
248                                         transition_temp = new double[get_edl()->session->audio_read_length];
249                                 }
253 // Trim transition_len
254                                 int transition_len = fragment_len;
255                                 if(fragment_len + start_project > 
256                                         playable_edit->startproject + transition->length)
257                                         fragment_len = playable_edit->startproject + 
258                                                 playable_edit->transition->length - 
259                                                 start_project;
261                                 if(transition_len > 0)
262                                 {
263                                         if(previous_edit->asset)
264                                         {
265                                                 File *source;
266                                                 if(!(source = get_cache()->check_out(previous_edit->asset)))
267                                                 {
268 // couldn't open source file / skip the edit
269                                                         printf(_("VirtualAConsole::load_track Couldn't open %s.\n"), playable_edit->asset->path);
270                                                         result = 1;
271                                                 }
272                                                 else
273                                                 {
274                                                         int result = 0;
276                                                         result = source->set_audio_position(start_project - 
277                                                                         previous_edit->startproject + 
278                                                                         previous_edit->startsource, 
279                                                                 get_edl()->session->sample_rate);
281                                                         if(result) printf("AModule::render start_project=%d playable_edit->startproject=%d playable_edit->startsource=%d\n"
282                                                                 "source=%p playable_edit=%p edl=%p edlsession=%p sample_rate=%d\n",
283                                                                 start_project, 
284                                                                 previous_edit->startproject, 
285                                                                 previous_edit->startsource, 
286                                                                 source, 
287                                                                 playable_edit, 
288                                                                 get_edl(), 
289                                                                 get_edl()->session, 
290                                                                 get_edl()->session->sample_rate);
292                                                         source->set_channel(previous_edit->channel);
294                                                         source->read_samples(transition_temp, 
295                                                                 transition_len,
296                                                                 get_edl()->session->sample_rate);
298                                                         get_cache()->check_in(previous_edit->asset);
299                                                 }
300                                         }
301                                         else
302                                         {
303                                                 bzero(transition_temp, transition_len * sizeof(double));
304                                         }
306                                         double *output = buffer + buffer_offset;
307                                         transition_server->process_realtime(
308                                                 &transition_temp,
309                                                 &output,
310                                                 start_project - playable_edit->startproject,
311                                                 transition_len,
312                                                 transition->length);
313                                 }
314                         }
315                 }
317 //printf("AModule::render 13\n");
318                 buffer_offset += fragment_len;
319                 start_project += fragment_len;
320                 if(playable_edit &&
321                         start_project >= playable_edit->startproject + playable_edit->length)
322                         playable_edit = (AEdit*)playable_edit->next;
323         }
325 //printf("AModule::render 14\n");
327 // Reverse buffer here so plugins always render forward.
328         if(direction == PLAY_REVERSE) 
329                 reverse_buffer(buffer, input_len);
331 //printf("AModule::render 15\n");
332         return result;