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

export.cc

Go to the documentation of this file.
00001 /*
00002 * export.cc Export Mode Base Object
00003 * Copyright (C) 2002 Mads Bondo Dydensborg <madsdyd@challenge.dk>
00004 * Copyright (C) 2001-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 #include <vector>
00027 using std::cerr;
00028 using std::endl;
00029 
00030 #include <math.h>
00031 #include <unistd.h>
00032 
00033 #include "export.h"
00034 #include "page_editor.h"
00035 
00036 static void on_tool_change( GtkOptionMenu *optionmenu, gpointer user_data )
00037 {
00038     if ( gtk_option_menu_get_history( optionmenu ) == 2 )
00039         ( ( Export * ) user_data ) ->selectScene( common->getCurrentScene( ) );
00040     else
00041         ( ( Export * ) user_data ) ->selectSection( gtk_option_menu_get_history( optionmenu ) );
00042 }
00043 
00048 Export::Export( PageExport *_exportPage, KinoCommon *_common ) :
00049         actions( EXPORT_SCENE_LIST ), exportPage( _exportPage ), common( _common )
00050 {
00051     menuRange = GTK_OPTION_MENU( lookup_widget( exportPage->getWidget(), "optionmenu_export_range" ) );
00052 
00053     startSpin = GTK_SPIN_BUTTON( lookup_widget( exportPage->getWidget(), "spinbutton_export_range_start" ) );
00054     startEntry = GTK_ENTRY( lookup_widget( exportPage->getWidget(), "entry_export_start" ) );
00055     endSpin = GTK_SPIN_BUTTON( lookup_widget( exportPage->getWidget(), "spinbutton_export_range_end" ) );
00056     endEntry = GTK_ENTRY( lookup_widget( exportPage->getWidget(), "entry_export_end" ) );
00057     everySpin = GTK_SPIN_BUTTON( lookup_widget( exportPage->getWidget(), "spinbutton_export_range_every" ) );
00058 
00059     gtk_option_menu_set_history( menuRange, 0 );
00060     selectSection( 0 );
00061     g_signal_connect( G_OBJECT( menuRange ), "changed", G_CALLBACK( on_tool_change ), this );
00062 
00063 
00064     /* Get pointers to the common control buttons (bottom of page) */
00065     previewButton
00066     = GTK_TOGGLE_BUTTON( lookup_widget( common->getWidget(),
00067                                         "togglebutton_export_preview" ) );
00068     exportButton
00069     = GTK_TOGGLE_BUTTON( lookup_widget( common->getWidget(),
00070                                         "togglebutton_export_export" ) );
00071     stopButton
00072     = GTK_TOGGLE_BUTTON( lookup_widget( common->getWidget(),
00073                                         "togglebutton_export_stop" ) );
00074     pauseButton
00075     = GTK_TOGGLE_BUTTON( lookup_widget( common->getWidget(),
00076                                         "togglebutton_export_pause" ) );
00077 
00078 }
00079 
00088 void Export::startExport( bool preview )
00089 {
00090     bool supports_preview = actions & EXPORT_PREVIEW;
00091     bool supports_export = actions & EXPORT_EXPORT;
00092     bool supports_pause = actions & EXPORT_PAUSE;
00093 
00094     /* Make sure the user can only click relevant buttons
00095      exportPage->exportMutex is a protection against the buttons going
00096      into a wild events generating loop. */
00097     exportPage->exportMutex = true;
00098     /* When exporting, export is pressed and can not be pressed
00099        pause and stop can be pressed, preview can not */
00100     gtk_toggle_button_set_active( previewButton, FALSE );
00101     gtk_widget_set_sensitive( GTK_WIDGET( previewButton ), FALSE );
00102 
00103     gtk_toggle_button_set_active( exportButton, TRUE );
00104     gtk_widget_set_sensitive( GTK_WIDGET( exportButton ), FALSE );
00105 
00106     gtk_toggle_button_set_active( stopButton, FALSE );
00107     gtk_widget_set_sensitive( GTK_WIDGET( stopButton ), TRUE );
00108 
00109     gtk_toggle_button_set_active( pauseButton, FALSE );
00110     gtk_widget_set_sensitive( GTK_WIDGET( pauseButton ), supports_pause );
00111     exportPage->exportMutex = false;
00112 
00113     /* Make the tabbed notebook inaccesible during export */
00114     GtkNotebook * tmp =
00115         GTK_NOTEBOOK( lookup_widget( common->getWidget(), "notebook_export" ) );
00116     if ( !tmp )
00117     {
00118         cerr << "Export::startExport. Unable to access the notebook_export widget!"
00119         << endl;
00120     }
00121     else
00122     {
00123         gtk_widget_set_sensitive ( GTK_WIDGET( tmp ), FALSE );
00124     }
00125 
00126     GtkWidget * tmpframe
00127     = GTK_WIDGET ( lookup_widget ( common->getWidget(), "vbox_export_range" ) );
00128     if ( !tmpframe )
00129     {
00130         cerr << "Export::startExport. Unable to acces the frame_export_range widget!"
00131         << endl;
00132     }
00133     else
00134     {
00135         gtk_widget_set_sensitive ( GTK_WIDGET( tmpframe ), FALSE );
00136     }
00137 
00138 
00139     /* Allow gtk to handle pending events - I am not sure this is strictly
00140        needed, but there seems to be some lag from pressing buttons until
00141        their state is updated.... this might help. */
00142     while ( gtk_events_pending() )
00143     {
00144         gtk_main_iteration();
00145     }
00146 
00147     /* Get a temporary playlist */
00148     PlayList playlist( *( common->getPlayList() ) );
00149 
00150     /* Set begin, end and every based on the range selections */
00151     int begin = 0;
00152     int end = 0;
00153     int every = 1;
00154 
00155     switch ( gtk_option_menu_get_history( menuRange ) )
00156     {
00157     case 0:
00158         begin = 0;
00159         end = common->getPlayList() ->GetNumFrames() - 1;
00160         break;
00161     case 1:
00162         begin = end = common->g_currentFrame;
00163         break;
00164     case 2:
00165         begin = gtk_spin_button_get_value_as_int( startSpin );
00166         end = gtk_spin_button_get_value_as_int( endSpin );
00167         break;
00168     }
00169     every = gtk_spin_button_get_value_as_int( everySpin );
00170 
00171     /* Reset the progess stuff */
00172     exportPage->resetProgress();
00173 
00174     /* Reset the time measuring stuff */
00175     startTime = 0.0;
00176     pauseTime = 0.0;
00177 
00178     /* Reset the statusmessage */
00179     common->setStatusBar( _( "Starting export" ) );
00180 
00181     /* Do the actual work */
00182     enum export_result status = doExport( &playlist, begin, end, every, preview );
00183 
00184     struct timeval tv;
00185     if ( 0 != gettimeofday( &tv, NULL ) )
00186     {
00187         cerr << ">>> Export::startExport - error calling gettimeofday?" << endl;
00188     }
00189 
00190 
00191     double now = tv.tv_sec + tv.tv_usec / 1000000.0;
00192     char buf[ 17 ];
00193     string message;
00194     //snprintf(buf, 512, "Export finished/failed/stopped - time: %s",
00195     //   formatSecs(buf1, 16, now - startTime));
00196     switch ( status )
00197     {
00198     case EXPORT_RESULT_SUCCESS:
00199         message = _( "Export finished - time: " );
00200         break;
00201     case EXPORT_RESULT_FAILURE:
00202         message = _( "Export failed - time: " );
00203         break;
00204     case EXPORT_RESULT_ABORT:
00205         message = _( "Export stopped - time: " );
00206         break;
00207     }
00208     message += formatSecs( buf, 16, now - startTime );
00209     common->setStatusBar( message.c_str() );
00210 
00211 
00212     /* Enable the common controls and buttons again */
00213     if ( tmp )
00214     {
00215         gtk_widget_set_sensitive ( GTK_WIDGET( tmp ), TRUE );
00216     }
00217     if ( tmpframe )
00218     {
00219         gtk_widget_set_sensitive ( GTK_WIDGET( tmpframe ), TRUE );
00220     }
00221 
00222     /* Set the progess to 100% - even in case of errors - the process have
00223        stopped.... */
00224     exportPage->updateProgress( ( gfloat ) 1.0 );
00225 
00226     /* Set the buttons to allow a new export session.
00227        export is available
00228        stop is pressed, but not available
00229        pause is not available
00230     */
00231     exportPage->exportMutex = true;
00232 
00233     gtk_toggle_button_set_active( previewButton, FALSE );
00234     gtk_widget_set_sensitive( GTK_WIDGET( previewButton ), supports_preview );
00235 
00236     gtk_toggle_button_set_active( exportButton, FALSE );
00237     gtk_widget_set_sensitive( GTK_WIDGET( exportButton ), supports_export );
00238 
00239     gtk_toggle_button_set_active( stopButton, TRUE );
00240     gtk_widget_set_sensitive( GTK_WIDGET( stopButton ), FALSE );
00241 
00242     gtk_toggle_button_set_active( pauseButton, FALSE );
00243     gtk_widget_set_sensitive( GTK_WIDGET( pauseButton ), FALSE );
00244     exportPage->exportMutex = false;
00245 
00246     /* We are no longer exporting at this point */
00247     exportPage->isExporting = false;
00248 
00249     while ( gtk_events_pending() )
00250     {
00251         gtk_main_iteration();
00252     }
00253 
00254 }
00255 
00256 
00265 gulong Export::onActivate()
00266 {
00267     return EXPORT_SCENE_LIST | EXPORT_EXPORT | EXPORT_PAUSE;
00268 }
00269 
00270 /* I am not sure I have seen any pages do anything in deactivate */
00271 gulong Export::onDeactivate()
00272 {
00273     return 0;
00274 }
00275 
00283 gulong Export::activate()
00284 {
00285     actions = onActivate();
00286 
00287     selectSection( gtk_option_menu_get_history( menuRange ) );
00288     /* Adjust on from-to range
00289        start: */
00290     GtkAdjustment *adjust = gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON( startSpin ) );
00291     adjust->lower = 0;
00292     adjust->upper = common->getPlayList() ->GetNumFrames() - 1;
00293     g_signal_emit_by_name( adjust, "changed" );
00294     if ( adjust->value > adjust->upper )
00295     {
00296         gtk_adjustment_set_value ( adjust, adjust->upper );
00297     }
00298     /* end: */
00299     adjust
00300     = gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON( endSpin ) );
00301     adjust->lower = 0;
00302     adjust->upper = common->getPlayList() ->GetNumFrames() - 1;
00303     g_signal_emit_by_name( adjust, "changed" );
00304     if ( adjust->value > adjust->upper )
00305     {
00306         gtk_adjustment_set_value ( adjust, adjust->upper );
00307     }
00308 
00309     /* Enable/disable common buttons */
00310     bool supports_preview = actions & EXPORT_PREVIEW;
00311     bool supports_export = actions & EXPORT_EXPORT;
00312     // bool supports_pause   = tmp & EXPORT_PAUSE;
00313     /* Adjust to reasonable standard */
00314     exportPage->exportMutex = true;
00315     if ( exportPage->isExporting )
00316     {
00317         /* Not good, we should locked on a page when exporting */
00318         cerr << ">>> Export::activate() internal error: "
00319         << "called with exportPage->isExporting!" << endl;
00320         /* Hmm. We should not change _anything_ when exporting. Really... */
00321         /* Only stop and pause should be available - if pausing, pause should
00322            be pressed
00323            TODO: we do not really know when we are previewing...
00324         */
00325         /*
00326           This code have been left here, until it is certain that the current
00327           solution where the user can not change to another export page during
00328           export, is acceptable to all parties.
00329         gtk_toggle_button_set_active( previewButton, FALSE );
00330         gtk_widget_set_sensitive( GTK_WIDGET(previewButton), supports_preview );
00331 
00332         gtk_toggle_button_set_active( exportButton, TRUE );
00333         gtk_widget_set_sensitive( GTK_WIDGET(exportButton), FALSE );
00334 
00335         gtk_toggle_button_set_active( stopButton, FALSE );
00336         gtk_widget_set_sensitive( GTK_WIDGET(stopButton), TRUE );
00337 
00338         gtk_toggle_button_set_active( pauseButton, exportPage->isPausing );
00339         gtk_widget_set_sensitive( GTK_WIDGET(pauseButton), supports_pause );
00340         */
00341     }
00342     else
00343     {
00344         /* At most preview and export available */
00345         gtk_toggle_button_set_active( previewButton, FALSE );
00346         gtk_widget_set_sensitive( GTK_WIDGET( previewButton ), supports_preview );
00347 
00348         gtk_toggle_button_set_active( exportButton, FALSE );
00349         gtk_widget_set_sensitive( GTK_WIDGET( exportButton ), supports_export );
00350 
00351         gtk_toggle_button_set_active( stopButton, TRUE );
00352         gtk_widget_set_sensitive( GTK_WIDGET( stopButton ), FALSE );
00353 
00354         gtk_toggle_button_set_active( pauseButton, FALSE );
00355         gtk_widget_set_sensitive( GTK_WIDGET( pauseButton ), FALSE );
00356     }
00357     exportPage->exportMutex = false;
00358 
00359 
00360     /* TODO: Activate and deactive buttons as needed */
00361     cerr << ">> Export::activate()" << endl;
00362     if ( EXPORT_SCENE_LIST & actions )
00363     {
00364         // cerr << "Export::activate() - SCENE_LIST" << endl;
00365         return SCENE_LIST;
00366     }
00367     else
00368     {
00369         // cerr << "Export::activate() - NO SCENE_LIST" << endl;
00370         return 0;
00371     }
00372 }
00373 gulong Export::deactivate()
00374 {
00375     cerr << "Export::deactivate()" << endl;
00376     if ( EXPORT_SCENE_LIST & onDeactivate() )
00377     {
00378         // cerr << "Export::deactivate() - SCENE_LIST" << endl;
00379         return SCENE_LIST;
00380     }
00381     else
00382     {
00383         // cerr << "Export::deactivate() - NO SCENE_LIST" << endl;
00384         return 0;
00385     }
00386 }
00387 
00390 void Export::start()
00391 {
00392     cerr << ">>> Export::start()" << endl;
00393 }
00394 void Export::clean()
00395 {
00396     cerr << ">>> Export::clean()" << endl;
00397 }
00398 
00408 void Export::selectScene( int i )
00409 {
00410     cerr << ">>> Export::selectScene() " << i << endl;
00411     /* Sanity check */
00412     if ( !( EXPORT_SCENE_LIST & actions ) )
00413     {
00414         cerr << ">>> Export::selectScene: internal consistency error. "
00415         << "selectScene, even though page does not support scene list " << actions << endl;
00416         return ;
00417     }
00418     if ( exportPage->isExporting )
00419         return;
00420     
00421     /* Set the start selection spinner */
00422     GtkAdjustment *adjust = gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON( startSpin ) );
00423 
00424     vector <int> scene = common->getPageEditor() ->GetScene();
00425 
00426     if ( scene.size( ) != 0 )
00427     {
00428         int begin = 0;
00429         int end = 0;
00430 
00431         begin = i == 0 ? 0 : scene[ i - 1 ];
00432         adjust->lower = 0;
00433         adjust->upper = scene[ scene.size() - 1 ] - 1;
00434         gtk_spin_button_set_value( GTK_SPIN_BUTTON( startSpin ), begin );
00435         g_signal_emit_by_name( adjust, "changed" );
00436 
00437         /* Set the end selection spinner */
00438         adjust = gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON( endSpin ) );
00439         adjust->lower = 0;
00440         adjust->upper = scene[ scene.size() - 1 ] - 1;
00441         end = scene[ i ] - 1;
00442         gtk_spin_button_set_value( GTK_SPIN_BUTTON( endSpin ), end );
00443         g_signal_emit_by_name( adjust, "changed" );
00444         Frame &frame = *( GetFramePool( ) ->GetFrame( ) );
00445         FileHandler *media;
00446         common->getPlayList() ->GetMediaObject( begin, &media );
00447         common->getPlayList() ->GetFrame( begin, frame );
00448         GetFramePool( ) ->DoneWithFrame( &frame );
00449         common->moveToFrame( begin );
00450         common->showFrameMoreInfo( frame, media );
00451         common->setCurrentScene( begin );
00452     }
00453 
00454     /* Set the range button active */
00455     if ( gtk_option_menu_get_history( menuRange ) != 2 )
00456         gtk_option_menu_set_history( menuRange, 2 );
00457     else
00458         selectSection( 2 );
00459 }
00460 
00461 void Export::selectSection( int i )
00462 {
00463     GtkWidget * label = lookup_widget( exportPage->getWidget(), "label177" );
00464     switch ( i )
00465     {
00466     case 2:
00467         gtk_widget_show( GTK_WIDGET( startSpin ) );
00468         gtk_widget_show( GTK_WIDGET( startEntry ) );
00469         gtk_widget_show( GTK_WIDGET( endSpin ) );
00470         gtk_widget_show( GTK_WIDGET( endEntry ) );
00471         gtk_widget_show( GTK_WIDGET( label ) );
00472         common->getPageExport()->timeFormatChanged();
00473         break;
00474 
00475     default:
00476         gtk_widget_hide( GTK_WIDGET( startSpin ) );
00477         gtk_widget_hide( GTK_WIDGET( startEntry ) );
00478         gtk_widget_hide( GTK_WIDGET( endSpin ) );
00479         gtk_widget_hide( GTK_WIDGET( endEntry ) );
00480         gtk_widget_hide( GTK_WIDGET( label ) );
00481         break;
00482     }
00483 }
00484 
00487 void Export::stopExport()
00488 {
00489     cerr << ">>> Export::stopExport()" << endl;
00490 }
00491 void Export::pauseExport()
00492 {
00493     cerr << ">>> Export::pauseExport()" << endl;
00494 }
00495 
00503 void Export::onRangeChange( GtkSpinButton *widget )
00504 {
00505     /* Make sure that start <= end */
00506     GtkAdjustment * startAdjust
00507     = gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON( startSpin ) );
00508     GtkAdjustment *endAdjust
00509     = gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON( endSpin ) );
00510 
00511     if ( widget == startSpin )
00512     {
00513         if ( endAdjust->value < startAdjust->value )
00514         {
00515             gtk_adjustment_set_value ( endAdjust, startAdjust->value );
00516         }
00517     }
00518     else
00519     {
00520         if ( widget == endSpin )
00521         {
00522             if ( startAdjust->value > endAdjust->value )
00523             {
00524                 gtk_adjustment_set_value ( startAdjust, endAdjust->value );
00525             }
00526         }
00527         else
00528         {
00529             cerr << ">>> Export::onRangeChange: internal error: widget passed is unknown"
00530             << endl;
00531         }
00532     }
00533 }
00534 
00535 
00539 void Export::doPause()
00540 {
00541     struct timespec ts;
00542     ts.tv_sec = 0;
00543     ts.tv_nsec = 1000 * 1000 * 20; /* 20 ms + sched overhead */
00544     while ( exportPage->isPausing )
00545     {
00546         // cerr << ">>> Export::doPause()" << endl;
00547         while ( gtk_events_pending() )
00548         {
00549             gtk_main_iteration();
00550         }
00551         /* Lets try not to hog the CPU */
00552         nanosleep( &ts, NULL );
00553     }
00554 }
00555 
00557 char * Export::formatSecs( char * buf, int size, double seconds )
00558 {
00559     int _seconds = ( int ) rint( seconds );
00560     int secs = _seconds % 60;
00561     int mins = ( _seconds / 60 ) % 60;
00562     int hours = ( _seconds / 3600 );
00563     if ( hours > 0 )
00564     {
00565         snprintf( buf, size, "%i:%02i:%02i", hours, mins, secs );
00566     }
00567     else
00568     {
00569         if ( mins > 0 )
00570         {
00571             snprintf( buf, size, "%i:%02i", mins, secs );
00572         }
00573         else
00574         {
00575             snprintf( buf, size, "%i", secs );
00576         }
00577     }
00578     return buf;
00579 }
00580 
00582 void Export::innerLoopUpdate( int progress, int begin, int end, int every,
00583         int currentFrame, const char* activity )
00584 {
00585     char buf[ 512 ];
00586     struct timeval tv;
00587     if ( 0 != gettimeofday( &tv, NULL ) )
00588     {
00589         cerr << ">>> Export::innerLoopUpdate: Error calling gettimeofday?" << endl;
00590     }
00591     double now = tv.tv_sec + tv.tv_usec / 1000000.0;
00592     gfloat com_ratio = ( gfloat ) ( progress - begin ) / ( gfloat ) ( end + 1 - begin ) ;
00593     if ( currentFrame == -1 )
00594         currentFrame = progress;
00595     /* Figure out how much time we have spend */
00596     if ( 0 == startTime )
00597     {
00598         /* First time */
00599         startTime = now;
00600         nextUpdateTime = now - 1;
00601         snprintf( buf, 512, _( "%s frame %i." ), activity, currentFrame );
00602     }
00603     else
00604     {
00605         /* Not first time
00606            We do not care to use difftime on this... */
00607         double time_so_far = now - startTime - pauseTime;
00608         double total_est = time_so_far / com_ratio;
00609         /* Write the time values into buffers */
00610         char buf1[ 16 ];
00611         char buf2[ 16 ];
00612         char buf3[ 16 ];
00613         snprintf( buf, 512, _( "%s frame %i. Time  used: %s,  estimated: %s,  left: %s" ),
00614                   activity,
00615                   currentFrame + 1,
00616                   formatSecs( buf1, 16, time_so_far ),
00617                   formatSecs( buf2, 16, total_est ),
00618                   formatSecs( buf3, 16, total_est - time_so_far ) );
00619     }
00620 
00621     /* Update status message
00622        TODO: Do filesystem checks first....
00623     */
00624     if ( now > nextUpdateTime )
00625     {
00626         common->setStatusBar( buf );
00627         nextUpdateTime = now + 0.25;
00628     }
00629 
00630     /* Update progressbar - assuming currentFrame have yet to be exported
00631        Updating the progressbar will handle any pending events. */
00632     exportPage->updateProgress( com_ratio );
00633 
00634     /* Check pause - make sure we ignore time paused in export. */
00635     if ( EXPORT_PAUSE & actions && exportPage->isPausing )
00636     {
00637         doPause();
00638         if ( 0 != gettimeofday( &tv, NULL ) )
00639         {
00640             cerr << ">>> Export::innerLoopUpdate: Error calling gettimeofday?" << endl;
00641         }
00642         double foo = tv.tv_sec + tv.tv_usec / 1000000.0;
00643         pauseTime += ( foo - now );
00644     }
00645 }
00646 
00647 double Export::calculateAdjustedRate( PlayList* playlist, double outputRate, int begin, int end, int every )
00648 {
00649     Frame& frame = *GetFramePool()->GetFrame();
00650     playlist->GetFrame( begin, frame );
00651     double seconds = double( end - begin + 1 ) / frame.GetFrameRate();
00652     int64_t idealSamples = int64_t( seconds * outputRate + 0.5 );
00653     int64_t actualSamples = 0;
00654     double adjustedRate = 0.0;
00655     struct timeval tv;
00656     if ( 0 != gettimeofday( &tv, NULL ) )
00657     {
00658         cerr << ">>> Export::calculateAdjustedRate: Error calling gettimeofday?" << endl;
00659     }
00660     double now = tv.tv_sec + tv.tv_usec / 1000000.0;
00661     double nextUpdateTime = now - 1.0;
00662     char buf[ 512 ];
00663     int n = -1, frameNum = 0;
00664     AsyncAudioResample<int16_ne_t,int16_le_t>* resampler = new AsyncAudioResample<int16_ne_t,int16_le_t>(
00665         AUDIO_RESAMPLE_SRC_SINC_FASTEST, playlist, outputRate, begin, end, every );
00666 
00667     // Determine the actual number of samples
00668     while ( exportPage->isExporting && n != 0 )
00669     {
00670         n = resampler->Process( outputRate, frame.CalculateNumberSamples( int(outputRate), frameNum++ ) );
00671         actualSamples += n;
00672 
00673         if ( 0 == gettimeofday( &tv, NULL ) )
00674         {
00675             now = tv.tv_sec + tv.tv_usec / 1000000.0;
00676             if ( now > nextUpdateTime )
00677             {
00678                 snprintf( buf, 512, "%s (%02d%%)", _("Locking audio"),
00679                     int( 100.0 * frameNum / (end - begin + 1) ) );
00680                 common->setStatusBar( buf );
00681                 nextUpdateTime = now + 1.0;
00682             }
00683         }
00684         exportPage->updateProgress( -1 );
00685 
00686         /* Check pause - make sure we ignore time paused in export. */
00687         if ( EXPORT_PAUSE & actions && exportPage->isPausing )
00688         {
00689             doPause();
00690         }
00691     }
00692     GetFramePool()->DoneWithFrame( &frame );
00693 
00694     if ( exportPage->isExporting )
00695     {
00696         // If there are less actual samples than ideal then increase the
00697         // rate to make resampler increase the number of samples.
00698 //      cerr << "calcAdjustedRate secs " << seconds << " ideal " << idealSamples << " actual " << actualSamples;
00699         adjustedRate = outputRate + ( idealSamples - actualSamples ) / seconds;
00700     }
00701 
00702     if ( 0 != gettimeofday( &tv, NULL ) )
00703         cerr << ">>> Export::innerLoopUpdate: Error calling gettimeofday?" << endl;
00704     double foo = tv.tv_sec + tv.tv_usec / 1000000.0;
00705     pauseTime += ( foo - now );
00706 
00707     cerr << ">>> output rate is " << outputRate << ", adjusted rate is " << adjustedRate << endl;
00708 
00709     return adjustedRate;
00710 }

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