Credit Andrew - fix vorbis audio which was scratchy and ensure aging plugin does...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / playtransport.C
index 0165de6581390281b9ff4b505d5feea2f34b8639..f53b529e79abf60a93674e844f687a0bbd2b4648 100644 (file)
@@ -28,7 +28,9 @@
 #include "playbackengine.h"
 #include "playtransport.h"
 #include "preferences.h"
+#include "shuttle.h"
 #include "theme.h"
+#include "tracks.h"
 #include "transportque.h"
 #include "vframe.h"
 
@@ -131,7 +133,7 @@ int PlayTransport::get_w()
 
 int PlayTransport::is_stopped()
 {
-       return engine->command->command == STOP ? 1 : 0;
+       return engine->is_playing_back ? 0 : 1;
 }
 
 int PlayTransport::flip_vertical(int vertical, int &x, int &y)
@@ -200,19 +202,39 @@ int PlayTransport::do_keypress(int key)
                goto_end();
                return result;
        }
-// as in play_command
+
        int ctrl_key = subwindow->ctrl_down() ? 1 : 0;
        int shft_key = subwindow->shift_down() ? 1 : 0;
        int alt_key = subwindow->alt_down() ? 1 : 0;
        int use_inout = ctrl_key;
        int toggle_audio = shft_key & ~ctrl_key;
        int loop_play = shft_key & ctrl_key;
-       int command = -1, prev_command = engine->command->command;
-       using_inout = use_inout;
+       float speed = 0;
+       int command = -1;
+       int curr_command = engine->is_playing_back ? engine->command->command : STOP;
        subwindow->unlock_window();
 
        result = 0;
-       switch( key ) {
+
+       if( key >= SKEY_MIN && key <= SKEY_MAX ) {
+               speed = SHUTTLE_MAX_SPEED *
+                        (key - (SKEY_MAX + SKEY_MIN)/2.f) /
+                               ((SKEY_MAX - SKEY_MIN) / 2.f);
+               if( speed < 0 ) {
+                       speed = -speed;
+                       command = speed < 1 ? SLOW_REWIND :
+                               speed > 1 ? FAST_REWIND : NORMAL_REWIND;
+               }
+               else if( speed > 0 ) {
+                       command = speed < 1 ? SLOW_FWD :
+                               speed > 1 ? FAST_FWD : NORMAL_FWD;
+               }
+               else
+                       command = STOP;
+               use_inout = 0;
+               loop_play = 0;
+       }
+       else switch( key ) {
        case KPINS:     command = STOP;                 break;
        case KPPLUS:    command = FAST_REWIND;          break;
        case KP6:       command = NORMAL_REWIND;        break;
@@ -222,8 +244,9 @@ int PlayTransport::do_keypress(int key)
        case KP2:       command = SLOW_FWD;             break;
        case KP3:       command = NORMAL_FWD;           break;
        case KPENTER:   command = FAST_FWD;             break;
+
        case ' ':
-               switch( prev_command ) {
+               switch( curr_command ) {
                case COMMAND_NONE:
                case CURRENT_FRAME:
                case LAST_FRAME:
@@ -265,7 +288,7 @@ int PlayTransport::do_keypress(int key)
                break;
        }
        if( command >= 0 ) {
-               handle_transport(command, 0, use_inout, 1, toggle_audio, loop_play);
+               handle_transport(command, 0, use_inout, toggle_audio, loop_play, speed);
                result = 1;
        }
 
@@ -276,24 +299,30 @@ int PlayTransport::do_keypress(int key)
 
 void PlayTransport::goto_start()
 {
-       handle_transport(REWIND, 1, 0);
+       handle_transport(REWIND, 1);
 }
 
 void PlayTransport::goto_end()
 {
-       handle_transport(GOTO_END, 1, 0);
+       handle_transport(GOTO_END, 1);
 }
 
 
 
-void PlayTransport::handle_transport(int command, int wait_tracking, int use_inout,
-               int update_refresh, int toggle_audio, int loop_play)
+void PlayTransport::handle_transport(int command, int wait_tracking,
+               int use_inout, int toggle_audio, int loop_play, float speed)
 {
        EDL *edl = get_edl();
        if( !edl ) return;
-       if( !is_vwindow() )
-               mwindow->queue_mixers(edl, command, wait_tracking, use_inout, update_refresh, toggle_audio, 0);
-       engine->issue_command(edl, command, wait_tracking, use_inout, update_refresh, toggle_audio, loop_play);
+       using_inout = use_inout;
+
+       if( use_mixers() )
+               mwindow->handle_mixers(edl, command, wait_tracking,
+                               use_inout, toggle_audio, 0, speed);
+       engine->next_command->toggle_audio = toggle_audio;
+       engine->next_command->loop_play = loop_play;
+       engine->next_command->speed = speed;
+       engine->send_command(command, edl, wait_tracking, use_inout);
 }
 
 EDL* PlayTransport::get_edl()
@@ -301,21 +330,14 @@ EDL* PlayTransport::get_edl()
        return mwindow->edl;
 }
 
-int PlayTransport::pause_transport()
+int PlayTransport::set_transport(int mode)
 {
-       if(active_button) active_button->set_mode(PLAY_MODE);
-       return 0;
-}
-
-
-int PlayTransport::reset_transport()
-{
-       fast_reverse->set_mode(PLAY_MODE);
-       reverse_play->set_mode(PLAY_MODE);
-       forward_play->set_mode(PLAY_MODE);
-       frame_reverse_play->set_mode(PLAY_MODE);
-       frame_forward_play->set_mode(PLAY_MODE);
-       fast_play->set_mode(PLAY_MODE);
+       fast_reverse->set_mode(mode);
+       reverse_play->set_mode(mode);
+       forward_play->set_mode(mode);
+       frame_reverse_play->set_mode(mode);
+       frame_forward_play->set_mode(mode);
+       fast_play->set_mode(mode);
        return 0;
 }
 
@@ -330,10 +352,29 @@ PTransportButton::~PTransportButton()
 {
 }
 
-int PTransportButton::set_mode(int mode)
+void PTransportButton::set_mode(int mode)
 {
        this->mode = mode;
-       return 0;
+}
+
+void PTransportButton::loop_mode(int dir)
+{
+       if( mode != LOOP_MODE ) return;
+       EDL *edl = transport->get_edl();
+       if( !edl ) return;
+       PlaybackEngine *engine = transport->engine;
+       if( !engine || engine->is_playing_back ) return;
+       double position = engine->get_tracking_position();
+       switch( dir ) {
+       case PLAY_FORWARD:
+               if( position >= edl->tracks->total_playable_length() )
+                       transport->goto_start();
+               break;
+       case PLAY_REVERSE:
+               if( position <= 0 )
+                       transport->goto_end();
+               break;
+       }
 }
 
 int PTransportButton::play_command(const char *lock_msg, int command)
@@ -344,7 +385,7 @@ int PTransportButton::play_command(const char *lock_msg, int command)
        int toggle_audio = shft_key & ~ctrl_key;
        int loop_play = shft_key & ctrl_key;
        unlock_window();
-       transport->handle_transport(command, 0, use_inout, 0, toggle_audio, loop_play);
+       transport->handle_transport(command, 0, use_inout, toggle_audio, loop_play, 0);
        lock_window(lock_msg);
        return 1;
 }
@@ -354,6 +395,8 @@ RewindButton::RewindButton(MWindow *mwindow, PlayTransport *transport, int x, in
  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("rewind"))
 {
        set_tooltip(_("Rewind ( Home )"));
+// *** CONTEXT_HELP ***
+       context_help_set_keyword("Transport Controls");
 }
 int RewindButton::handle_event()
 {
@@ -367,9 +410,12 @@ FastReverseButton::FastReverseButton(MWindow *mwindow, PlayTransport *transport,
  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("fastrev"))
 {
        set_tooltip(_("Fast reverse ( + or Alt-p )"));
+// *** CONTEXT_HELP ***
+       context_help_set_keyword("Transport Controls");
 }
 int FastReverseButton::handle_event()
 {
+       loop_mode(PLAY_REVERSE);
        return play_command("FastReverseButton::handle_event", FAST_REWIND);
 }
 
@@ -379,9 +425,12 @@ ReverseButton::ReverseButton(MWindow *mwindow, PlayTransport *transport, int x,
  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("reverse"))
 {
        set_tooltip(_("Normal reverse ( 6 or Alt-o )"));
+// *** CONTEXT_HELP ***
+       context_help_set_keyword("Transport Controls");
 }
 int ReverseButton::handle_event()
 {
+       loop_mode(PLAY_REVERSE);
        return play_command("ReverseButton::handle_event", NORMAL_REWIND);
 }
 
@@ -391,6 +440,8 @@ FrameReverseButton::FrameReverseButton(MWindow *mwindow, PlayTransport *transpor
  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("framerev"))
 {
        set_tooltip(_("Frame reverse ( 4 or Alt-u )"));
+// *** CONTEXT_HELP ***
+       context_help_set_keyword("Transport Controls");
 }
 int FrameReverseButton::handle_event()
 {
@@ -406,9 +457,12 @@ PlayButton::PlayButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("play"))
 {
        set_tooltip(_("Normal forward ( 3 or Alt-l )"));
+// *** CONTEXT_HELP ***
+       context_help_set_keyword("Transport Controls");
 }
 int PlayButton::handle_event()
 {
+       loop_mode(PLAY_FORWARD);
        return play_command("PlayButton::handle_event", NORMAL_FWD);
 }
 
@@ -420,6 +474,8 @@ FramePlayButton::FramePlayButton(MWindow *mwindow, PlayTransport *transport, int
  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("framefwd"))
 {
        set_tooltip(_("Frame forward ( 1 or Alt-j )"));
+// *** CONTEXT_HELP ***
+       context_help_set_keyword("Transport Controls");
 }
 int FramePlayButton::handle_event()
 {
@@ -435,9 +491,12 @@ FastPlayButton::FastPlayButton(MWindow *mwindow, PlayTransport *transport, int x
  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("fastfwd"))
 {
        set_tooltip(_("Fast forward ( Enter or Alt-; )"));
+// *** CONTEXT_HELP ***
+       context_help_set_keyword("Transport Controls");
 }
 int FastPlayButton::handle_event()
 {
+       loop_mode(PLAY_FORWARD);
        return play_command("FastPlayButton::handle_event", FAST_FWD);
 }
 
@@ -445,6 +504,8 @@ EndButton::EndButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("end"))
 {
        set_tooltip(_("Jump to end ( End )"));
+// *** CONTEXT_HELP ***
+       context_help_set_keyword("Transport Controls");
 }
 int EndButton::handle_event()
 {
@@ -458,11 +519,13 @@ StopButton::StopButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
  : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("stop"))
 {
        set_tooltip(_("Stop ( 0 or Alt-m )"));
+// *** CONTEXT_HELP ***
+       context_help_set_keyword("Transport Controls");
 }
 int StopButton::handle_event()
 {
        unlock_window();
-       transport->handle_transport(STOP, 0, 0);
+       transport->handle_transport(STOP);
        lock_window("StopButton::handle_event");
        return 1;
 }
@@ -472,26 +535,23 @@ int StopButton::handle_event()
 void PlayTransport::change_position(double position)
 {
        if( !get_edl() ) return;
-       int prev_command = engine->command->command;
+       int command = engine->command->command;
 // stop transport
-       if( prev_command != STOP && prev_command != COMMAND_NONE &&
-           prev_command != SINGLE_FRAME_FWD && prev_command != SINGLE_FRAME_REWIND ) {
-               engine->que->send_command(STOP, CHANGE_NONE, 0, 0);
-               engine->interrupt_playback(0);
-       }
+       engine->stop_playback(0);
        mwindow->gui->lock_window("PlayTransport::change_position");
        mwindow->goto_position(position);
        mwindow->gui->unlock_window();
 // restart command
-       switch(prev_command) {
+       switch( command ) {
        case FAST_REWIND:
        case NORMAL_REWIND:
        case SLOW_REWIND:
        case SLOW_FWD:
        case NORMAL_FWD:
        case FAST_FWD:
-               engine->que->send_command(prev_command, CHANGE_NONE,
-                               get_edl(), 1, 1, using_inout, 0);
+               engine->next_command->realtime = 1;
+               engine->next_command->resume = 1;
+               engine->transport_command(command, CHANGE_NONE, get_edl(), using_inout);
        }
 }