4 * Copyright (C) 2008 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 "bcsignals.h"
24 #include "condition.h"
26 #include "edlsession.h"
27 #include "localsession.h"
28 #include "playbackengine.h"
30 #include "transportque.h"
32 TransportCommand::TransportCommand()
34 // In rendering we want a master EDL so settings don't get clobbered
35 // in the middle of a job.
37 edl->create_objects();
43 TransportCommand::~TransportCommand()
45 edl->Garbage::remove_user();
48 void TransportCommand::reset()
59 // Don't reset the change type for commands which don't perform the change
60 if(command != STOP) change_type = 0;
61 command = COMMAND_NONE;
64 EDL* TransportCommand::get_edl()
69 void TransportCommand::delete_edl()
71 edl->Garbage::remove_user();
75 void TransportCommand::new_edl()
78 edl->create_objects();
82 void TransportCommand::copy_from(TransportCommand *command)
84 this->command = command->command;
85 this->change_type = command->change_type;
86 this->edl->copy_all(command->edl);
87 this->start_position = command->start_position;
88 this->end_position = command->end_position;
89 this->playbackstart = command->playbackstart;
90 this->realtime = command->realtime;
91 this->resume = command->resume;
92 this->toggle_audio = command->toggle_audio;
93 this->loop_play = command->loop_play;
94 this->displacement = command->displacement;
95 this->speed = command->speed;
98 TransportCommand& TransportCommand::operator=(TransportCommand &command)
104 int TransportCommand::single_frame(int command)
106 return (command == SINGLE_FRAME_FWD || command == SINGLE_FRAME_REWIND ||
107 command == CURRENT_FRAME || command == LAST_FRAME);
110 int TransportCommand::get_direction(int command)
113 case SINGLE_FRAME_FWD:
120 case SINGLE_FRAME_REWIND:
133 float TransportCommand::get_speed(int command, float speed)
138 return speed ? speed : 0.5;
142 case SINGLE_FRAME_FWD:
143 case SINGLE_FRAME_REWIND:
150 return speed ? speed : 2.;
156 // Assume starting without pause
157 void TransportCommand::set_playback_range(EDL *edl, int use_inout, int do_displacement)
159 if( !edl ) edl = this->edl;
160 double length = edl->tracks->total_playable_length();
161 double frame_period = 1.0 / edl->session->frame_rate;
164 start_position = use_inout && edl->local_session->inpoint_valid() ?
165 edl->local_session->get_inpoint() :
166 !loop_play ? edl->local_session->get_selectionstart(1) : 0;
167 end_position = use_inout && edl->local_session->outpoint_valid() ?
168 edl->local_session->get_outpoint() :
169 !loop_play ? edl->local_session->get_selectionend(1) : length;
171 if( !use_inout && EQUIV(start_position, end_position) ) {
172 // starting play at or past end_position, play to end_position of media (for mixers)
173 if( start_position >= length )
174 length = edl->tracks->total_length();
179 end_position = length;
180 // this prevents a crash if start_position position is after the loop when playing forwards
181 if( edl->local_session->loop_playback &&
182 start_position > edl->local_session->loop_end ) {
183 start_position = edl->local_session->loop_start;
191 // this prevents a crash if start_position position is before the loop when playing backwards
192 if( edl->local_session->loop_playback &&
193 end_position <= edl->local_session->loop_start ) {
194 end_position = edl->local_session->loop_end;
200 case SINGLE_FRAME_FWD:
201 end_position = start_position + frame_period;
204 case SINGLE_FRAME_REWIND:
205 start_position = end_position - frame_period;
209 if( realtime && do_displacement ) {
210 if( (command != CURRENT_FRAME && get_direction() == PLAY_FORWARD ) ||
211 (command != LAST_FRAME && get_direction() == PLAY_REVERSE ) ) {
212 start_position += frame_period;
213 end_position += frame_period;
219 // if( start_position < 0 )
220 // start_position = 0;
221 // if( end_position > length )
222 // end_position = length;
223 if( end_position < start_position )
224 end_position = start_position;
226 playbackstart = get_direction() == PLAY_FORWARD ?
227 start_position : end_position;
230 void TransportCommand::playback_range_adjust_inout()
232 if(edl->local_session->inpoint_valid() ||
233 edl->local_session->outpoint_valid())
235 playback_range_inout();
239 void TransportCommand::playback_range_inout()
241 if(edl->local_session->inpoint_valid())
242 start_position = edl->local_session->get_inpoint();
246 if(edl->local_session->outpoint_valid())
247 end_position = edl->local_session->get_outpoint();
249 end_position = edl->tracks->total_playable_length();
250 if( start_position >= end_position )
251 end_position = edl->tracks->total_length();
255 void TransportCommand::playback_range_project()
258 end_position = edl->tracks->total_playable_length();
261 void TransportCommand::playback_range_1frame()
263 start_position = end_position = edl->local_session->get_selectionstart(1);
264 if( edl->session->frame_rate > 0 ) end_position += 1./edl->session->frame_rate;