X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.0%2Fcinelerra%2Famodule.C;fp=cinelerra-5.0%2Fcinelerra%2Famodule.C;h=0000000000000000000000000000000000000000;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=448e1676e8dd19528f282f2e23749281a8540d9a;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.0/cinelerra/amodule.C b/cinelerra-5.0/cinelerra/amodule.C deleted file mode 100644 index 448e1676..00000000 --- a/cinelerra-5.0/cinelerra/amodule.C +++ /dev/null @@ -1,1037 +0,0 @@ - -/* - * CINELERRA - * Copyright (C) 2009-2013 Adam Williams - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "aattachmentpoint.h" -#include "aedit.h" -#include "amodule.h" -#include "aplugin.h" -#include "arender.h" -#include "asset.h" -#include "atrack.h" -#include "automation.h" -#include "bcsignals.h" -#include "cache.h" -#include "clip.h" -#include "edits.h" -#include "edl.h" -#include "edlsession.h" -#include "file.h" -#include "filexml.h" -#include "floatautos.h" -#include "format.inc" -#include "language.h" -#include "module.h" -#include "patch.h" -#include "plugin.h" -#include "pluginarray.h" -#include "preferences.h" -#include "renderengine.h" -#include "mainsession.h" -#include "samples.h" -#include "sharedlocation.h" -#include "theme.h" -#include "transition.h" -#include "transportque.h" -#include - - - - - - - - -AModuleResample::AModuleResample(AModule *module) - : Resample() -{ - this->module = module; - bzero(nested_output, sizeof(Samples*) * MAX_CHANNELS); - nested_allocation = 0; -} - -AModuleResample::~AModuleResample() -{ - for(int i = 0; i < MAX_CHANNELS; i++) - delete nested_output[i]; -} - -int AModuleResample::read_samples(Samples *buffer, int64_t start, int64_t len) -{ - int result = 0; - - - if(module->asset) - { -// Files only read going forward. - if(get_direction() == PLAY_REVERSE) - { - start -= len; - } - -//printf("AModuleResample::read_samples start=" _LD " len=" _LD "\n", start, len); - module->file->set_audio_position(start); - module->file->set_channel(module->channel); - result = module->file->read_samples(buffer, len); - -// Reverse buffer so resampling filter renders forward. - if(get_direction() == PLAY_REVERSE) - Resample::reverse_buffer(buffer->get_data(), len); - } - else - if(module->nested_edl) - { - - -// Nested EDL generates reversed buffer. - for(int i = 0; i < module->nested_edl->session->audio_channels; i++) - { - if(nested_allocation < len) - { - delete nested_output[i]; - nested_output[i] = 0; - } - - if(!nested_output[i]) - { - nested_output[i] = new Samples(len); - } - } - - - result = module->nested_renderengine->arender->process_buffer( - nested_output, - len, - start); -// printf("AModuleResample::read_samples buffer=%p module=%p len=%d\n", -// buffer, -// module, -// len); - memcpy(buffer->get_data(), - nested_output[module->channel]->get_data(), - len * sizeof(double)); - - } - return result; -} - - - - - - - - - - - -AModule::AModule(RenderEngine *renderengine, - CommonRender *commonrender, - PluginArray *plugin_array, - Track *track) - : Module(renderengine, commonrender, plugin_array, track) -{ - data_type = TRACK_AUDIO; - transition_temp = 0; - speed_temp = 0; - level_history = 0; - current_level = 0; - bzero(nested_output, sizeof(Samples*) * MAX_CHANNELS); - bzero(prev_head, SPEED_OVERLAP * sizeof(double)); - bzero(prev_tail, SPEED_OVERLAP * sizeof(double)); - nested_allocation = 0; - resample = 0; - asset = 0; - file = 0; -} - - - - -AModule::~AModule() -{ - if(transition_temp) delete transition_temp; - if(speed_temp) delete speed_temp; - if(level_history) - { - delete [] level_history; - delete [] level_samples; - } - - for(int i = 0; i < MAX_CHANNELS; i++) - { - if(nested_output[i]) - { - delete nested_output[i]; - } - } - - delete resample; -} - -AttachmentPoint* AModule::new_attachment(Plugin *plugin) -{ - return new AAttachmentPoint(renderengine, plugin); -} - - -void AModule::create_objects() -{ - Module::create_objects(); -// Not needed in pluginarray - if(commonrender) - { - level_history = new double[((ARender*)commonrender)->total_peaks]; - level_samples = new int64_t[((ARender*)commonrender)->total_peaks]; - current_level = 0; - - for(int i = 0; i < ((ARender*)commonrender)->total_peaks; i++) - { - level_history[i] = 0; - level_samples[i] = -1; - } - } -} - -int AModule::get_buffer_size() -{ - if(renderengine) - return renderengine->fragment_len; - else - return plugin_array->get_bufsize(); -} - - -CICache* AModule::get_cache() -{ - if(renderengine) - return renderengine->get_acache(); - else - return cache; -} - - -int AModule::import_samples(AEdit *edit, - int64_t start_project, - int64_t edit_startproject, - int64_t edit_startsource, - int direction, - int sample_rate, - Samples *buffer, - int64_t fragment_len) -{ - int result = 0; -// start in EDL samplerate - int64_t start_source = start_project - - edit_startproject + - edit_startsource; -// fragment size adjusted for speed curve - int64_t speed_fragment_len = fragment_len; -// boundaries of input fragment required for speed curve - double max_position = 0; - double min_position = 0; - - double speed_position = edit_startsource; -// position in source where speed curve starts reading - double speed_position1 = speed_position; -// position in source where speed curve finishes - double speed_position2 = speed_position; - -// Need speed curve processing - int have_speed = 0; -// Temporary buffer for rendering speed curve - Samples *speed_buffer = buffer; - const int debug = 0; - -if(debug) printf("AModule::import_samples %d edit=%p nested_edl=%p\n", -__LINE__, -edit, -nested_edl); - if(nested_edl && edit->channel >= nested_edl->session->audio_channels) - return 1; -if(debug) printf("AModule::import_samples %d\n", __LINE__); - - this->channel = edit->channel; -if(debug) printf("AModule::import_samples %d speed_fragment_len=%ld\n", -__LINE__, -speed_fragment_len); - - - - -// apply speed curve to source position so the timeline agrees with the playback - if(track->has_speed()) - { -// get speed adjusted position from start of edit. - FloatAuto *previous = 0; - FloatAuto *next = 0; - FloatAutos *speed_autos = (FloatAutos*)track->automation->autos[AUTOMATION_SPEED]; - for(int64_t i = edit_startproject; i < start_project; i++) - { - double speed = speed_autos->get_value(i, - PLAY_FORWARD, - previous, - next); - speed_position += speed; - } - - speed_position1 = speed_position; - - -// calculate boundaries of input fragment required for speed curve - max_position = speed_position; - min_position = speed_position; - for(int64_t i = start_project; i < start_project + fragment_len; i++) - { - double speed = speed_autos->get_value(i, - PLAY_FORWARD, - previous, - next); - speed_position += speed; - if(speed_position > max_position) max_position = speed_position; - if(speed_position < min_position) min_position = speed_position; - } - - speed_position2 = speed_position; - if(speed_position2 < speed_position1) - { - max_position += 1.0; -// min_position -= 1.0; - speed_fragment_len = (int64_t)(max_position - min_position); - } - else - { - max_position += 1.0; - speed_fragment_len = (int64_t)(max_position - min_position); - } - -printf("AModule::import_samples %d %f %f %f %f\n", -__LINE__, -min_position, -max_position, -speed_position1, -speed_position2); - -// new start of source to read from file - start_source = (int64_t)min_position; - have_speed = 1; - - - -// swap in the temp buffer - if(speed_temp && speed_temp->get_allocated() < speed_fragment_len) - { - delete speed_temp; - speed_temp = 0; - } - - if(!speed_temp) - { - speed_temp = new Samples(speed_fragment_len); - } - - speed_buffer = speed_temp; - } - - - - if(speed_fragment_len == 0) - return 1; - - - -// Source is a nested EDL - if(edit->nested_edl) - { - int command; - asset = 0; - - if(direction == PLAY_REVERSE) - command = NORMAL_REWIND; - else - command = NORMAL_FWD; - -if(debug) printf("AModule::import_samples %d\n", __LINE__); - if(!nested_edl || nested_edl->id != edit->nested_edl->id) - { - nested_edl = edit->nested_edl; - if(nested_renderengine) - { - delete nested_renderengine; - nested_renderengine = 0; - } - - if(!nested_command) - { - nested_command = new TransportCommand; - } - - - if(!nested_renderengine) - { - nested_command->command = command; - nested_command->get_edl()->copy_all(nested_edl); - nested_command->change_type = CHANGE_ALL; - nested_command->realtime = renderengine->command->realtime; - nested_renderengine = new RenderEngine(0, - get_preferences(), - 0, - renderengine ? renderengine->channeldb : 0, - 1); - nested_renderengine->set_acache(get_cache()); -// Must use a private cache for the audio -// if(!cache) -// { -// cache = new CICache(get_preferences()); -// private_cache = 1; -// } -// nested_renderengine->set_acache(cache); - nested_renderengine->arm_command(nested_command); - } - } -if(debug) printf("AModule::import_samples %d speed_fragment_len=%d\n", __LINE__, (int)speed_fragment_len); - -// Allocate output buffers for all channels - for(int i = 0; i < nested_edl->session->audio_channels; i++) - { - if(nested_allocation < speed_fragment_len) - { - delete nested_output[i]; - nested_output[i] = 0; - } - - if(!nested_output[i]) - { - nested_output[i] = new Samples(speed_fragment_len); - } - } -if(debug) printf("AModule::import_samples %d\n", __LINE__); - - if(nested_allocation < speed_fragment_len) - nested_allocation = speed_fragment_len; - -// Update direction command - nested_renderengine->command->command = command; - -// Render the segment - if(!nested_renderengine->arender) - { - bzero(speed_buffer->get_data(), speed_fragment_len * sizeof(double)); - } - else - if(sample_rate != nested_edl->session->sample_rate) - { -// Read through sample rate converter. - if(!resample) - { - resample = new AModuleResample(this); - } - -if(debug) printf("AModule::import_samples %d %d %d\n", -__LINE__, -(int)sample_rate, -(int)nested_edl->session->sample_rate); - result = resample->resample(speed_buffer, - speed_fragment_len, - nested_edl->session->sample_rate, - sample_rate, - start_source, - direction); -// Resample reverses to keep it running forward. -if(debug) printf("AModule::import_samples %d\n", __LINE__); - } - else - { -// Render without resampling -if(debug) printf("AModule::import_samples %d\n", __LINE__); - result = nested_renderengine->arender->process_buffer( - nested_output, - speed_fragment_len, - start_source); -if(debug) printf("AModule::import_samples %d\n", __LINE__); - memcpy(speed_buffer->get_data(), - nested_output[edit->channel]->get_data(), - speed_fragment_len * sizeof(double)); -if(debug) printf("AModule::import_samples %d\n", __LINE__); - -// Reverse fragment so ::render can apply transitions going forward. - if(direction == PLAY_REVERSE) - { - Resample::reverse_buffer(speed_buffer->get_data(), speed_fragment_len); - } - } - -if(debug) printf("AModule::import_samples %d\n", __LINE__); - } - else -// Source is an asset - if(edit->asset) - { - nested_edl = 0; -if(debug) printf("AModule::import_samples %d\n", __LINE__); - asset = edit->asset; - -if(debug) printf("AModule::import_samples %d\n", __LINE__); - get_cache()->age(); - -if(debug) printf("AModule::import_samples %d\n", __LINE__); - if(nested_renderengine) - { - delete nested_renderengine; - nested_renderengine = 0; - } - -if(debug) printf("AModule::import_samples %d\n", __LINE__); - - if(!(file = get_cache()->check_out( - asset, - get_edl()))) - { -// couldn't open source file / skip the edit - printf(_("AModule::import_samples Couldn't open %s.\n"), asset->path); - result = 1; - } - else - { - result = 0; - - - if(sample_rate != asset->sample_rate) - { -// Read through sample rate converter. - if(!resample) - { - resample = new AModuleResample(this); - } - -if(debug) printf("AModule::import_samples %d %d %d\n", -__LINE__, -sample_rate, -asset->sample_rate); - result = resample->resample(speed_buffer, - speed_fragment_len, - asset->sample_rate, - sample_rate, - start_source, - direction); -// Resample reverses to keep it running forward. - } - else - { - -if(debug) -printf("AModule::import_samples %d channel=%d start_source=%ld len=%d\n", __LINE__, edit->channel, start_source, (int)speed_fragment_len); - file->set_audio_position(start_source); - file->set_channel(edit->channel); - result = file->read_samples(speed_buffer, speed_fragment_len); -// Reverse fragment so ::render can apply transitions going forward. -if(debug) printf("AModule::import_samples %d speed_buffer=%p data=%p speed_fragment_len=%d\n", -__LINE__, -(void*)speed_buffer, -(void*)speed_buffer->get_data(), -(int)speed_fragment_len); - if(direction == PLAY_REVERSE) - { - Resample::reverse_buffer(speed_buffer->get_data(), speed_fragment_len); - } -if(debug) printf("AModule::import_samples %d\n", __LINE__); - } - -if(debug) printf("AModule::import_samples %d\n", __LINE__); - get_cache()->check_in(asset); -if(debug) printf("AModule::import_samples %d\n", __LINE__); - file = 0; - - - - - - } - } - else - { - nested_edl = 0; - asset = 0; -if(debug) printf("AModule::import_samples %d %p %d\n", __LINE__, speed_buffer->get_data(), (int)speed_fragment_len); - if(speed_fragment_len > 0) bzero(speed_buffer->get_data(), speed_fragment_len * sizeof(double)); -if(debug) printf("AModule::import_samples %d\n", __LINE__); - } -if(debug) printf("AModule::import_samples %d\n", __LINE__); - - - - - - - - - -// Stretch it to fit the speed curve -// Need overlapping buffers to get the interpolation to work, but this -// screws up sequential effects. - if(have_speed) - { - FloatAuto *previous = 0; - FloatAuto *next = 0; - FloatAutos *speed_autos = (FloatAutos*)track->automation->autos[AUTOMATION_SPEED]; - double *buffer_samples = buffer->get_data(); - double *speed_samples = speed_buffer->get_data(); - -//printf("AModule::import_samples %d %lld\n", __LINE__, speed_fragment_len); - - if(speed_fragment_len == 0) - { - bzero(buffer_samples, fragment_len * sizeof(double)); - bzero(prev_tail, SPEED_OVERLAP * sizeof(double)); - bzero(prev_head, SPEED_OVERLAP * sizeof(double)); - } - else - { -// buffer is now reversed - if(direction == PLAY_REVERSE) - { - int out_offset = 0; - speed_position = speed_position2; - //printf("AModule::import_samples %d %lld %lld\n", __LINE__, start_project, speed_fragment_len); - for(int64_t i = start_project + fragment_len; - i != start_project; - i--) - { - // funky sample reordering, because the source is a reversed buffer - int in_offset = (int64_t)(speed_fragment_len - 1 - speed_position); - CLAMP(in_offset, 0, speed_fragment_len - 1); - buffer_samples[out_offset++] = speed_samples[in_offset]; - double speed = speed_autos->get_value(i, - PLAY_REVERSE, - previous, - next); - speed_position -= speed; - } - //printf("AModule::import_samples %d %f\n", __LINE__, speed_position); - } - else - { - int out_offset = 0; -// position in buffer to read - speed_position = speed_position1 - start_source; - -//printf("AModule::import_samples %d %f\n", __LINE__, speed_position); - for(int64_t i = start_project; i < start_project + fragment_len; i++) - { - double speed = speed_autos->get_value(i, - PLAY_FORWARD, - previous, - next); - double next_speed_position = speed_position + speed; - - int in_offset = (int)(speed_position); - if(fabs(speed) >= 1.0) - { - int total = abs(speed); - double accum = 0; - for(int j = 0; j < total; j++) - { - int in_offset2 = in_offset + (speed > 0 ? j : -j); - - CLAMP(in_offset2, 0, speed_fragment_len - 1); - accum += speed_samples[in_offset2]; - } - - - buffer_samples[out_offset++] = accum / total; - } - else - { - - -// if(in_offset < 0 || in_offset >= speed_fragment_len) -// printf("AModule::import_samples %d %d %d\n", -// __LINE__, -// in_offset, -// speed_fragment_len); - - int in_offset1 = in_offset; - int in_offset2 = in_offset; - - if(speed < 0) - { - in_offset1 += SPEED_OVERLAP; - in_offset2 = in_offset1 - 1; - } - else - { - in_offset1 -= SPEED_OVERLAP; - in_offset2 = in_offset1 + 1; - } - - CLAMP(in_offset1, -SPEED_OVERLAP, speed_fragment_len - 1 + SPEED_OVERLAP); - CLAMP(in_offset2, -SPEED_OVERLAP, speed_fragment_len - 1 + SPEED_OVERLAP); - - double value1 = 0; - if(in_offset1 >= speed_fragment_len) - { - value1 = prev_head[in_offset1 - speed_fragment_len]; - } - else - if(in_offset1 >= 0) - { - value1 = speed_samples[in_offset1]; - } - else - { -//printf("AModule::import_samples %d %d\n", __LINE__, in_offset1); - value1 = prev_tail[SPEED_OVERLAP + in_offset1]; - } -#if 0 - double value2 = 0; - if(in_offset2 >= speed_fragment_len) - { - value2 = prev_head[in_offset2 - speed_fragment_len]; - } - else - if(in_offset2 >= 0) - { - value2 = speed_samples()[in_offset2]; - } - else - { - value2 = prev_tail[SPEED_OVERLAP + in_offset2]; - } - - double fraction = speed_position - floor(speed_position); - buffer_samples[out_offset++] = - value1 * (1.0 - fraction) + - value2 * fraction; -#endif - buffer_samples[out_offset++] = value1; - - - } - - speed_position = next_speed_position; - } - } - - for(int i = 0; i < SPEED_OVERLAP; i++) - { - int offset = speed_fragment_len - - SPEED_OVERLAP + - i; - CLAMP(offset, 0, speed_fragment_len - 1); -//printf("AModule::import_samples %d %d\n", __LINE__, offset, ); - prev_tail[i] = speed_samples[offset]; - offset = i; - CLAMP(offset, 0, speed_fragment_len - 1); - prev_head[i] = speed_samples[offset]; - } - } - } - - - - - - return result; -} - - - -int AModule::render(Samples *buffer, - int64_t input_len, - int64_t start_position, - int direction, - int sample_rate, - int use_nudge) -{ - int64_t edl_rate = get_edl()->session->sample_rate; - const int debug = 0; - -if(debug) printf("AModule::render %d\n", __LINE__); - - if(use_nudge) - start_position += track->nudge * - sample_rate / - edl_rate; - AEdit *playable_edit; - int64_t end_position; - if(direction == PLAY_FORWARD) - end_position = start_position + input_len; - else - end_position = start_position - input_len; - int buffer_offset = 0; - int result = 0; - - -// // Flip range around so the source is always read forward. -// if(direction == PLAY_REVERSE) -// { -// start_project -= input_len; -// end_position -= input_len; -// } - - -// Clear buffer - bzero(buffer->get_data(), input_len * sizeof(double)); - -// The EDL is normalized to the requested sample rate because -// the requested rate may be the project sample rate and a sample rate -// might as well be directly from the source rate to the requested rate. -// Get first edit containing the range - if(direction == PLAY_FORWARD) - playable_edit = (AEdit*)track->edits->first; - else - playable_edit = (AEdit*)track->edits->last; -if(debug) printf("AModule::render %d\n", __LINE__); - - while(playable_edit) - { - int64_t edit_start = playable_edit->startproject; - int64_t edit_end = playable_edit->startproject + playable_edit->length; - -// Normalize to requested rate - edit_start = edit_start * sample_rate / edl_rate; - edit_end = edit_end * sample_rate / edl_rate; - - if(direction == PLAY_FORWARD) - { - if(start_position < edit_end && end_position > edit_start) - { - break; - } - playable_edit = (AEdit*)playable_edit->next; - } - else - { - if(end_position < edit_end && start_position > edit_start) - { - break; - } - playable_edit = (AEdit*)playable_edit->previous; - } - } - - -if(debug) printf("AModule::render %d\n", __LINE__); - - - - - -// Fill output one fragment at a time - while(start_position != end_position) - { - int64_t fragment_len = input_len; - -if(debug) printf("AModule::render %d " _LD " " _LD "\n", __LINE__, start_position, end_position); -// Clamp fragment to end of input - if(direction == PLAY_FORWARD && - start_position + fragment_len > end_position) - fragment_len = end_position - start_position; - else - if(direction == PLAY_REVERSE && - start_position - fragment_len < end_position) - fragment_len = start_position - end_position; -if(debug) printf("AModule::render %d " _LD "\n", __LINE__, fragment_len); - -// Normalize position here since update_transition is a boolean operation. - update_transition(start_position * - edl_rate / - sample_rate, - PLAY_FORWARD); - - if(playable_edit) - { - AEdit *previous_edit = (AEdit*)playable_edit->previous; - -// Normalize EDL positions to requested rate - int64_t edit_startproject = playable_edit->startproject; - int64_t edit_endproject = playable_edit->startproject + playable_edit->length; - int64_t edit_startsource = playable_edit->startsource; -if(debug) printf("AModule::render %d " _LD "\n", __LINE__, fragment_len); - - edit_startproject = edit_startproject * sample_rate / edl_rate; - edit_endproject = edit_endproject * sample_rate / edl_rate; - edit_startsource = edit_startsource * sample_rate / edl_rate; -if(debug) printf("AModule::render %d " _LD "\n", __LINE__, fragment_len); - - - -// Clamp fragment to end of edit - if(direction == PLAY_FORWARD && - start_position + fragment_len > edit_endproject) - fragment_len = edit_endproject - start_position; - else - if(direction == PLAY_REVERSE && - start_position - fragment_len < edit_startproject) - fragment_len = start_position - edit_startproject; -if(debug) printf("AModule::render %d " _LD "\n", __LINE__, fragment_len); - -// Clamp to end of transition - int64_t transition_len = 0; - - if(transition && - previous_edit) - { - transition_len = transition->length * - sample_rate / - edl_rate; - if(direction == PLAY_FORWARD && - start_position < edit_startproject + transition_len && - start_position + fragment_len > edit_startproject + transition_len) - fragment_len = edit_startproject + transition_len - start_position; - else - if(direction == PLAY_REVERSE && - start_position > edit_startproject + transition_len && - start_position - fragment_len < edit_startproject + transition_len) - fragment_len = start_position - edit_startproject - transition_len; - } -if(debug) printf("AModule::render %d buffer_offset=%d fragment_len=" _LD "\n", -__LINE__, -buffer_offset, -fragment_len); - - Samples output(buffer); - output.set_offset(output.get_offset() + buffer_offset); - if(import_samples(playable_edit, - start_position, - edit_startproject, - edit_startsource, - direction, - sample_rate, - &output, - fragment_len)) result = 1; - -if(debug) printf("AModule::render %d\n", __LINE__); - - -// Read transition into temp and render - if(transition && previous_edit) - { - int64_t previous_startproject = previous_edit->startproject * - sample_rate / - edl_rate; - int64_t previous_startsource = previous_edit->startsource * - sample_rate / - edl_rate; - -// Allocate transition temp size - int transition_fragment_len = fragment_len; - if(direction == PLAY_FORWARD && - fragment_len + start_position > edit_startproject + transition_len) - fragment_len = edit_startproject + transition_len - start_position; - - -// Read into temp buffers -// Temp + master or temp + temp ? temp + master - if(transition_temp && - transition_temp->get_allocated() < fragment_len) - { - delete transition_temp; - transition_temp = 0; - } - - if(!transition_temp) - { - transition_temp = new Samples(fragment_len); - } - -if(debug) printf("AModule::render %d " _LD "\n", __LINE__, fragment_len); - - if(transition_fragment_len > 0) - { -// Previous_edit is always the outgoing segment, regardless of direction - import_samples(previous_edit, - start_position, - previous_startproject, - previous_startsource, - direction, - sample_rate, - transition_temp, - transition_fragment_len); - int64_t current_position; - -// Reverse buffers here so transitions always render forward. - if(direction == PLAY_REVERSE) - { - Resample::reverse_buffer(output.get_data(), transition_fragment_len); - Resample::reverse_buffer(transition_temp->get_data(), transition_fragment_len); - current_position = start_position - - transition_fragment_len - - edit_startproject; - } - else - { - current_position = start_position - edit_startproject; - } - - transition_server->process_transition( - transition_temp, - &output, - current_position, - transition_fragment_len, - transition->length); - -// Reverse output buffer here so transitions always render forward. - if(direction == PLAY_REVERSE) - Resample::reverse_buffer(output.get_data(), - transition_fragment_len); - } - } -if(debug) printf("AModule::render %d start_position=" _LD " end_position=" _LD " fragment_len=" _LD "\n", -__LINE__, -start_position, -end_position, -fragment_len); - - if(direction == PLAY_REVERSE) - { - if(playable_edit && start_position - fragment_len <= edit_startproject) - playable_edit = (AEdit*)playable_edit->previous; - } - else - { - if(playable_edit && start_position + fragment_len >= edit_endproject) - playable_edit = (AEdit*)playable_edit->next; - } - } - - if(fragment_len > 0) - { - buffer_offset += fragment_len; - if(direction == PLAY_FORWARD) - start_position += fragment_len; - else - start_position -= fragment_len; - } - } - -if(debug) printf("AModule::render %d\n", __LINE__); - - return result; -} - - - - - - - - -