bbfe590670fa156d773782f1ae3816f2a3a6187b
[goodguy/history.git] / cinelerra-5.1 / cinelerra / arender.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2009 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "amodule.h"
23 #include "arender.h"
24 #include "atrack.h"
25 #include "audiodevice.h"
26 #include "auto.h"
27 #include "autos.h"
28 #include "bcsignals.h"
29 #include "cache.h"
30 #include "condition.h"
31 #include "edit.h"
32 #include "edl.h"
33 #include "edlsession.h"
34 #include "levelwindow.h"
35 #include "mainsession.h"
36 #include "playabletracks.h"
37 #include "playbackengine.h"
38 #include "preferences.h"
39 #include "renderengine.h"
40 #include "samples.h"
41 #include "tracks.h"
42 #include "transportque.h"
43 #include "virtualaconsole.h"
44 #include "virtualconsole.h"
45 #include "virtualnode.h"
46
47 ARender::ARender(RenderEngine *renderengine)
48  : CommonRender(renderengine)
49 {
50 // Clear output buffers
51         for(int i = 0; i < MAXCHANNELS; i++)
52         {
53                 buffer[i] = 0;
54                 audio_out[i] = 0;
55                 buffer_allocated[i] = 0;
56                 level_history[i] = 0;
57         }
58         level_samples = 0;
59         total_peaks = 0;
60
61         data_type = TRACK_AUDIO;
62 }
63
64 ARender::~ARender()
65 {
66         for(int i = 0; i < MAXCHANNELS; i++)
67         {
68                 if(buffer[i]) delete buffer[i];
69                 if(level_history[i]) delete [] level_history[i];
70         }
71         if(level_samples) delete [] level_samples;
72 }
73
74 void ARender::arm_command()
75 {
76 // Need the meter history now so AModule can allocate its own history
77         calculate_history_size();
78         CommonRender::arm_command();
79         asynchronous = 1;
80         init_meters();
81 }
82
83
84 int ARender::get_total_tracks()
85 {
86         return renderengine->get_edl()->tracks->total_audio_tracks();
87 }
88
89 Module* ARender::new_module(Track *track)
90 {
91         return new AModule(renderengine, this, 0, track);
92 }
93
94 int ARender::calculate_history_size()
95 {
96         if(total_peaks > 0)
97                 return total_peaks;
98         else
99         {
100                 meter_render_fragment = renderengine->fragment_len;
101 // This number and the timer in tracking.C determine the rate
102                 while(meter_render_fragment >
103                         renderengine->get_edl()->session->sample_rate / TRACKING_RATE)
104                         meter_render_fragment /= 2;
105                 total_peaks = 16 *
106                         renderengine->fragment_len /
107                         meter_render_fragment;
108                 return total_peaks;
109         }
110 }
111
112 int ARender::init_meters()
113 {
114 // not providing enough peaks results in peaks that are ahead of the sound
115         if(level_samples) delete [] level_samples;
116         calculate_history_size();
117         level_samples = new int64_t[total_peaks];
118
119         for(int i = 0; i < MAXCHANNELS;i++)
120         {
121                 current_level[i] = 0;
122                 if(buffer[i] && !level_history[i])
123                         level_history[i] = new double[total_peaks];
124         }
125
126         for(int i = 0; i < total_peaks; i++)
127         {
128                 level_samples[i] = -1;
129         }
130
131         for(int j = 0; j < MAXCHANNELS; j++)
132         {
133                 if(buffer[j])
134                         for(int i = 0; i < total_peaks; i++)
135                                 level_history[j][i] = 0;
136         }
137         return 0;
138 }
139
140 void ARender::allocate_buffers(int samples)
141 {
142         for(int i = 0; i < MAXCHANNELS; i++)
143         {
144 // Reset the output buffers in case speed changed
145                 if(buffer_allocated[i] < samples)
146                 {
147                         delete buffer[i];
148                         buffer[i] = 0;
149                 }
150
151                 if(i < renderengine->get_edl()->session->audio_channels)
152                 {
153                         buffer[i] = new Samples(samples);
154                         buffer_allocated[i] = samples;
155                         audio_out[i] = buffer[i];
156                 }
157         }
158 }
159
160 void ARender::init_output_buffers()
161 {
162         allocate_buffers(renderengine->adjusted_fragment_len);
163 }
164
165
166 VirtualConsole* ARender::new_vconsole_object()
167 {
168         return new VirtualAConsole(renderengine, this);
169 }
170
171 int64_t ARender::tounits(double position, int round)
172 {
173         if(round)
174                 return Units::round(position * renderengine->get_edl()->session->sample_rate);
175         else
176                 return (int64_t)(position * renderengine->get_edl()->session->sample_rate);
177 }
178
179 double ARender::fromunits(int64_t position)
180 {
181         return (double)position / renderengine->get_edl()->session->sample_rate;
182 }
183
184
185 int ARender::process_buffer(Samples **buffer_out,
186         int64_t input_len,
187         int64_t input_position)
188 {
189         int result = 0;
190
191         int64_t fragment_position = 0;
192         int64_t fragment_len = input_len;
193         int reconfigure = 0;
194         current_position = input_position;
195
196 // Process in fragments
197         int start_offset = buffer_out[0]->get_offset();
198         while(fragment_position < input_len)
199         {
200 // Set pointers for destination data
201                 for(int i = 0; i < MAXCHANNELS; i++)
202                 {
203                         if(buffer_out[i])
204                         {
205                                 this->audio_out[i] = buffer_out[i];
206                                 this->audio_out[i]->set_offset(start_offset + fragment_position);
207                         }
208                         else
209                                 this->audio_out[i] = 0;
210                 }
211
212                 fragment_len = input_len;
213                 if(fragment_position + fragment_len > input_len)
214                         fragment_len = input_len - fragment_position;
215
216                 reconfigure = vconsole->test_reconfigure(input_position,
217                         fragment_len);
218
219 //printf("ARender::process_buffer 1 %jd %d\n", input_position, reconfigure);
220
221                 if(reconfigure) restart_playback();
222
223                 result = process_buffer(fragment_len, input_position);
224
225                 fragment_position += fragment_len;
226                 input_position += fragment_len;
227                 current_position = input_position;
228         }
229
230 // Reset offsets
231         for(int i = 0; i < MAXCHANNELS; i++)
232         {
233                 if(buffer_out[i]) buffer_out[i]->set_offset(start_offset);
234         }
235
236
237
238         return result;
239 }
240
241
242 int ARender::process_buffer(int64_t input_len, int64_t input_position)
243 {
244         int result = ((VirtualAConsole*)vconsole)->process_buffer(input_len,
245                 input_position);
246         return result;
247 }
248
249 int ARender::get_history_number(int64_t *table, int64_t position)
250 {
251 // Get the entry closest to position
252         int result = 0;
253         int64_t min_difference = 0x7fffffff;
254         for(int i = 0; i < total_peaks; i++)
255         {
256
257 //printf("%jd ", table[i]);
258                 if(labs(table[i] - position) < min_difference)
259                 {
260                         min_difference = labs(table[i] - position);
261                         result = i;
262                 }
263         }
264 //printf("\n");
265 //printf("ARender::get_history_number %jd %d\n", position, result);
266         return result;
267 }
268
269 void ARender::send_last_buffer()
270 {
271         if( renderengine->audio )
272                 renderengine->audio->set_last_buffer();
273 }
274
275 int ARender::stop_audio(int wait)
276 {
277         if( renderengine->audio )
278                 renderengine->audio->stop_audio(wait);
279         return 0;
280 }
281
282 void ARender::interrupt_playback()
283 {
284 //printf("ARender::interrupt_playback\n");
285         interrupt = 1;
286         if( renderengine->audio )
287                 renderengine->audio->interrupt_playback();
288 }
289
290 void ARender::run()
291 {
292         int64_t current_input_length;
293         int reconfigure = 0;
294 const int debug = 0;
295
296         first_buffer = 1;
297
298         start_lock->unlock();
299 if(debug) printf("ARender::run %d %d\n", __LINE__, Thread::calculate_realtime());
300
301         while(!done && !interrupt)
302         {
303                 float speed = renderengine->command->get_speed();
304                 current_input_length = (int64_t)(renderengine->fragment_len * speed +0.5) ;
305
306 if(debug) printf("ARender::run %d %jd %jd\n", __LINE__, current_position, current_input_length);
307                 get_boundaries(current_input_length);
308
309 if(debug) printf("ARender::run %d %jd %jd\n", __LINE__, current_position, current_input_length);
310                 if(current_input_length)
311                 {
312                         reconfigure = vconsole->test_reconfigure(current_position,
313                                 current_input_length);
314                         if(reconfigure) restart_playback();
315                 }
316 if(debug) printf("ARender::run %d %jd %jd\n", __LINE__, current_position, current_input_length);
317
318
319 // Update tracking if no video is playing.
320                 if(renderengine->command->realtime &&
321                         renderengine->playback_engine &&
322                         !renderengine->do_video)
323                 {
324                         double position = (double)renderengine->audio->current_position() /
325                                 renderengine->get_edl()->session->sample_rate * speed;
326
327                         if(renderengine->command->get_direction() == PLAY_FORWARD)
328                                 position += renderengine->command->playbackstart;
329                         else
330                                 position = renderengine->command->playbackstart - position;
331
332 // This number is not compensated for looping.  It's compensated in
333 // PlaybackEngine::get_tracking_position when interpolation also happens.
334                         renderengine->playback_engine->update_tracking(position);
335                 }
336
337
338 if(debug) printf("ARender::run %d %jd\n", __LINE__, current_input_length);
339
340
341
342                 process_buffer(current_input_length, current_position);
343 if(debug) printf("ARender::run %d\n", __LINE__);
344
345
346                 advance_position(current_input_length);
347 if(debug) printf("ARender::run %d\n", __LINE__);
348
349
350                 if(vconsole->interrupt) interrupt = 1;
351         }
352
353 if(debug) printf("ARender::run %d\n", __LINE__);
354         if(!interrupt) send_last_buffer();
355         if(renderengine->command->realtime)
356                 stop_audio(interrupt ? 0 : 1);
357         vconsole->stop_rendering(0);
358         stop_plugins();
359 }
360
361
362 int ARender::get_next_peak(int current_peak)
363 {
364         current_peak++;
365         if(current_peak >= total_peaks) current_peak = 0;
366         return current_peak;
367 }
368
369