Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

audio_transitions.cc

Go to the documentation of this file.
00001 /*
00002 * audio_transitions.cc -- audio transitions
00003 * Copyright (C) 2002 Charles Yates <charles.yates@pandora.be>
00004 * Copyright (C) 2002-2007 Dan Dennedy <dan@dennedy.org>
00005 *
00006 * This program is free software; you can redistribute it and/or modify
00007 * it under the terms of the GNU General Public License as published by
00008 * the Free Software Foundation; either version 2 of the License, or
00009 * (at your option) any later version.
00010 *
00011 * This program is distributed in the hope that it will be useful,
00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 * GNU General Public License for more details.
00015 *
00016 * You should have received a copy of the GNU General Public License
00017 * along with this program; if not, write to the Free Software Foundation,
00018 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00019 */
00020 
00021 #ifdef HAVE_CONFIG_H
00022 #include <config.h>
00023 #endif
00024 
00025 #include <iostream>
00026 
00027 #include <glade/glade.h>
00028 #include "audio_transitions.h"
00029 #include "page_magick.h"
00030 
00031 extern "C"
00032 {
00033 #include "support.h"
00034     extern GladeXML* magick_glade;
00035 }
00036 
00040 static void
00041 gtk_curve_reset_vector ( GtkCurve *curve )
00042 {
00043     if ( curve->ctlpoint )
00044         g_free ( curve->ctlpoint );
00045 
00046     curve->num_ctlpoints = 2;
00047     curve->ctlpoint = ( gfloat( * ) [ 2 ] ) g_malloc ( 2 * sizeof ( curve->ctlpoint[ 0 ] ) );
00048     curve->ctlpoint[ 0 ][ 0 ] = curve->min_x;
00049     curve->ctlpoint[ 0 ][ 1 ] = curve->max_y;
00050     curve->ctlpoint[ 1 ][ 0 ] = curve->max_x;
00051     curve->ctlpoint[ 1 ][ 1 ] = curve->min_y;
00052 
00053 }
00054 
00055 class AudioNone : public GDKAudioTransition
00056 {
00057 public:
00058     char *GetDescription( ) const
00059     {
00060         return _( "No Change" );
00061     }
00062 
00063     void GetFrame( int16_t **aframe, int16_t **bframe, int frequency, int channels, int& samples, double position, double frame_delta )
00064     {}
00065 };
00066 
00067 #define MAX_VECTOR 1000
00068 
00069 class AudioSwitch : public GDKAudioTransition
00070 {
00071 private:
00072     GtkWidget *window;
00073     gfloat vectorA[ MAX_VECTOR ];
00074     gfloat vectorB[ MAX_VECTOR ];
00075 
00076 
00077 public:
00078     AudioSwitch( )
00079     {
00080         window = glade_xml_get_widget( magick_glade, "window_switch" );
00081     }
00082 
00083     virtual ~AudioSwitch( )
00084     {
00085         gtk_widget_destroy( window );
00086     }
00087 
00088     char *GetDescription( ) const
00089     {
00090         return _( "Cross Fade" );
00091     }
00092 
00093     void GetFrame( int16_t **aframe, int16_t **bframe, int frequency, int channels, int& samples, double position, double frame_delta )
00094     {
00095         GtkCurve * curveA = GTK_CURVE( lookup_widget( window, "curve1" ) );
00096         GtkCurve *curveB = GTK_CURVE( lookup_widget( window, "curve2" ) );
00097         gtk_curve_get_vector( curveA, MAX_VECTOR, vectorA );
00098         gtk_curve_get_vector( curveB, MAX_VECTOR, vectorB );
00099         
00100         int pos = ( int ) ( position * MAX_VECTOR );
00101         double factorA = vectorA[ pos ];
00102         double factorB = vectorB[ pos ];
00103         if ( factorA + factorB > 1.0 )
00104         {
00105             factorA /= factorA + factorB;
00106             factorB /= factorA + factorB;
00107         }
00108         for ( int s = 0; s < samples; s ++ )
00109             for ( int c = 0; c < channels; c ++ )
00110                 aframe[ c ][ s ] = ( int16_t ) ( ( double ) aframe[ c ][ s ] * factorA + ( double ) bframe[ c ][ s ] * factorB );
00111     }
00112 
00113     void AttachWidgets( GtkBin *bin )
00114     {
00115         gtk_widget_reparent( ( GTK_BIN( window ) ) ->child, GTK_WIDGET( bin ) );
00116         GtkCurve *curveA = GTK_CURVE( lookup_widget( window, "curve1" ) );
00117         GtkCurve *curveB = GTK_CURVE( lookup_widget( window, "curve2" ) );
00118         gtk_curve_reset_vector( curveA );
00119         gtk_curve_set_curve_type( curveA, GTK_CURVE_TYPE_SPLINE );
00120         gtk_curve_set_curve_type( curveB, GTK_CURVE_TYPE_SPLINE );
00121     }
00122 
00123     void DetachWidgets( GtkBin *bin )
00124     {
00125         gtk_widget_reparent( ( GTK_BIN( bin ) ) ->child, GTK_WIDGET( window ) );
00126     }
00127 };
00128 
00132 static void
00133 on_optionmenu_selected ( GtkMenuItem *menu_item, gpointer user_data )
00134 {
00135     ( ( GDKAudioTransitionRepository * ) user_data ) ->SelectionChange();
00136 }
00137 
00143 GDKAudioTransitionRepository::GDKAudioTransitionRepository() : selected_transition( NULL ), menu( NULL ), container( NULL )
00144 {
00145     // Register an instance of each object (adapting raw transitions to GDK transitions where necessary)
00146     Register( new AudioSwitch() );
00147     Register( new AudioNone() );
00148 }
00149 
00153 GDKAudioTransitionRepository::~GDKAudioTransitionRepository()
00154 {
00155     // Remove the transitions in the repository
00156     for ( unsigned int index = 0; index < transitions.size(); index ++ )
00157         delete transitions[ index ];
00158 }
00159 
00163 void GDKAudioTransitionRepository::Register( GDKAudioTransition *transition )
00164 {
00165     std::cerr << ">>> Audio Transition: " << transition->GetDescription() << std::endl;
00166     transitions.push_back( transition );
00167 }
00168 
00172 void GDKAudioTransitionRepository::Initialise( GtkOptionMenu *menu, GtkBin *container )
00173 {
00174     // Store these for future reference
00175     this->menu = menu;
00176     this->container = container;
00177 
00178     // Add the transitions to the menu
00179     GtkMenu *menu_new = GTK_MENU( gtk_menu_new( ) );
00180     for ( unsigned int index = 0; index < transitions.size(); index ++ )
00181     {
00182         GtkWidget *item = gtk_menu_item_new_with_label( transitions[ index ] ->GetDescription( ) );
00183         gtk_widget_show( item );
00184         gtk_menu_append( menu_new, item );
00185         g_signal_connect( G_OBJECT( item ), "activate", G_CALLBACK( on_optionmenu_selected ), this );
00186     }
00187     gtk_menu_set_active( menu_new, 0 );
00188     gtk_option_menu_set_menu( menu, GTK_WIDGET( menu_new ) );
00189 
00190     // Register the selected items widgets
00191     SelectionChange();
00192 }
00193 
00197 GDKAudioTransition *GDKAudioTransitionRepository::Get( ) const
00198 {
00199     GtkMenu * transitionMenu = GTK_MENU( gtk_option_menu_get_menu( menu ) );
00200     GtkWidget *active_item = gtk_menu_get_active( transitionMenu );
00201     return transitions[ g_list_index( GTK_MENU_SHELL( transitionMenu ) ->children, active_item ) ];
00202 }
00203 
00207 void GDKAudioTransitionRepository::SelectionChange( )
00208 {
00209     bool isPreviewing = false;
00210     PageMagick* magick = 0;
00211 
00212     if ( common && common->getPageMagick( ) )
00213         magick = common->getPageMagick( );
00214     if ( magick && magick->IsPreviewing() )
00215     {
00216         isPreviewing = true;
00217         magick->StopPreview();
00218     }
00219 
00220     // Detach the selected transitions widgets
00221     if ( selected_transition != NULL )
00222         selected_transition->DetachWidgets( container );
00223 
00224     // Get the new selection
00225     selected_transition = Get();
00226 
00227     // Attach the new transitions widgets
00228     if ( selected_transition != NULL )
00229         selected_transition->AttachWidgets( container );
00230 
00231     if ( magick )
00232     {
00233         if ( isPreviewing )
00234             magick->StartPreview();
00235         else
00236             magick->PreviewFrame();
00237     }
00238 }

Generated on Sun Mar 11 22:11:44 2007 for Kino by  doxygen 1.4.2