plug leaks, leaker tweaks, lang for effect info, c41 spiffs, wm probe tweaks
[goodguy/history.git] / cinelerra-5.1 / cinelerra / playtransport.C
index b330c4dcc8b4c8a9908d17466d4a84289fe07f70..38a5725f1cc7333d0979afcd6872f957aa978d7e 100644 (file)
@@ -2,21 +2,21 @@
 /*
  * CINELERRA
  * Copyright (C) 2008 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 "edl.h"
@@ -34,9 +34,9 @@
 
 
 
-PlayTransport::PlayTransport(MWindow *mwindow, 
-       BC_WindowBase *subwindow, 
-       int x, 
+PlayTransport::PlayTransport(MWindow *mwindow,
+       BC_WindowBase *subwindow,
+       int x,
        int y)
 {
        this->subwindow = subwindow;
@@ -78,21 +78,21 @@ void PlayTransport::create_objects()
        int x = this->x, y = this->y;
        subwindow->add_subwindow(rewind_button = new RewindButton(mwindow, this, x, y));
        x += rewind_button->get_w();
-       subwindow->add_subwindow(fast_reverse = new FastReverseButton(mwindow, this, x, y)); 
+       subwindow->add_subwindow(fast_reverse = new FastReverseButton(mwindow, this, x, y));
        x += fast_reverse->get_w();
-       subwindow->add_subwindow(reverse_play = new ReverseButton(mwindow, this, x, y)); 
+       subwindow->add_subwindow(reverse_play = new ReverseButton(mwindow, this, x, y));
        x += reverse_play->get_w();
-       subwindow->add_subwindow(frame_reverse_play = new FrameReverseButton(mwindow, this, x, y)); 
+       subwindow->add_subwindow(frame_reverse_play = new FrameReverseButton(mwindow, this, x, y));
        x += frame_reverse_play->get_w();
-       subwindow->add_subwindow(stop_button = new StopButton(mwindow, this, x, y)); 
+       subwindow->add_subwindow(stop_button = new StopButton(mwindow, this, x, y));
        x += stop_button->get_w();
-       subwindow->add_subwindow(frame_forward_play = new FramePlayButton(mwindow, this, x, y)); 
+       subwindow->add_subwindow(frame_forward_play = new FramePlayButton(mwindow, this, x, y));
        x += frame_forward_play->get_w();
-       subwindow->add_subwindow(forward_play = new PlayButton(mwindow, this, x, y)); 
+       subwindow->add_subwindow(forward_play = new PlayButton(mwindow, this, x, y));
        x += forward_play->get_w();
-       subwindow->add_subwindow(fast_play = new FastPlayButton(mwindow, this, x, y)); 
+       subwindow->add_subwindow(fast_play = new FastPlayButton(mwindow, this, x, y));
        x += fast_play->get_w();
-       subwindow->add_subwindow(end_button = new EndButton(mwindow, this, x, y)); 
+       subwindow->add_subwindow(end_button = new EndButton(mwindow, this, x, y));
        x += end_button->get_w();
 
        reverse = 0;
@@ -133,44 +133,44 @@ int PlayTransport::flip_vertical(int vertical, int &x, int &y)
 {
        if(vertical)
        {
-               rewind_button->reposition_window(x, y); 
+               rewind_button->reposition_window(x, y);
                y += rewind_button->get_h();
-               fast_reverse->reposition_window(x, y); 
+               fast_reverse->reposition_window(x, y);
                y += fast_reverse->get_h();
-               reverse_play->reposition_window(x, y); 
+               reverse_play->reposition_window(x, y);
                y += reverse_play->get_h();
-               frame_reverse_play->reposition_window(x, y); 
+               frame_reverse_play->reposition_window(x, y);
                y += frame_reverse_play->get_h();
-               stop_button->reposition_window(x, y); 
+               stop_button->reposition_window(x, y);
                y += stop_button->get_h();
-               frame_forward_play->reposition_window(x, y); 
+               frame_forward_play->reposition_window(x, y);
                y += frame_forward_play->get_h();
-               forward_play->reposition_window(x, y); 
+               forward_play->reposition_window(x, y);
                y += forward_play->get_h();
-               fast_play->reposition_window(x, y); 
+               fast_play->reposition_window(x, y);
                y += fast_play->get_h();
-               end_button->reposition_window(x, y); 
+               end_button->reposition_window(x, y);
                y += end_button->get_h();
        }
        else
        {
-               rewind_button->reposition_window(x, y - 2); 
+               rewind_button->reposition_window(x, y - 2);
                x += rewind_button->get_w();
-               fast_reverse->reposition_window(x, y - 2); 
+               fast_reverse->reposition_window(x, y - 2);
                x += fast_reverse->get_w();
-               reverse_play->reposition_window(x, y - 2); 
+               reverse_play->reposition_window(x, y - 2);
                x += reverse_play->get_w();
-               frame_reverse_play->reposition_window(x, y - 2); 
+               frame_reverse_play->reposition_window(x, y - 2);
                x += frame_reverse_play->get_w();
-               stop_button->reposition_window(x, y - 2); 
+               stop_button->reposition_window(x, y - 2);
                x += stop_button->get_w();
-               frame_forward_play->reposition_window(x, y - 2); 
+               frame_forward_play->reposition_window(x, y - 2);
                x += frame_forward_play->get_w();
-               forward_play->reposition_window(x, y - 2); 
+               forward_play->reposition_window(x, y - 2);
                x += forward_play->get_w();
-               fast_play->reposition_window(x, y - 2); 
+               fast_play->reposition_window(x, y - 2);
                x += fast_play->get_w();
-               end_button->reposition_window(x, y - 2); 
+               end_button->reposition_window(x, y - 2);
                x += end_button->get_w();
        }
 
@@ -180,74 +180,55 @@ int PlayTransport::flip_vertical(int vertical, int &x, int &y)
 int PlayTransport::keypress_event()
 {
        int result = 1;
-       if(subwindow->shift_down())
-       {
-               switch(subwindow->get_keypress())
-               {
-                       case END:
-                               subwindow->lock_window("PlayTransport::keypress_event 1");
-                               goto_end();                                   
-                               subwindow->unlock_window();
-                               break;
-                       case HOME:
-                               subwindow->lock_window("PlayTransport::keypress_event 2");
-                               goto_start();                                 
-                               subwindow->unlock_window();
-                               break;
-                       default:
-                               result = 0;
-                               break;
-               }
+       int key = subwindow->get_keypress();
+// unqualified keys, still holding lock
+       switch( key ) {
+       case HOME:
+               goto_start();
+               return result;
+       case END:
+               goto_end();
                return result;
        }
 
-// Set playback range to in/out points if CTRL is down
-       int use_inout = 0;
-       if(subwindow->ctrl_down())
-       {
-               use_inout = 1;
-       }
+       int toggle_audio = subwindow->shift_down() ? 1 : 0;
+       int use_inout = subwindow->ctrl_down() ? 1 : 0;
+       int command = -1, prev_command = engine->command->command;
        using_inout = use_inout;
        subwindow->unlock_window();
 
-
-       switch(subwindow->get_keypress())
-       {
-               case KPPLUS:    handle_transport(FAST_REWIND, 0, use_inout);            break;
-               case KP6:       handle_transport(NORMAL_REWIND, 0, use_inout);          break;
-               case KP5:       handle_transport(SLOW_REWIND, 0, use_inout);            break;
-               case KP4:       handle_transport(SINGLE_FRAME_REWIND, 0, use_inout);    break;
-               case KP1:       handle_transport(SINGLE_FRAME_FWD, 0, use_inout);       break;
-               case KP2:       handle_transport(SLOW_FWD, 0, use_inout);               break;
-               case KP3:       handle_transport(NORMAL_FWD, 0, use_inout);             break;
-               case KPENTER:   handle_transport(FAST_FWD, 0, use_inout);               break;
-               case KPINS:     handle_transport(STOP, 0, use_inout);                   break;
-               case ' ': {
-                       int prev_command = engine->command->command;
-                       int new_command = prev_command == COMMAND_NONE ||
-                                       prev_command == CURRENT_FRAME ||
-                                       prev_command == PAUSE ||
-                                       prev_command == STOP ? NORMAL_FWD : STOP;
-                               handle_transport(new_command, 0, use_inout);            break;
-                         }
-               case 'k':       handle_transport(STOP, 0, use_inout);                   break;
-               case END:
-                       subwindow->lock_window("PlayTransport::keypress_event 3");
-                       goto_end();                                   
-                       subwindow->unlock_window();
-                       break;
-               case HOME:
-                       subwindow->lock_window("PlayTransport::keypress_event 4");
-                       goto_start();                                 
-                       subwindow->unlock_window();
+       switch( key ) {
+       case 'k':
+       case KPINS:     command = STOP;                 break;
+       case KPPLUS:    command = FAST_REWIND;          break;
+       case KP6:       command = NORMAL_REWIND;        break;
+       case KP5:       command = SLOW_REWIND;          break;
+       case KP4:       command = SINGLE_FRAME_REWIND;  break;
+       case KP1:       command = SINGLE_FRAME_FWD;     break;
+       case KP2:       command = SLOW_FWD;             break;
+       case KP3:       command = NORMAL_FWD;           break;
+       case KPENTER:   command = FAST_FWD;             break;
+       case ' ':
+               switch( prev_command ) {
+               case COMMAND_NONE:
+               case CURRENT_FRAME:
+               case PAUSE:
+               case STOP:
+                       command = NORMAL_FWD;
                        break;
                default:
-                       result = 0; 
+                       command = STOP;
                        break;
+               }
+               break;
+       default:
+               result = 0;
+               break;
        }
+       if( command >= 0 )
+               handle_transport(command, 0, use_inout, 1, toggle_audio);
 
        subwindow->lock_window("PlayTransport::keypress_event 5");
-
        return result;
 }
 
@@ -264,116 +245,77 @@ void PlayTransport::goto_end()
 
 
 
-void PlayTransport::handle_transport(int command, 
-       int wait_tracking,
-       int use_inout,
-       int update_refresh)
+void PlayTransport::handle_transport(int command,
+       int wait_tracking, int use_inout, int update_refresh, int toggle_audio)
 {
-       if(!get_edl()) return;
+       if( !get_edl() ) return;
 
 // Stop requires transferring the output buffer to a refresh buffer.
        int do_stop = 0;
+       int resume = 0;
 //printf("PlayTransport::handle_transport 1 %d\n", command);
        int prev_command = engine->command->command;
-       int prev_direction = engine->command->get_direction();
        int prev_single_frame = engine->command->single_frame();
+       int prev_audio = engine->command->audio_toggle ?
+                !prev_single_frame : prev_single_frame;
+       int cur_single_frame = TransportCommand::single_frame(command);
+       int cur_audio = toggle_audio ?
+                !cur_single_frame : cur_single_frame;
 
 // Dispatch command
-       switch(command)
-       {
-// Commands that play back
-               case FAST_REWIND:
-               case NORMAL_REWIND:
-               case SLOW_REWIND:
-               case SINGLE_FRAME_REWIND:
-               case SINGLE_FRAME_FWD:
-               case SLOW_FWD:
-               case NORMAL_FWD:
-               case FAST_FWD:
-// Same direction pressed twice.  Stop
-                       if(prev_command == command && 
-                               !prev_single_frame)
-                       {
-                               do_stop = 1;
-                       }
-                       else
+       switch(command) {
+       case FAST_REWIND:       // Commands that play back
+       case NORMAL_REWIND:
+       case SLOW_REWIND:
+       case SINGLE_FRAME_REWIND:
+       case SINGLE_FRAME_FWD:
+       case SLOW_FWD:
+       case NORMAL_FWD:
+       case FAST_FWD:
+               if( !prev_single_frame &&
+                   prev_command == command &&
+                   cur_audio == prev_audio ) {
+// Same direction pressed twice and no change in audio state,  Stop
+                       do_stop = 1;
+                       break;
+               }
 // Resume or change direction
-                       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,
-                                       0,
-                                       0);
-                               engine->interrupt_playback(wait_tracking);
-                               engine->que->send_command(command,
-                                       CHANGE_NONE, 
-                                       get_edl(),
-                                       1,
-                                       1,
-                                       use_inout);
-                       }
-                       else
+               switch( prev_command ) {
+               default:
+                       engine->que->send_command(STOP, CHANGE_NONE, 0, 0, 0, 0);
+                       engine->interrupt_playback(wait_tracking);
+                       resume = 1;
+// fall through
+               case STOP:
+               case COMMAND_NONE:
+               case SINGLE_FRAME_FWD:
+               case SINGLE_FRAME_REWIND:
 // Start from scratch
-                       {
-                               engine->que->send_command(command,
-                                       CHANGE_NONE, 
-                                       get_edl(),
-                                       1,
-                                       0,
-                                       use_inout);
-                       }
+                       engine->que->send_command(command, CHANGE_NONE, get_edl(),
+                               1, resume, use_inout, toggle_audio);
                        break;
+               }
+               break;
 
 // Commands that stop
-               case STOP:
-                       do_stop = 1;
-                       break;
+       case STOP:
+               do_stop = 1;
+               break;
 
-               case REWIND:
-               case GOTO_END:
-                       engine->que->send_command(STOP,
-                               CHANGE_NONE, 
-                               0,
-                               0,
-                               0,
-                               0);
+       case REWIND:
+       case GOTO_END:
+               engine->que->send_command(STOP, CHANGE_NONE, 0, 0, 0, 0);
                        engine->interrupt_playback(wait_tracking);
                        break;
        }
 
-       if(do_stop)
-       {
-               engine->que->send_command(STOP,
-                       CHANGE_NONE, 
-                       0,
-                       0,
-                       0,
-                       0);
+       if( do_stop ) {
+               engine->que->send_command(STOP, CHANGE_NONE, 0, 0, 0, 0);
                engine->interrupt_playback(wait_tracking);
-// This is necessary to get an OpenGL output buffer
-// printf("PlayTransport::handle_transport 2 update_refresh=%d prev_command=%d prev_direction=%d\n", 
-// update_refresh, prev_command, prev_direction);
-               if(!prev_single_frame && 
-                       update_refresh &&
-                       prev_command != STOP &&
-                       prev_command != COMMAND_NONE)
-               {
-                       engine->que->send_command(
-                               (prev_direction == PLAY_FORWARD) ? SINGLE_FRAME_REWIND : SINGLE_FRAME_FWD,
-                               CHANGE_NONE, 
-                               get_edl(),
-                               1,
-                               0,
-                               0);
-               }
        }
 }
 
+
 EDL* PlayTransport::get_edl()
 {
        return mwindow->edl;
@@ -429,11 +371,11 @@ int RewindButton::handle_event()
 }
 
 FastReverseButton::FastReverseButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
- : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("fastrev")) 
+ : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("fastrev"))
 {
        set_tooltip(_("Fast reverse ( + )"));
 }
-int FastReverseButton::handle_event() 
+int FastReverseButton::handle_event()
 {
        unlock_window();
        transport->handle_transport(FAST_REWIND, 0, ctrl_down());
@@ -444,7 +386,7 @@ int FastReverseButton::handle_event()
 // Reverse playback normal speed
 
 ReverseButton::ReverseButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
- : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("reverse")) 
+ : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("reverse"))
 {
        set_tooltip(_("Normal reverse ( 6 )"));
 }
@@ -474,7 +416,7 @@ int FrameReverseButton::handle_event()
 // forward playback normal speed
 
 PlayButton::PlayButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
- : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("play")) 
+ : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("play"))
 {
        set_tooltip(_("Normal forward ( 3 )"));
 }
@@ -491,7 +433,7 @@ int PlayButton::handle_event()
 // forward playback one frame
 
 FramePlayButton::FramePlayButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
- : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("framefwd")) 
+ : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("framefwd"))
 {
        set_tooltip(_("Frame forward ( 1 )"));
 }
@@ -506,11 +448,11 @@ int FramePlayButton::handle_event()
 
 
 FastPlayButton::FastPlayButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
- : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("fastfwd")) 
+ : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("fastfwd"))
 {
        set_tooltip(_("Fast forward ( Enter )"));
 }
-int FastPlayButton::handle_event() 
+int FastPlayButton::handle_event()
 {
        unlock_window();
        transport->handle_transport(FAST_FWD, 0, ctrl_down());
@@ -519,12 +461,12 @@ int FastPlayButton::handle_event()
 }
 
 EndButton::EndButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
- : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("end")) 
+ : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("end"))
 {
        set_tooltip(_("Jump to end ( End )"));
 }
 int EndButton::handle_event()
-{      
+{
 //     unlock_window();
        transport->goto_end();
 //     lock_window();
@@ -532,7 +474,7 @@ int EndButton::handle_event()
 }
 
 StopButton::StopButton(MWindow *mwindow, PlayTransport *transport, int x, int y)
- : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("stop")) 
+ : PTransportButton(mwindow, transport, x, y, mwindow->theme->get_image_set("stop"))
 {
        set_tooltip(_("Stop ( 0 )"));
 }