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"
43 #include "pluginarray.h"
44 #include "preferences.h"
45 #include "renderengine.h"
46 #include "mainsession.h"
48 #include "sharedlocation.h"
50 #include "transition.h"
51 #include "transportque.h"
61 AModuleResample::AModuleResample(AModule *module)
64 this->module = module;
65 bzero(nested_output, sizeof(Samples*) * MAX_CHANNELS);
66 nested_allocation = 0;
69 AModuleResample::~AModuleResample()
71 for(int i = 0; i < MAX_CHANNELS; i++)
72 delete nested_output[i];
75 int AModuleResample::read_samples(Samples *buffer, int64_t start, int64_t len)
82 // Files only read going forward.
83 if(get_direction() == PLAY_REVERSE)
88 //printf("AModuleResample::read_samples start=%jd len=%jd\n", start, len);
89 module->file->set_audio_position(start);
90 module->file->set_channel(module->channel);
91 result = module->file->read_samples(buffer, len);
93 // Reverse buffer so resampling filter renders forward.
94 if(get_direction() == PLAY_REVERSE)
95 Resample::reverse_buffer(buffer->get_data(), len);
98 if(module->nested_edl)
102 // Nested EDL generates reversed buffer.
103 for(int i = 0; i < module->nested_edl->session->audio_channels; i++)
105 if(nested_allocation < len)
107 delete nested_output[i];
108 nested_output[i] = 0;
111 if(!nested_output[i])
113 nested_output[i] = new Samples(len);
118 result = module->nested_renderengine->arender->process_buffer(
122 // printf("AModuleResample::read_samples buffer=%p module=%p len=%d\n",
126 memcpy(buffer->get_data(),
127 nested_output[module->channel]->get_data(),
128 len * sizeof(double));
144 AModule::AModule(RenderEngine *renderengine,
145 CommonRender *commonrender,
146 PluginArray *plugin_array,
148 : Module(renderengine, commonrender, plugin_array, track)
150 data_type = TRACK_AUDIO;
155 bzero(nested_output, sizeof(Samples*) * MAX_CHANNELS);
156 bzero(prev_head, SPEED_OVERLAP * sizeof(double));
157 bzero(prev_tail, SPEED_OVERLAP * sizeof(double));
158 nested_allocation = 0;
169 if(transition_temp) delete transition_temp;
170 if(speed_temp) delete speed_temp;
173 delete [] level_history;
174 delete [] level_samples;
177 for(int i = 0; i < MAX_CHANNELS; i++)
181 delete nested_output[i];
188 AttachmentPoint* AModule::new_attachment(Plugin *plugin)
190 return new AAttachmentPoint(renderengine, plugin);
194 void AModule::create_objects()
196 Module::create_objects();
197 // Not needed in pluginarray
200 level_history = new double[((ARender*)commonrender)->total_peaks];
201 level_samples = new int64_t[((ARender*)commonrender)->total_peaks];
204 for(int i = 0; i < ((ARender*)commonrender)->total_peaks; i++)
206 level_history[i] = 0;
207 level_samples[i] = -1;
212 int AModule::get_buffer_size()
215 return renderengine->fragment_len;
217 return plugin_array->get_bufsize();
221 CICache* AModule::get_cache()
224 return renderengine->get_acache();
230 int AModule::import_samples(AEdit *edit,
231 int64_t start_project,
232 int64_t edit_startproject,
233 int64_t edit_startsource,
237 int64_t fragment_len)
240 // start in EDL samplerate
241 int64_t start_source = start_project -
244 // fragment size adjusted for speed curve
245 int64_t speed_fragment_len = fragment_len;
246 // boundaries of input fragment required for speed curve
247 double max_position = 0;
248 double min_position = 0;
250 double speed_position = edit_startsource;
251 // position in source where speed curve starts reading
252 double speed_position1 = speed_position;
253 // position in source where speed curve finishes
254 double speed_position2 = speed_position;
256 // Need speed curve processing
258 // Temporary buffer for rendering speed curve
259 Samples *speed_buffer = buffer;
262 if(debug) printf("AModule::import_samples %d edit=%p nested_edl=%p\n",
266 if(nested_edl && edit->channel >= nested_edl->session->audio_channels)
268 if(debug) printf("AModule::import_samples %d\n", __LINE__);
270 this->channel = edit->channel;
271 if(debug) printf("AModule::import_samples %d speed_fragment_len=%ld\n",
278 // apply speed curve to source position so the timeline agrees with the playback
279 if(track->has_speed())
281 // get speed adjusted position from start of edit.
282 FloatAuto *previous = 0;
284 FloatAutos *speed_autos = (FloatAutos*)track->automation->autos[AUTOMATION_SPEED];
285 for(int64_t i = edit_startproject; i < start_project; i++)
287 double speed = speed_autos->get_value(i,
291 speed_position += speed;
294 speed_position1 = speed_position;
297 // calculate boundaries of input fragment required for speed curve
298 max_position = speed_position;
299 min_position = speed_position;
300 for(int64_t i = start_project; i < start_project + fragment_len; i++)
302 double speed = speed_autos->get_value(i,
306 speed_position += speed;
307 if(speed_position > max_position) max_position = speed_position;
308 if(speed_position < min_position) min_position = speed_position;
311 speed_position2 = speed_position;
312 if(speed_position2 < speed_position1)
315 // min_position -= 1.0;
316 speed_fragment_len = (int64_t)(max_position - min_position);
321 speed_fragment_len = (int64_t)(max_position - min_position);
324 //printf("AModule::import_samples %d %f %f %f %f\n",
325 // __LINE__, min_position, max_position, speed_position1, speed_position2);
327 // new start of source to read from file
328 start_source = (int64_t)min_position;
333 // swap in the temp buffer
334 if(speed_temp && speed_temp->get_allocated() < speed_fragment_len)
342 speed_temp = new Samples(speed_fragment_len);
345 speed_buffer = speed_temp;
350 if(speed_fragment_len == 0)
355 // Source is a nested EDL
361 if(direction == PLAY_REVERSE)
362 command = NORMAL_REWIND;
364 command = NORMAL_FWD;
366 if(debug) printf("AModule::import_samples %d\n", __LINE__);
367 if(!nested_edl || nested_edl->id != edit->nested_edl->id)
369 nested_edl = edit->nested_edl;
370 if(nested_renderengine)
372 delete nested_renderengine;
373 nested_renderengine = 0;
378 nested_command = new TransportCommand;
382 if(!nested_renderengine)
384 nested_command->command = command;
385 nested_command->get_edl()->copy_all(nested_edl);
386 nested_command->change_type = CHANGE_ALL;
387 nested_command->realtime = renderengine->command->realtime;
388 nested_renderengine = new RenderEngine(0,
391 renderengine ? renderengine->channeldb : 0,
393 nested_renderengine->set_acache(get_cache());
394 // Must use a private cache for the audio
397 // cache = new CICache(get_preferences());
398 // private_cache = 1;
400 // nested_renderengine->set_acache(cache);
401 nested_renderengine->arm_command(nested_command);
404 if(debug) printf("AModule::import_samples %d speed_fragment_len=%d\n", __LINE__, (int)speed_fragment_len);
406 // Allocate output buffers for all channels
407 for(int i = 0; i < nested_edl->session->audio_channels; i++)
409 if(nested_allocation < speed_fragment_len)
411 delete nested_output[i];
412 nested_output[i] = 0;
415 if(!nested_output[i])
417 nested_output[i] = new Samples(speed_fragment_len);
420 if(debug) printf("AModule::import_samples %d\n", __LINE__);
422 if(nested_allocation < speed_fragment_len)
423 nested_allocation = speed_fragment_len;
425 // Update direction command
426 nested_renderengine->command->command = command;
428 // Render the segment
429 if(!nested_renderengine->arender)
431 bzero(speed_buffer->get_data(), speed_fragment_len * sizeof(double));
434 if(sample_rate != nested_edl->session->sample_rate)
436 // Read through sample rate converter.
439 resample = new AModuleResample(this);
442 if(debug) printf("AModule::import_samples %d %d %d\n",
445 (int)nested_edl->session->sample_rate);
446 result = resample->resample(speed_buffer,
448 nested_edl->session->sample_rate,
452 // Resample reverses to keep it running forward.
453 if(debug) printf("AModule::import_samples %d\n", __LINE__);
457 // Render without resampling
458 if(debug) printf("AModule::import_samples %d\n", __LINE__);
459 result = nested_renderengine->arender->process_buffer(
463 if(debug) printf("AModule::import_samples %d\n", __LINE__);
464 memcpy(speed_buffer->get_data(),
465 nested_output[edit->channel]->get_data(),
466 speed_fragment_len * sizeof(double));
467 if(debug) printf("AModule::import_samples %d\n", __LINE__);
469 // Reverse fragment so ::render can apply transitions going forward.
470 if(direction == PLAY_REVERSE)
472 Resample::reverse_buffer(speed_buffer->get_data(), speed_fragment_len);
476 if(debug) printf("AModule::import_samples %d\n", __LINE__);
479 // Source is an asset
483 if(debug) printf("AModule::import_samples %d\n", __LINE__);
486 if(debug) printf("AModule::import_samples %d\n", __LINE__);
489 if(debug) printf("AModule::import_samples %d\n", __LINE__);
490 if(nested_renderengine)
492 delete nested_renderengine;
493 nested_renderengine = 0;
496 if(debug) printf("AModule::import_samples %d\n", __LINE__);
498 if(!(file = get_cache()->check_out(
502 // couldn't open source file / skip the edit
503 printf(_("AModule::import_samples Couldn't open %s.\n"), asset->path);
511 if(sample_rate != asset->sample_rate)
513 // Read through sample rate converter.
516 resample = new AModuleResample(this);
519 if(debug) printf("AModule::import_samples %d %d %d\n",
523 result = resample->resample(speed_buffer,
529 // Resample reverses to keep it running forward.
535 printf("AModule::import_samples %d channel=%d start_source=%ld len=%d\n", __LINE__, edit->channel, start_source, (int)speed_fragment_len);
536 file->set_audio_position(start_source);
537 file->set_channel(edit->channel);
538 result = file->read_samples(speed_buffer, speed_fragment_len);
539 // Reverse fragment so ::render can apply transitions going forward.
540 if(debug) printf("AModule::import_samples %d speed_buffer=%p data=%p speed_fragment_len=%d\n",
543 (void*)speed_buffer->get_data(),
544 (int)speed_fragment_len);
545 if(direction == PLAY_REVERSE)
547 Resample::reverse_buffer(speed_buffer->get_data(), speed_fragment_len);
549 if(debug) printf("AModule::import_samples %d\n", __LINE__);
552 if(debug) printf("AModule::import_samples %d\n", __LINE__);
553 get_cache()->check_in(asset);
554 if(debug) printf("AModule::import_samples %d\n", __LINE__);
567 if(debug) printf("AModule::import_samples %d %p %d\n", __LINE__, speed_buffer->get_data(), (int)speed_fragment_len);
568 if(speed_fragment_len > 0) bzero(speed_buffer->get_data(), speed_fragment_len * sizeof(double));
569 if(debug) printf("AModule::import_samples %d\n", __LINE__);
571 if(debug) printf("AModule::import_samples %d\n", __LINE__);
581 // Stretch it to fit the speed curve
582 // Need overlapping buffers to get the interpolation to work, but this
583 // screws up sequential effects.
586 FloatAuto *previous = 0;
588 FloatAutos *speed_autos = (FloatAutos*)track->automation->autos[AUTOMATION_SPEED];
589 double *buffer_samples = buffer->get_data();
590 double *speed_samples = speed_buffer->get_data();
592 //printf("AModule::import_samples %d %lld\n", __LINE__, speed_fragment_len);
594 if(speed_fragment_len == 0)
596 bzero(buffer_samples, fragment_len * sizeof(double));
597 bzero(prev_tail, SPEED_OVERLAP * sizeof(double));
598 bzero(prev_head, SPEED_OVERLAP * sizeof(double));
602 // buffer is now reversed
603 if(direction == PLAY_REVERSE)
606 speed_position = speed_position2;
607 //printf("AModule::import_samples %d %lld %lld\n", __LINE__, start_project, speed_fragment_len);
608 for(int64_t i = start_project + fragment_len;
612 // funky sample reordering, because the source is a reversed buffer
613 int in_offset = (int64_t)(speed_fragment_len - 1 - speed_position);
614 CLAMP(in_offset, 0, speed_fragment_len - 1);
615 buffer_samples[out_offset++] = speed_samples[in_offset];
616 double speed = speed_autos->get_value(i,
620 speed_position -= speed;
622 //printf("AModule::import_samples %d %f\n", __LINE__, speed_position);
627 // position in buffer to read
628 speed_position = speed_position1 - start_source;
630 //printf("AModule::import_samples %d %f\n", __LINE__, speed_position);
631 for(int64_t i = start_project; i < start_project + fragment_len; i++)
633 double speed = speed_autos->get_value(i,
637 double next_speed_position = speed_position + speed;
639 int in_offset = (int)(speed_position);
640 if(fabs(speed) >= 1.0)
642 int total = abs(speed);
644 for(int j = 0; j < total; j++)
646 int in_offset2 = in_offset + (speed > 0 ? j : -j);
648 CLAMP(in_offset2, 0, speed_fragment_len - 1);
649 accum += speed_samples[in_offset2];
653 buffer_samples[out_offset++] = accum / total;
659 // if(in_offset < 0 || in_offset >= speed_fragment_len)
660 // printf("AModule::import_samples %d %d %d\n",
663 // speed_fragment_len);
665 int in_offset1 = in_offset;
666 int in_offset2 = in_offset;
670 in_offset1 += SPEED_OVERLAP;
671 in_offset2 = in_offset1 - 1;
675 in_offset1 -= SPEED_OVERLAP;
676 in_offset2 = in_offset1 + 1;
679 CLAMP(in_offset1, -SPEED_OVERLAP, speed_fragment_len - 1 + SPEED_OVERLAP);
680 CLAMP(in_offset2, -SPEED_OVERLAP, speed_fragment_len - 1 + SPEED_OVERLAP);
683 if(in_offset1 >= speed_fragment_len)
685 value1 = prev_head[in_offset1 - speed_fragment_len];
690 value1 = speed_samples[in_offset1];
694 //printf("AModule::import_samples %d %d\n", __LINE__, in_offset1);
695 value1 = prev_tail[SPEED_OVERLAP + in_offset1];
699 if(in_offset2 >= speed_fragment_len)
701 value2 = prev_head[in_offset2 - speed_fragment_len];
706 value2 = speed_samples()[in_offset2];
710 value2 = prev_tail[SPEED_OVERLAP + in_offset2];
713 double fraction = speed_position - floor(speed_position);
714 buffer_samples[out_offset++] =
715 value1 * (1.0 - fraction) +
718 buffer_samples[out_offset++] = value1;
723 speed_position = next_speed_position;
727 for(int i = 0; i < SPEED_OVERLAP; i++)
729 int offset = speed_fragment_len -
732 CLAMP(offset, 0, speed_fragment_len - 1);
733 //printf("AModule::import_samples %d %d\n", __LINE__, offset, );
734 prev_tail[i] = speed_samples[offset];
736 CLAMP(offset, 0, speed_fragment_len - 1);
737 prev_head[i] = speed_samples[offset];
751 int AModule::render(Samples *buffer,
753 int64_t start_position,
758 int64_t edl_rate = get_edl()->session->sample_rate;
761 if(debug) printf("AModule::render %d\n", __LINE__);
764 start_position += track->nudge *
767 AEdit *playable_edit;
768 int64_t end_position;
769 if(direction == PLAY_FORWARD)
770 end_position = start_position + input_len;
772 end_position = start_position - input_len;
773 int buffer_offset = 0;
777 // // Flip range around so the source is always read forward.
778 // if(direction == PLAY_REVERSE)
780 // start_project -= input_len;
781 // end_position -= input_len;
786 bzero(buffer->get_data(), input_len * sizeof(double));
788 // The EDL is normalized to the requested sample rate because
789 // the requested rate may be the project sample rate and a sample rate
790 // might as well be directly from the source rate to the requested rate.
791 // Get first edit containing the range
792 if(direction == PLAY_FORWARD)
793 playable_edit = (AEdit*)track->edits->first;
795 playable_edit = (AEdit*)track->edits->last;
796 if(debug) printf("AModule::render %d\n", __LINE__);
800 int64_t edit_start = playable_edit->startproject;
801 int64_t edit_end = playable_edit->startproject + playable_edit->length;
803 // Normalize to requested rate
804 edit_start = edit_start * sample_rate / edl_rate;
805 edit_end = edit_end * sample_rate / edl_rate;
807 if(direction == PLAY_FORWARD)
809 if(start_position < edit_end && end_position > edit_start)
813 playable_edit = (AEdit*)playable_edit->next;
817 if(end_position < edit_end && start_position > edit_start)
821 playable_edit = (AEdit*)playable_edit->previous;
826 if(debug) printf("AModule::render %d\n", __LINE__);
832 // Fill output one fragment at a time
833 while(start_position != end_position)
835 int64_t fragment_len = input_len;
837 if(debug) printf("AModule::render %d %jd %jd\n", __LINE__, start_position, end_position);
838 // Clamp fragment to end of input
839 if(direction == PLAY_FORWARD &&
840 start_position + fragment_len > end_position)
841 fragment_len = end_position - start_position;
843 if(direction == PLAY_REVERSE &&
844 start_position - fragment_len < end_position)
845 fragment_len = start_position - end_position;
846 if(debug) printf("AModule::render %d %jd\n", __LINE__, fragment_len);
848 // Normalize position here since update_transition is a boolean operation.
849 update_transition(start_position *
856 AEdit *previous_edit = (AEdit*)playable_edit->previous;
858 // Normalize EDL positions to requested rate
859 int64_t edit_startproject = playable_edit->startproject;
860 int64_t edit_endproject = playable_edit->startproject + playable_edit->length;
861 int64_t edit_startsource = playable_edit->startsource;
862 if(debug) printf("AModule::render %d %jd\n", __LINE__, fragment_len);
864 edit_startproject = edit_startproject * sample_rate / edl_rate;
865 edit_endproject = edit_endproject * sample_rate / edl_rate;
866 edit_startsource = edit_startsource * sample_rate / edl_rate;
867 if(debug) printf("AModule::render %d %jd\n", __LINE__, fragment_len);
871 // Clamp fragment to end of edit
872 if(direction == PLAY_FORWARD &&
873 start_position + fragment_len > edit_endproject)
874 fragment_len = edit_endproject - start_position;
876 if(direction == PLAY_REVERSE &&
877 start_position - fragment_len < edit_startproject)
878 fragment_len = start_position - edit_startproject;
879 if(debug) printf("AModule::render %d %jd\n", __LINE__, fragment_len);
881 // Clamp to end of transition
882 int64_t transition_len = 0;
887 transition_len = transition->length *
890 if(direction == PLAY_FORWARD &&
891 start_position < edit_startproject + transition_len &&
892 start_position + fragment_len > edit_startproject + transition_len)
893 fragment_len = edit_startproject + transition_len - start_position;
895 if(direction == PLAY_REVERSE &&
896 start_position > edit_startproject + transition_len &&
897 start_position - fragment_len < edit_startproject + transition_len)
898 fragment_len = start_position - edit_startproject - transition_len;
900 if(debug) printf("AModule::render %d buffer_offset=%d fragment_len=%jd\n",
905 Samples output(buffer);
906 output.set_offset(output.get_offset() + buffer_offset);
907 if(import_samples(playable_edit,
914 fragment_len)) result = 1;
916 if(debug) printf("AModule::render %d\n", __LINE__);
919 // Read transition into temp and render
920 if(transition && previous_edit)
922 int64_t previous_startproject = previous_edit->startproject *
925 int64_t previous_startsource = previous_edit->startsource *
929 // Allocate transition temp size
930 int transition_fragment_len = fragment_len;
931 if(direction == PLAY_FORWARD &&
932 fragment_len + start_position > edit_startproject + transition_len)
933 fragment_len = edit_startproject + transition_len - start_position;
936 // Read into temp buffers
937 // Temp + master or temp + temp ? temp + master
938 if(transition_temp &&
939 transition_temp->get_allocated() < fragment_len)
941 delete transition_temp;
947 transition_temp = new Samples(fragment_len);
950 if(debug) printf("AModule::render %d %jd\n", __LINE__, fragment_len);
952 if(transition_fragment_len > 0)
954 // Previous_edit is always the outgoing segment, regardless of direction
955 import_samples(previous_edit,
957 previous_startproject,
958 previous_startsource,
962 transition_fragment_len);
963 int64_t current_position;
965 // Reverse buffers here so transitions always render forward.
966 if(direction == PLAY_REVERSE)
968 Resample::reverse_buffer(output.get_data(), transition_fragment_len);
969 Resample::reverse_buffer(transition_temp->get_data(), transition_fragment_len);
970 current_position = start_position -
971 transition_fragment_len -
976 current_position = start_position - edit_startproject;
979 transition_server->process_transition(
983 transition_fragment_len,
986 // Reverse output buffer here so transitions always render forward.
987 if(direction == PLAY_REVERSE)
988 Resample::reverse_buffer(output.get_data(),
989 transition_fragment_len);
992 if(debug) printf("AModule::render %d start_position=%jd end_position=%jd fragment_len=%jd\n",
998 if(direction == PLAY_REVERSE)
1000 if(playable_edit && start_position - fragment_len <= edit_startproject)
1001 playable_edit = (AEdit*)playable_edit->previous;
1005 if(playable_edit && start_position + fragment_len >= edit_endproject)
1006 playable_edit = (AEdit*)playable_edit->next;
1010 if(fragment_len > 0)
1012 buffer_offset += fragment_len;
1013 if(direction == PLAY_FORWARD)
1014 start_position += fragment_len;
1016 start_position -= fragment_len;
1020 if(debug) printf("AModule::render %d\n", __LINE__);