00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef HAVE_CONFIG_H
00021 #include <config.h>
00022 #endif
00023
00024 #include <vector>
00025 #include <iostream>
00026 using std::cerr;
00027 using std::endl;
00028 #include <string>
00029
00030 #include <gtk/gtk.h>
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033
00034 #include "kino_av_pipe.h"
00035 #include "page_export_audio.h"
00036 #include "preferences.h"
00037 #include "kino_common.h"
00038 #include "frame.h"
00039 #include "page_editor.h"
00040 #include "message.h"
00041
00042
00048 ExportAudio::ExportAudio( PageExport *_exportPage, KinoCommon *_common ) :
00049 Export( _exportPage, _common )
00050 {
00051 cerr << "> Creating ExportAudio Page" << endl;
00052 fileEntry = GTK_ENTRY( lookup_widget( common->getWidget(), "entry_export_audio_file" ) );
00053
00054 sampleRate
00055 = GTK_MENU( gtk_option_menu_get_menu( GTK_OPTION_MENU( lookup_widget( exportPage->getWidget(),
00056 "optionmenu_export_audio_sampling" ) ) ) );
00057 audioFormat
00058 = GTK_MENU( gtk_option_menu_get_menu( GTK_OPTION_MENU( lookup_widget( exportPage->getWidget(),
00059 "optionmenu_export_audio_format" ) ) ) );
00060 splitCheck
00061 = GTK_TOGGLE_BUTTON( lookup_widget( exportPage->getWidget(),
00062 "checkbutton_export_audio_split" ) );
00063 }
00064
00068 ExportAudio::~ExportAudio()
00069 {
00070 cerr << "> Destroying ExportAudio Page" << endl;
00071 }
00072
00075 enum export_result
00076 ExportAudio::doExport( PlayList * playlist, int begin, int end, int every,
00077 bool preview )
00078 {
00079 cerr << ">>> ExportAudio::doExport" << endl;
00080 Frame& frame = *GetFramePool()->GetFrame();
00081 gchar *file = NULL;
00082 enum export_result status = EXPORT_RESULT_SUCCESS;
00083
00084
00085 file = g_strdup( gtk_entry_get_text( fileEntry ) );
00086 if ( !( strcmp( file, "" ) && strpbrk( file, "\'" ) == NULL ) )
00087 {
00088 modal_message( _( "You must enter a filename which does not contain quotes." ) );
00089 g_free( file );
00090 return EXPORT_RESULT_FAILURE;
00091 }
00092
00093
00094
00095 playlist->GetFrame( begin, frame );
00096
00097 AudioInfo info;
00098 frame.GetAudioInfo( info );
00099 short channels = info.channels;
00100 int outputFrequency = info.frequency;
00101 bool splitScene = gtk_toggle_button_get_active( splitCheck );
00102
00103
00104 GtkWidget *active_item = gtk_menu_get_active( sampleRate );
00105 int menuValue = g_list_index ( GTK_MENU_SHELL ( sampleRate ) ->children,
00106 active_item );
00107 if ( menuValue == 1 )
00108 outputFrequency = 32000;
00109 else if ( menuValue == 2 )
00110 outputFrequency = 44100;
00111 else if ( menuValue == 3 )
00112 outputFrequency = 48000;
00113
00114
00115 active_item = gtk_menu_get_active( audioFormat );
00116 menuValue = g_list_index ( GTK_MENU_SHELL ( audioFormat ) ->children, active_item );
00117
00118 gchar *outputtemplate = NULL;
00119 kino_audio_pipe type = PIPE_AUDIO_WAV;
00120
00121 if ( menuValue == 0 )
00122 {
00123 outputtemplate = g_strdup_printf( "%s%%s.wav", file );
00124 type = PIPE_AUDIO_WAV;
00125 }
00126 else if ( menuValue == 1 )
00127 {
00128 outputtemplate = g_strdup_printf( "| sox -t .raw -r %d -c 2 -w -s - \'%s\'%%s.wav",
00129 outputFrequency, file );
00130 type = PIPE_AUDIO_WAV;
00131 }
00132 else if ( menuValue == 2 )
00133 {
00134 outputtemplate = g_strdup_printf( "| mp2enc -r %d -o \'%s\'%%s.mp2",
00135 outputFrequency, file );
00136 type = PIPE_AUDIO_WAV;
00137 }
00138 else if ( menuValue == 3 )
00139 {
00140 outputtemplate = g_strdup_printf( "| lame -r -s %d -x - -o \'%s\'%%s.mp3",
00141 outputFrequency / 1000, file );
00142 type = PIPE_AUDIO_PCM;
00143 }
00144 else if ( menuValue == 4 )
00145 {
00146 outputtemplate = g_strdup_printf( "| oggenc - -o \'%s\'%%s.ogg", file );
00147 type = PIPE_AUDIO_WAV;
00148 }
00149
00150
00151 KinoAudioPipe *outputPipe = KinoAudioFactory::CreateAudioPipe( type );
00152 int scene = 0;
00153 for ( int sceneBegin = begin; sceneBegin <= end && exportPage->isExporting;
00154 scene ++ )
00155 {
00156 gchar *full;
00157 char sceneString[ 5 ];
00158 int sceneEnd = end;
00159
00160
00161 if ( splitScene )
00162 {
00163 sprintf( sceneString, "%03d", scene );
00164 sceneEnd = playlist->FindEndOfScene( sceneBegin );
00165 if ( sceneEnd > end )
00166 sceneEnd = end;
00167 }
00168 else
00169 {
00170 strcpy( sceneString, "" );
00171 }
00172
00173
00174 full = g_strdup_printf( outputtemplate, sceneString );
00175
00176
00177 bool active = outputPipe->OpenAudio( full, channels, outputFrequency, 2 );
00178 g_free( full );
00179
00180 if ( active )
00181 {
00182
00183
00184
00185 innerLoopUpdate( sceneBegin, begin, end, every );
00186
00187
00188 double adjustedRate = calculateAdjustedRate( playlist, outputFrequency, sceneBegin, sceneEnd, every );
00189 if ( ! adjustedRate )
00190 status = EXPORT_RESULT_ABORT;
00191
00192
00193 AsyncAudioResample<int16_ne_t,int16_le_t>* resampler = new AsyncAudioResample<int16_ne_t,int16_le_t>(
00194 AUDIO_RESAMPLE_SRC_SINC_BEST_QUALITY, playlist, outputFrequency, sceneBegin, sceneEnd, every );
00195 if ( resampler->IsError() )
00196 {
00197 std::cerr << ">>> Resampler error: " << resampler->GetError() << std::endl;
00198 exportPage->isExporting = false;
00199 status = EXPORT_RESULT_FAILURE;
00200 break;
00201 }
00202
00203
00204 for ( int i = sceneBegin, j = 0; i <= sceneEnd && exportPage->isExporting;
00205 i += every, j++ )
00206 {
00207 innerLoopUpdate( i, begin, end, every );
00208
00209 int requestedSamples = frame.CalculateNumberSamples( outputFrequency, j );
00210 int nsamples = resampler->Process( adjustedRate, requestedSamples );
00211 if ( nsamples > 0 && !outputPipe->OutputAudioFrame( (int16_t *)resampler->GetOutput(), nsamples * channels * sizeof(int16_t) ) )
00212 {
00213 modal_message( _( "Error during audio export - aborting." ) );
00214 status = EXPORT_RESULT_FAILURE;
00215 exportPage->isExporting = false;
00216 }
00217 }
00218 if ( status == EXPORT_RESULT_SUCCESS && !exportPage->isExporting )
00219 status = EXPORT_RESULT_ABORT;
00220
00221
00222 outputPipe->CloseAudio();
00223 delete resampler;
00224 resampler = 0;
00225 }
00226 else
00227 {
00228 modal_message( _( "Error starting output" ) );
00229 status = EXPORT_RESULT_FAILURE;
00230 break;
00231 }
00232
00233
00234 sceneBegin = sceneEnd + 1;
00235 }
00236
00237 g_free( file );
00238 g_free( outputtemplate );
00239 delete outputPipe;
00240
00241 GetFramePool()->DoneWithFrame( &frame );
00242
00243 return status;
00244 }
00245
00246
00247 extern "C"
00248 {
00249 void
00250 on_button_export_audio_file_clicked (GtkButton *button,
00251 gpointer user_data)
00252 {
00253 const char *filename = common->getFileToSave( _("Enter a File Name to Save As") );
00254 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( button ), "entry_export_audio_file" ) );
00255 if ( strcmp( filename, "" ) )
00256 gtk_entry_set_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( button ), "entry_export_audio_file" ) ), filename );
00257 }
00258 }