+++ /dev/null
-
-/*
- * CINELERRA
- * Copyright (C) 2009 Adam Williams <broadcast at earthling dot net>
- *
- * 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 "amodule.h"
-#include "arender.h"
-#include "atrack.h"
-#include "audiodevice.h"
-#include "auto.h"
-#include "autos.h"
-#include "bcsignals.h"
-#include "cache.h"
-#include "condition.h"
-#include "edit.h"
-#include "edl.h"
-#include "edlsession.h"
-#include "format.inc"
-#include "levelwindow.h"
-#include "mainsession.h"
-#include "playabletracks.h"
-#include "playbackengine.h"
-#include "preferences.h"
-#include "renderengine.h"
-#include "samples.h"
-#include "tracks.h"
-#include "transportque.h"
-#include "virtualaconsole.h"
-#include "virtualconsole.h"
-#include "virtualnode.h"
-
-ARender::ARender(RenderEngine *renderengine)
- : CommonRender(renderengine)
-{
-// Clear output buffers
- for(int i = 0; i < MAXCHANNELS; i++)
- {
- buffer[i] = 0;
- audio_out[i] = 0;
- buffer_allocated[i] = 0;
- level_history[i] = 0;
- }
- level_samples = 0;
- total_peaks = 0;
-
- data_type = TRACK_AUDIO;
-}
-
-ARender::~ARender()
-{
- for(int i = 0; i < MAXCHANNELS; i++)
- {
- if(buffer[i]) delete buffer[i];
- if(level_history[i]) delete [] level_history[i];
- }
- if(level_samples) delete [] level_samples;
-}
-
-void ARender::arm_command()
-{
-// Need the meter history now so AModule can allocate its own history
- calculate_history_size();
- CommonRender::arm_command();
- asynchronous = 1;
- init_meters();
-}
-
-
-int ARender::get_total_tracks()
-{
- return renderengine->get_edl()->tracks->total_audio_tracks();
-}
-
-Module* ARender::new_module(Track *track)
-{
- return new AModule(renderengine, this, 0, track);
-}
-
-int ARender::calculate_history_size()
-{
- if(total_peaks > 0)
- return total_peaks;
- else
- {
- meter_render_fragment = renderengine->fragment_len;
-// This number and the timer in tracking.C determine the rate
- while(meter_render_fragment >
- renderengine->get_edl()->session->sample_rate / TRACKING_RATE)
- meter_render_fragment /= 2;
- total_peaks = 16 *
- renderengine->fragment_len /
- meter_render_fragment;
- return total_peaks;
- }
-}
-
-int ARender::init_meters()
-{
-// not providing enough peaks results in peaks that are ahead of the sound
- if(level_samples) delete [] level_samples;
- calculate_history_size();
- level_samples = new int64_t[total_peaks];
-
- for(int i = 0; i < MAXCHANNELS;i++)
- {
- current_level[i] = 0;
- if(buffer[i] && !level_history[i])
- level_history[i] = new double[total_peaks];
- }
-
- for(int i = 0; i < total_peaks; i++)
- {
- level_samples[i] = -1;
- }
-
- for(int j = 0; j < MAXCHANNELS; j++)
- {
- if(buffer[j])
- for(int i = 0; i < total_peaks; i++)
- level_history[j][i] = 0;
- }
- return 0;
-}
-
-void ARender::allocate_buffers(int samples)
-{
- for(int i = 0; i < MAXCHANNELS; i++)
- {
-// Reset the output buffers in case speed changed
- if(buffer_allocated[i] < samples)
- {
- delete buffer[i];
- buffer[i] = 0;
- }
-
- if(i < renderengine->get_edl()->session->audio_channels)
- {
- buffer[i] = new Samples(samples);
- buffer_allocated[i] = samples;
- audio_out[i] = buffer[i];
- }
- }
-}
-
-void ARender::init_output_buffers()
-{
- allocate_buffers(renderengine->adjusted_fragment_len);
-}
-
-
-VirtualConsole* ARender::new_vconsole_object()
-{
- return new VirtualAConsole(renderengine, this);
-}
-
-int64_t ARender::tounits(double position, int round)
-{
- if(round)
- return Units::round(position * renderengine->get_edl()->session->sample_rate);
- else
- return (int64_t)(position * renderengine->get_edl()->session->sample_rate);
-}
-
-double ARender::fromunits(int64_t position)
-{
- return (double)position / renderengine->get_edl()->session->sample_rate;
-}
-
-
-int ARender::process_buffer(Samples **buffer_out,
- int64_t input_len,
- int64_t input_position)
-{
- int result = 0;
-
- int64_t fragment_position = 0;
- int64_t fragment_len = input_len;
- int reconfigure = 0;
- current_position = input_position;
-
-// Process in fragments
- int start_offset = buffer_out[0]->get_offset();
- while(fragment_position < input_len)
- {
-// Set pointers for destination data
- for(int i = 0; i < MAXCHANNELS; i++)
- {
- if(buffer_out[i])
- {
- this->audio_out[i] = buffer_out[i];
- this->audio_out[i]->set_offset(start_offset + fragment_position);
- }
- else
- this->audio_out[i] = 0;
- }
-
- fragment_len = input_len;
- if(fragment_position + fragment_len > input_len)
- fragment_len = input_len - fragment_position;
-
- reconfigure = vconsole->test_reconfigure(input_position,
- fragment_len);
-
-//printf("ARender::process_buffer 1 " _LD " %d\n", input_position, reconfigure);
-
- if(reconfigure) restart_playback();
-
- result = process_buffer(fragment_len, input_position);
-
- fragment_position += fragment_len;
- input_position += fragment_len;
- current_position = input_position;
- }
-
-// Reset offsets
- for(int i = 0; i < MAXCHANNELS; i++)
- {
- if(buffer_out[i]) buffer_out[i]->set_offset(start_offset);
- }
-
-
-
- return result;
-}
-
-
-int ARender::process_buffer(int64_t input_len, int64_t input_position)
-{
- int result = ((VirtualAConsole*)vconsole)->process_buffer(input_len,
- input_position);
- return result;
-}
-
-int ARender::get_history_number(int64_t *table, int64_t position)
-{
-// Get the entry closest to position
- int result = 0;
- int64_t min_difference = 0x7fffffff;
- for(int i = 0; i < total_peaks; i++)
- {
-
-//printf("" _LD " ", table[i]);
- if(labs(table[i] - position) < min_difference)
- {
- min_difference = labs(table[i] - position);
- result = i;
- }
- }
-//printf("\n");
-//printf("ARender::get_history_number " _LD " %d\n", position, result);
- return result;
-}
-
-void ARender::send_last_buffer()
-{
- if( renderengine->audio )
- renderengine->audio->set_last_buffer();
-}
-
-int ARender::stop_audio(int wait)
-{
- if( renderengine->audio )
- renderengine->audio->stop_audio(wait);
- return 0;
-}
-
-void ARender::interrupt_playback()
-{
-//printf("ARender::interrupt_playback\n");
- interrupt = 1;
- if( renderengine->audio )
- renderengine->audio->interrupt_playback();
-}
-
-void ARender::run()
-{
- int64_t current_input_length;
- int reconfigure = 0;
-const int debug = 0;
-
- first_buffer = 1;
-
- start_lock->unlock();
-if(debug) printf("ARender::run %d %d\n", __LINE__, Thread::calculate_realtime());
-
- while(!done && !interrupt)
- {
- float speed = renderengine->command->get_speed();
- current_input_length = (int64_t)(renderengine->fragment_len * speed +0.5) ;
-
-if(debug) printf("ARender::run %d " _LD " " _LD "\n", __LINE__, current_position, current_input_length);
- get_boundaries(current_input_length);
-
-if(debug) printf("ARender::run %d " _LD " " _LD "\n", __LINE__, current_position, current_input_length);
- if(current_input_length)
- {
- reconfigure = vconsole->test_reconfigure(current_position,
- current_input_length);
- if(reconfigure) restart_playback();
- }
-if(debug) printf("ARender::run %d " _LD " " _LD "\n", __LINE__, current_position, current_input_length);
-
-
-// Update tracking if no video is playing.
- if(renderengine->command->realtime &&
- renderengine->playback_engine &&
- !renderengine->do_video)
- {
- double position = (double)renderengine->audio->current_position() /
- renderengine->get_edl()->session->sample_rate * speed;
-
- if(renderengine->command->get_direction() == PLAY_FORWARD)
- position += renderengine->command->playbackstart;
- else
- position = renderengine->command->playbackstart - position;
-
-// This number is not compensated for looping. It's compensated in
-// PlaybackEngine::get_tracking_position when interpolation also happens.
- renderengine->playback_engine->update_tracking(position);
- }
-
-
-if(debug) printf("ARender::run %d " _LD "\n", __LINE__, current_input_length);
-
-
-
- process_buffer(current_input_length, current_position);
-if(debug) printf("ARender::run %d\n", __LINE__);
-
-
- advance_position(current_input_length);
-if(debug) printf("ARender::run %d\n", __LINE__);
-
-
- if(vconsole->interrupt) interrupt = 1;
- }
-
-if(debug) printf("ARender::run %d\n", __LINE__);
- if(!interrupt) send_last_buffer();
- if(renderengine->command->realtime)
- stop_audio(interrupt ? 0 : 1);
- vconsole->stop_rendering(0);
- stop_plugins();
-}
-
-
-int ARender::get_next_peak(int current_peak)
-{
- current_peak++;
- if(current_peak >= total_peaks) current_peak = 0;
- return current_peak;
-}
-
-
-
-
-
-
-
-
-