4 * Copyright (C) 2009-2013 Adam Williams <broadcast at earthling dot net>
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.
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.
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
22 #include "aattachmentpoint.h"
29 #include "automation.h"
30 #include "bcsignals.h"
35 #include "edlsession.h"
38 #include "floatautos.h"
44 #include "pluginarray.h"
45 #include "preferences.h"
46 #include "renderengine.h"
47 #include "mainsession.h"
49 #include "sharedlocation.h"
51 #include "transition.h"
52 #include "transportque.h"
62 AModuleResample::AModuleResample(AModule *module)
65 this->module = module;
66 bzero(nested_output, sizeof(Samples*) * MAX_CHANNELS);
67 nested_allocation = 0;
70 AModuleResample::~AModuleResample()
72 for(int i = 0; i < MAX_CHANNELS; i++)
73 delete nested_output[i];
76 int AModuleResample::read_samples(Samples *buffer, int64_t start, int64_t len)
83 // Files only read going forward.
84 if(get_direction() == PLAY_REVERSE)
89 //printf("AModuleResample::read_samples start=" _LD " len=" _LD "\n", start, len);
90 module->file->set_audio_position(start);
91 module->file->set_channel(module->channel);
92 result = module->file->read_samples(buffer, len);
94 // Reverse buffer so resampling filter renders forward.
95 if(get_direction() == PLAY_REVERSE)
96 Resample::reverse_buffer(buffer->get_data(), len);
99 if(module->nested_edl)
103 // Nested EDL generates reversed buffer.
104 for(int i = 0; i < module->nested_edl->session->audio_channels; i++)
106 if(nested_allocation < len)
108 delete nested_output[i];
109 nested_output[i] = 0;
112 if(!nested_output[i])
114 nested_output[i] = new Samples(len);
119 result = module->nested_renderengine->arender->process_buffer(
123 // printf("AModuleResample::read_samples buffer=%p module=%p len=%d\n",
127 memcpy(buffer->get_data(),
128 nested_output[module->channel]->get_data(),
129 len * sizeof(double));
145 AModule::AModule(RenderEngine *renderengine,
146 CommonRender *commonrender,
147 PluginArray *plugin_array,
149 : Module(renderengine, commonrender, plugin_array, track)
151 data_type = TRACK_AUDIO;
156 bzero(nested_output, sizeof(Samples*) * MAX_CHANNELS);
157 bzero(prev_head, SPEED_OVERLAP * sizeof(double));
158 bzero(prev_tail, SPEED_OVERLAP * sizeof(double));
159 nested_allocation = 0;
170 if(transition_temp) delete transition_temp;
171 if(speed_temp) delete speed_temp;
174 delete [] level_history;
175 delete [] level_samples;
178 for(int i = 0; i < MAX_CHANNELS; i++)
182 delete nested_output[i];
189 AttachmentPoint* AModule::new_attachment(Plugin *plugin)
191 return new AAttachmentPoint(renderengine, plugin);
195 void AModule::create_objects()
197 Module::create_objects();
198 // Not needed in pluginarray
201 level_history = new double[((ARender*)commonrender)->total_peaks];
202 level_samples = new int64_t[((ARender*)commonrender)->total_peaks];
205 for(int i = 0; i < ((ARender*)commonrender)->total_peaks; i++)
207 level_history[i] = 0;
208 level_samples[i] = -1;
213 int AModule::get_buffer_size()
216 return renderengine->fragment_len;
218 return plugin_array->get_bufsize();
222 CICache* AModule::get_cache()
225 return renderengine->get_acache();
231 int AModule::import_samples(AEdit *edit,
232 int64_t start_project,
233 int64_t edit_startproject,
234 int64_t edit_startsource,
238 int64_t fragment_len)
241 // start in EDL samplerate
242 int64_t start_source = start_project -
245 // fragment size adjusted for speed curve
246 int64_t speed_fragment_len = fragment_len;
247 // boundaries of input fragment required for speed curve
248 double max_position = 0;
249 double min_position = 0;
251 double speed_position = edit_startsource;
252 // position in source where speed curve starts reading
253 double speed_position1 = speed_position;
254 // position in source where speed curve finishes
255 double speed_position2 = speed_position;
257 // Need speed curve processing
259 // Temporary buffer for rendering speed curve
260 Samples *speed_buffer = buffer;
263 if(debug) printf("AModule::import_samples %d edit=%p nested_edl=%p\n",
267 if(nested_edl && edit->channel >= nested_edl->session->audio_channels)
269 if(debug) printf("AModule::import_samples %d\n", __LINE__);
271 this->channel = edit->channel;
272 if(debug) printf("AModule::import_samples %d speed_fragment_len=%ld\n",
279 // apply speed curve to source position so the timeline agrees with the playback
280 if(track->has_speed())
282 // get speed adjusted position from start of edit.
283 FloatAuto *previous = 0;
285 FloatAutos *speed_autos = (FloatAutos*)track->automation->autos[AUTOMATION_SPEED];
286 for(int64_t i = edit_startproject; i < start_project; i++)
288 double speed = speed_autos->get_value(i,
292 speed_position += speed;
295 speed_position1 = speed_position;
298 // calculate boundaries of input fragment required for speed curve
299 max_position = speed_position;
300 min_position = speed_position;
301 for(int64_t i = start_project; i < start_project + fragment_len; i++)
303 double speed = speed_autos->get_value(i,
307 speed_position += speed;
308 if(speed_position > max_position) max_position = speed_position;
309 if(speed_position < min_position) min_position = speed_position;
312 speed_position2 = speed_position;
313 if(speed_position2 < speed_position1)
316 // min_position -= 1.0;
317 speed_fragment_len = (int64_t)(max_position - min_position);
322 speed_fragment_len = (int64_t)(max_position - min_position);
325 printf("AModule::import_samples %d %f %f %f %f\n",
332 // new start of source to read from file
333 start_source = (int64_t)min_position;
338 // swap in the temp buffer
339 if(speed_temp && speed_temp->get_allocated() < speed_fragment_len)
347 speed_temp = new Samples(speed_fragment_len);
350 speed_buffer = speed_temp;
355 if(speed_fragment_len == 0)
360 // Source is a nested EDL
366 if(direction == PLAY_REVERSE)
367 command = NORMAL_REWIND;
369 command = NORMAL_FWD;
371 if(debug) printf("AModule::import_samples %d\n", __LINE__);
372 if(!nested_edl || nested_edl->id != edit->nested_edl->id)
374 nested_edl = edit->nested_edl;
375 if(nested_renderengine)
377 delete nested_renderengine;
378 nested_renderengine = 0;
383 nested_command = new TransportCommand;
387 if(!nested_renderengine)
389 nested_command->command = command;
390 nested_command->get_edl()->copy_all(nested_edl);
391 nested_command->change_type = CHANGE_ALL;
392 nested_command->realtime = renderengine->command->realtime;
393 nested_renderengine = new RenderEngine(0,
396 renderengine ? renderengine->channeldb : 0,
398 nested_renderengine->set_acache(get_cache());
399 // Must use a private cache for the audio
402 // cache = new CICache(get_preferences());
403 // private_cache = 1;
405 // nested_renderengine->set_acache(cache);
406 nested_renderengine->arm_command(nested_command);
409 if(debug) printf("AModule::import_samples %d speed_fragment_len=%d\n", __LINE__, (int)speed_fragment_len);
411 // Allocate output buffers for all channels
412 for(int i = 0; i < nested_edl->session->audio_channels; i++)
414 if(nested_allocation < speed_fragment_len)
416 delete nested_output[i];
417 nested_output[i] = 0;
420 if(!nested_output[i])
422 nested_output[i] = new Samples(speed_fragment_len);
425 if(debug) printf("AModule::import_samples %d\n", __LINE__);
427 if(nested_allocation < speed_fragment_len)
428 nested_allocation = speed_fragment_len;
430 // Update direction command
431 nested_renderengine->command->command = command;
433 // Render the segment
434 if(!nested_renderengine->arender)
436 bzero(speed_buffer->get_data(), speed_fragment_len * sizeof(double));
439 if(sample_rate != nested_edl->session->sample_rate)
441 // Read through sample rate converter.
444 resample = new AModuleResample(this);
447 if(debug) printf("AModule::import_samples %d %d %d\n",
450 (int)nested_edl->session->sample_rate);
451 result = resample->resample(speed_buffer,
453 nested_edl->session->sample_rate,
457 // Resample reverses to keep it running forward.
458 if(debug) printf("AModule::import_samples %d\n", __LINE__);
462 // Render without resampling
463 if(debug) printf("AModule::import_samples %d\n", __LINE__);
464 result = nested_renderengine->arender->process_buffer(
468 if(debug) printf("AModule::import_samples %d\n", __LINE__);
469 memcpy(speed_buffer->get_data(),
470 nested_output[edit->channel]->get_data(),
471 speed_fragment_len * sizeof(double));
472 if(debug) printf("AModule::import_samples %d\n", __LINE__);
474 // Reverse fragment so ::render can apply transitions going forward.
475 if(direction == PLAY_REVERSE)
477 Resample::reverse_buffer(speed_buffer->get_data(), speed_fragment_len);
481 if(debug) printf("AModule::import_samples %d\n", __LINE__);
484 // Source is an asset
488 if(debug) printf("AModule::import_samples %d\n", __LINE__);
491 if(debug) printf("AModule::import_samples %d\n", __LINE__);
494 if(debug) printf("AModule::import_samples %d\n", __LINE__);
495 if(nested_renderengine)
497 delete nested_renderengine;
498 nested_renderengine = 0;
501 if(debug) printf("AModule::import_samples %d\n", __LINE__);
503 if(!(file = get_cache()->check_out(
507 // couldn't open source file / skip the edit
508 printf(_("AModule::import_samples Couldn't open %s.\n"), asset->path);
516 if(sample_rate != asset->sample_rate)
518 // Read through sample rate converter.
521 resample = new AModuleResample(this);
524 if(debug) printf("AModule::import_samples %d %d %d\n",
528 result = resample->resample(speed_buffer,
534 // Resample reverses to keep it running forward.
540 printf("AModule::import_samples %d channel=%d start_source=%ld len=%d\n", __LINE__, edit->channel, start_source, (int)speed_fragment_len);
541 file->set_audio_position(start_source);
542 file->set_channel(edit->channel);
543 result = file->read_samples(speed_buffer, speed_fragment_len);
544 // Reverse fragment so ::render can apply transitions going forward.
545 if(debug) printf("AModule::import_samples %d speed_buffer=%p data=%p speed_fragment_len=%d\n",
548 (void*)speed_buffer->get_data(),
549 (int)speed_fragment_len);
550 if(direction == PLAY_REVERSE)
552 Resample::reverse_buffer(speed_buffer->get_data(), speed_fragment_len);
554 if(debug) printf("AModule::import_samples %d\n", __LINE__);
557 if(debug) printf("AModule::import_samples %d\n", __LINE__);
558 get_cache()->check_in(asset);
559 if(debug) printf("AModule::import_samples %d\n", __LINE__);
572 if(debug) printf("AModule::import_samples %d %p %d\n", __LINE__, speed_buffer->get_data(), (int)speed_fragment_len);
573 if(speed_fragment_len > 0) bzero(speed_buffer->get_data(), speed_fragment_len * sizeof(double));
574 if(debug) printf("AModule::import_samples %d\n", __LINE__);
576 if(debug) printf("AModule::import_samples %d\n", __LINE__);
586 // Stretch it to fit the speed curve
587 // Need overlapping buffers to get the interpolation to work, but this
588 // screws up sequential effects.
591 FloatAuto *previous = 0;
593 FloatAutos *speed_autos = (FloatAutos*)track->automation->autos[AUTOMATION_SPEED];
594 double *buffer_samples = buffer->get_data();
595 double *speed_samples = speed_buffer->get_data();
597 //printf("AModule::import_samples %d %lld\n", __LINE__, speed_fragment_len);
599 if(speed_fragment_len == 0)
601 bzero(buffer_samples, fragment_len * sizeof(double));
602 bzero(prev_tail, SPEED_OVERLAP * sizeof(double));
603 bzero(prev_head, SPEED_OVERLAP * sizeof(double));
607 // buffer is now reversed
608 if(direction == PLAY_REVERSE)
611 speed_position = speed_position2;
612 //printf("AModule::import_samples %d %lld %lld\n", __LINE__, start_project, speed_fragment_len);
613 for(int64_t i = start_project + fragment_len;
617 // funky sample reordering, because the source is a reversed buffer
618 int in_offset = (int64_t)(speed_fragment_len - 1 - speed_position);
619 CLAMP(in_offset, 0, speed_fragment_len - 1);
620 buffer_samples[out_offset++] = speed_samples[in_offset];
621 double speed = speed_autos->get_value(i,
625 speed_position -= speed;
627 //printf("AModule::import_samples %d %f\n", __LINE__, speed_position);
632 // position in buffer to read
633 speed_position = speed_position1 - start_source;
635 //printf("AModule::import_samples %d %f\n", __LINE__, speed_position);
636 for(int64_t i = start_project; i < start_project + fragment_len; i++)
638 double speed = speed_autos->get_value(i,
642 double next_speed_position = speed_position + speed;
644 int in_offset = (int)(speed_position);
645 if(fabs(speed) >= 1.0)
647 int total = abs(speed);
649 for(int j = 0; j < total; j++)
651 int in_offset2 = in_offset + (speed > 0 ? j : -j);
653 CLAMP(in_offset2, 0, speed_fragment_len - 1);
654 accum += speed_samples[in_offset2];
658 buffer_samples[out_offset++] = accum / total;
664 // if(in_offset < 0 || in_offset >= speed_fragment_len)
665 // printf("AModule::import_samples %d %d %d\n",
668 // speed_fragment_len);
670 int in_offset1 = in_offset;
671 int in_offset2 = in_offset;
675 in_offset1 += SPEED_OVERLAP;
676 in_offset2 = in_offset1 - 1;
680 in_offset1 -= SPEED_OVERLAP;
681 in_offset2 = in_offset1 + 1;
684 CLAMP(in_offset1, -SPEED_OVERLAP, speed_fragment_len - 1 + SPEED_OVERLAP);
685 CLAMP(in_offset2, -SPEED_OVERLAP, speed_fragment_len - 1 + SPEED_OVERLAP);
688 if(in_offset1 >= speed_fragment_len)
690 value1 = prev_head[in_offset1 - speed_fragment_len];
695 value1 = speed_samples[in_offset1];
699 //printf("AModule::import_samples %d %d\n", __LINE__, in_offset1);
700 value1 = prev_tail[SPEED_OVERLAP + in_offset1];
704 if(in_offset2 >= speed_fragment_len)
706 value2 = prev_head[in_offset2 - speed_fragment_len];
711 value2 = speed_samples()[in_offset2];
715 value2 = prev_tail[SPEED_OVERLAP + in_offset2];
718 double fraction = speed_position - floor(speed_position);
719 buffer_samples[out_offset++] =
720 value1 * (1.0 - fraction) +
723 buffer_samples[out_offset++] = value1;
728 speed_position = next_speed_position;
732 for(int i = 0; i < SPEED_OVERLAP; i++)
734 int offset = speed_fragment_len -
737 CLAMP(offset, 0, speed_fragment_len - 1);
738 //printf("AModule::import_samples %d %d\n", __LINE__, offset, );
739 prev_tail[i] = speed_samples[offset];
741 CLAMP(offset, 0, speed_fragment_len - 1);
742 prev_head[i] = speed_samples[offset];
756 int AModule::render(Samples *buffer,
758 int64_t start_position,
763 int64_t edl_rate = get_edl()->session->sample_rate;
766 if(debug) printf("AModule::render %d\n", __LINE__);
769 start_position += track->nudge *
772 AEdit *playable_edit;
773 int64_t end_position;
774 if(direction == PLAY_FORWARD)
775 end_position = start_position + input_len;
777 end_position = start_position - input_len;
778 int buffer_offset = 0;
782 // // Flip range around so the source is always read forward.
783 // if(direction == PLAY_REVERSE)
785 // start_project -= input_len;
786 // end_position -= input_len;
791 bzero(buffer->get_data(), input_len * sizeof(double));
793 // The EDL is normalized to the requested sample rate because
794 // the requested rate may be the project sample rate and a sample rate
795 // might as well be directly from the source rate to the requested rate.
796 // Get first edit containing the range
797 if(direction == PLAY_FORWARD)
798 playable_edit = (AEdit*)track->edits->first;
800 playable_edit = (AEdit*)track->edits->last;
801 if(debug) printf("AModule::render %d\n", __LINE__);
805 int64_t edit_start = playable_edit->startproject;
806 int64_t edit_end = playable_edit->startproject + playable_edit->length;
808 // Normalize to requested rate
809 edit_start = edit_start * sample_rate / edl_rate;
810 edit_end = edit_end * sample_rate / edl_rate;
812 if(direction == PLAY_FORWARD)
814 if(start_position < edit_end && end_position > edit_start)
818 playable_edit = (AEdit*)playable_edit->next;
822 if(end_position < edit_end && start_position > edit_start)
826 playable_edit = (AEdit*)playable_edit->previous;
831 if(debug) printf("AModule::render %d\n", __LINE__);
837 // Fill output one fragment at a time
838 while(start_position != end_position)
840 int64_t fragment_len = input_len;
842 if(debug) printf("AModule::render %d " _LD " " _LD "\n", __LINE__, start_position, end_position);
843 // Clamp fragment to end of input
844 if(direction == PLAY_FORWARD &&
845 start_position + fragment_len > end_position)
846 fragment_len = end_position - start_position;
848 if(direction == PLAY_REVERSE &&
849 start_position - fragment_len < end_position)
850 fragment_len = start_position - end_position;
851 if(debug) printf("AModule::render %d " _LD "\n", __LINE__, fragment_len);
853 // Normalize position here since update_transition is a boolean operation.
854 update_transition(start_position *
861 AEdit *previous_edit = (AEdit*)playable_edit->previous;
863 // Normalize EDL positions to requested rate
864 int64_t edit_startproject = playable_edit->startproject;
865 int64_t edit_endproject = playable_edit->startproject + playable_edit->length;
866 int64_t edit_startsource = playable_edit->startsource;
867 if(debug) printf("AModule::render %d " _LD "\n", __LINE__, fragment_len);
869 edit_startproject = edit_startproject * sample_rate / edl_rate;
870 edit_endproject = edit_endproject * sample_rate / edl_rate;
871 edit_startsource = edit_startsource * sample_rate / edl_rate;
872 if(debug) printf("AModule::render %d " _LD "\n", __LINE__, fragment_len);
876 // Clamp fragment to end of edit
877 if(direction == PLAY_FORWARD &&
878 start_position + fragment_len > edit_endproject)
879 fragment_len = edit_endproject - start_position;
881 if(direction == PLAY_REVERSE &&
882 start_position - fragment_len < edit_startproject)
883 fragment_len = start_position - edit_startproject;
884 if(debug) printf("AModule::render %d " _LD "\n", __LINE__, fragment_len);
886 // Clamp to end of transition
887 int64_t transition_len = 0;
892 transition_len = transition->length *
895 if(direction == PLAY_FORWARD &&
896 start_position < edit_startproject + transition_len &&
897 start_position + fragment_len > edit_startproject + transition_len)
898 fragment_len = edit_startproject + transition_len - start_position;
900 if(direction == PLAY_REVERSE &&
901 start_position > edit_startproject + transition_len &&
902 start_position - fragment_len < edit_startproject + transition_len)
903 fragment_len = start_position - edit_startproject - transition_len;
905 if(debug) printf("AModule::render %d buffer_offset=%d fragment_len=" _LD "\n",
910 Samples output(buffer);
911 output.set_offset(output.get_offset() + buffer_offset);
912 if(import_samples(playable_edit,
919 fragment_len)) result = 1;
921 if(debug) printf("AModule::render %d\n", __LINE__);
924 // Read transition into temp and render
925 if(transition && previous_edit)
927 int64_t previous_startproject = previous_edit->startproject *
930 int64_t previous_startsource = previous_edit->startsource *
934 // Allocate transition temp size
935 int transition_fragment_len = fragment_len;
936 if(direction == PLAY_FORWARD &&
937 fragment_len + start_position > edit_startproject + transition_len)
938 fragment_len = edit_startproject + transition_len - start_position;
941 // Read into temp buffers
942 // Temp + master or temp + temp ? temp + master
943 if(transition_temp &&
944 transition_temp->get_allocated() < fragment_len)
946 delete transition_temp;
952 transition_temp = new Samples(fragment_len);
955 if(debug) printf("AModule::render %d " _LD "\n", __LINE__, fragment_len);
957 if(transition_fragment_len > 0)
959 // Previous_edit is always the outgoing segment, regardless of direction
960 import_samples(previous_edit,
962 previous_startproject,
963 previous_startsource,
967 transition_fragment_len);
968 int64_t current_position;
970 // Reverse buffers here so transitions always render forward.
971 if(direction == PLAY_REVERSE)
973 Resample::reverse_buffer(output.get_data(), transition_fragment_len);
974 Resample::reverse_buffer(transition_temp->get_data(), transition_fragment_len);
975 current_position = start_position -
976 transition_fragment_len -
981 current_position = start_position - edit_startproject;
984 transition_server->process_transition(
988 transition_fragment_len,
991 // Reverse output buffer here so transitions always render forward.
992 if(direction == PLAY_REVERSE)
993 Resample::reverse_buffer(output.get_data(),
994 transition_fragment_len);
997 if(debug) printf("AModule::render %d start_position=" _LD " end_position=" _LD " fragment_len=" _LD "\n",
1003 if(direction == PLAY_REVERSE)
1005 if(playable_edit && start_position - fragment_len <= edit_startproject)
1006 playable_edit = (AEdit*)playable_edit->previous;
1010 if(playable_edit && start_position + fragment_len >= edit_endproject)
1011 playable_edit = (AEdit*)playable_edit->next;
1015 if(fragment_len > 0)
1017 buffer_offset += fragment_len;
1018 if(direction == PLAY_FORWARD)
1019 start_position += fragment_len;
1021 start_position -= fragment_len;
1025 if(debug) printf("AModule::render %d\n", __LINE__);