From 32d5ca7c642744bd93ce7c06637076743ce44b72 Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Thu, 12 Jun 2008 20:35:20 +0000 Subject: [PATCH] improved support for different file-formats when exporting and fixed bug which made LMMS crash when exporting to OGG-file git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1123 0778d3d1-df1d-0410-868b-ea421aaaa00d --- ChangeLog | 11 +++++ include/project_renderer.h | 29 +++++++++-- src/core/audio/audio_file_ogg.cpp | 4 +- src/core/main.cpp | 10 ++-- src/core/project_renderer.cpp | 81 ++++++++++++------------------- src/gui/dialogs/export_project.ui | 47 ++++-------------- src/gui/export_project_dialog.cpp | 38 +++++++++++++-- 7 files changed, 117 insertions(+), 103 deletions(-) diff --git a/ChangeLog b/ChangeLog index aa059b0de..8ce149ff1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2008-06-12 Tobias Doerffel + + * include/project_renderer.h: + * src/gui/dialogs/export_project.ui: + * src/gui/export_project_dialog.cpp: + * src/core/audio/audio_file_ogg.cpp: + * src/core/main.cpp: + * src/core/project_renderer.cpp: + improved support for different file-formats when exporting and fixed + bug which made LMMS crash when exporting to OGG-file + 2008-06-10 Tobias Doerffel * src/core/song.cpp: diff --git a/include/project_renderer.h b/include/project_renderer.h index 522290a48..13cf0f8a3 100644 --- a/include/project_renderer.h +++ b/include/project_renderer.h @@ -26,17 +26,20 @@ #define _PROJECT_RENDERER_H #include "audio_file_device.h" +#include "lmmsconfig.h" class projectRenderer : public QThread { Q_OBJECT public: - enum ExportFileTypes + enum ExportFileFormats { WaveFile, +#ifdef LMMS_HAVE_VORBIS_CODEC_H OggFile, - NullFile = 0xFF +#endif + NumFileFormats } ; struct outputSettings @@ -55,11 +58,17 @@ public: projectRenderer( const mixer::qualitySettings & _qs, const outputSettings & _os, - ExportFileTypes _file_type, + ExportFileFormats _file_format, const QString & _out_file ); virtual ~projectRenderer(); - static ExportFileTypes getFileTypeFromExtension( const QString & _ext ); + bool isReady( void ) const + { + return m_fileDev != NULL; + } + + static ExportFileFormats getFileFormatFromExtension( + const QString & _ext ); public slots: @@ -85,4 +94,16 @@ private: } ; + +struct fileEncodeDevice +{ + projectRenderer::ExportFileFormats m_fileFormat; + const char * m_description; + const char * m_extension; + audioFileDeviceInstantiaton m_getDevInst; +} ; + + +extern fileEncodeDevice __fileEncodeDevices[]; + #endif diff --git a/src/core/audio/audio_file_ogg.cpp b/src/core/audio/audio_file_ogg.cpp index 95e3ce436..0fb5dbcfe 100644 --- a/src/core/audio/audio_file_ogg.cpp +++ b/src/core/audio/audio_file_ogg.cpp @@ -34,7 +34,7 @@ #include "audio_file_ogg.h" -#ifdef HAVE_VORBIS_CODEC_H +#ifdef LMMS_HAVE_VORBIS_CODEC_H #include @@ -180,7 +180,7 @@ bool audioFileOgg::startEncoding( void ) -void FASTCALL audioFileOgg::writeBuffer( const surroundSampleFrame * _ab, +void audioFileOgg::writeBuffer( const surroundSampleFrame * _ab, const fpp_t _frames, const float _master_gain ) { diff --git a/src/core/main.cpp b/src/core/main.cpp index 0d0da6d47..4ea1d9d4f 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -104,7 +104,7 @@ int main( int argc, char * * argv ) mixer::qualitySettings qs( mixer::qualitySettings::Mode_HighQuality ); projectRenderer::outputSettings os( 44100, FALSE, 160 ); - projectRenderer::ExportFileTypes eft = projectRenderer::WaveFile; + projectRenderer::ExportFileFormats eff = projectRenderer::WaveFile; for( int i = 1; i < argc; ++i ) @@ -174,11 +174,11 @@ int main( int argc, char * * argv ) const QString ext = QString( argv[i + 1] ); if( ext == "wav" ) { - eft = projectRenderer::WaveFile; + eff = projectRenderer::WaveFile; } else if( ext == "ogg" ) { - eft = projectRenderer::OggFile; + eff = projectRenderer::OggFile; } else { @@ -391,8 +391,8 @@ int main( int argc, char * * argv ) engine::getSong()->loadProject( file_to_load ); // create renderer - projectRenderer * r = new projectRenderer( qs, os, eft, - render_out + QString( ( eft == projectRenderer::WaveFile ) ? + projectRenderer * r = new projectRenderer( qs, os, eff, + render_out + QString( ( eff == projectRenderer::WaveFile ) ? "wav" : "ogg" ) ); QCoreApplication::instance()->connect( r, SIGNAL( finished() ), SLOT( quit() ) ); diff --git a/src/core/project_renderer.cpp b/src/core/project_renderer.cpp index 7f2fe5c33..f329715b0 100644 --- a/src/core/project_renderer.cpp +++ b/src/core/project_renderer.cpp @@ -33,30 +33,25 @@ #include "audio_file_ogg.h" -struct fileEncodeDevice -{ - projectRenderer::ExportFileTypes m_fileType; -// const char * m_description; - const char * m_extension; - audioFileDeviceInstantiaton m_getDevInst; -} ; - - -static fileEncodeDevice __fileEncodeDevices[] = +fileEncodeDevice __fileEncodeDevices[] = { - { projectRenderer::WaveFile,/* QT_TRANSLATE_NOOP( "exportProjectDialog", - "Uncompressed Wave-File (*.wav)" ),*/ + { projectRenderer::WaveFile, + QT_TRANSLATE_NOOP( "projectRenderer", "WAV-File" ), ".wav", &audioFileWave::getInst }, -#ifdef HAVE_VORBIS_CODEC_H - { projectRenderer::OggFile, /*QT_TRANSLATE_NOOP( "exportProjectDialog", - "Compressed OGG-File (*.ogg)" ),*/ - ".ogg", &audioFileOgg::getInst }, + { projectRenderer::OggFile, + QT_TRANSLATE_NOOP( "projectRenderer", "Compressed OGG-File" ), + ".ogg", +#ifdef LMMS_HAVE_VORBIS_CODEC_H + &audioFileOgg::getInst +#else + NULL #endif + }, // ... insert your own file-encoder-infos here... may be one day the // user can add own encoders inside the program... - { projectRenderer::NullFile, NULL, NULL } + { projectRenderer::NumFileFormats, NULL, NULL, NULL } } ; @@ -65,47 +60,30 @@ static fileEncodeDevice __fileEncodeDevices[] = projectRenderer::projectRenderer( const mixer::qualitySettings & _qs, const outputSettings & _os, - ExportFileTypes _file_type, + ExportFileFormats _file_format, const QString & _out_file ) : QThread( engine::getMixer() ), + m_fileDev( NULL ), m_qualitySettings( _qs ), m_oldQualitySettings( engine::getMixer()->currentQualitySettings() ), m_progress( 0 ), m_abort( FALSE ) { - int idx = 0; - while( __fileEncodeDevices[idx].m_fileType != NullFile ) - { - if( __fileEncodeDevices[idx].m_fileType == _file_type ) - { - break; - } - ++idx; - } - - if( __fileEncodeDevices[idx].m_fileType == NullFile ) + if( __fileEncodeDevices[_file_format].m_getDevInst == NULL ) { return; } bool success_ful = FALSE; - m_fileDev = __fileEncodeDevices[idx].m_getDevInst( + m_fileDev = __fileEncodeDevices[_file_format].m_getDevInst( _os.samplerate, DEFAULT_CHANNELS, success_ful, _out_file, _os.vbr, _os.bitrate, _os.bitrate - 64, _os.bitrate + 64, engine::getMixer() ); if( success_ful == FALSE ) { -/* QMessageBox::information( this, - tr( "Export failed" ), - tr( "The project-export failed, " - "because the output-file/-" - "device could not be opened.\n" - "Make sure, you have write " - "access to the selected " - "file/device!" ), - QMessageBox::Ok ); - return;*/ + delete m_fileDev; + m_fileDev = NULL; } } @@ -120,17 +98,17 @@ projectRenderer::~projectRenderer() -// little help-function for getting file-type from a file-extension (only for +// little help-function for getting file-format from a file-extension (only for // registered file-encoders) -projectRenderer::ExportFileTypes projectRenderer::getFileTypeFromExtension( +projectRenderer::ExportFileFormats projectRenderer::getFileFormatFromExtension( const QString & _ext ) { int idx = 0; - while( __fileEncodeDevices[idx].m_fileType != NullFile ) + while( __fileEncodeDevices[idx].m_fileFormat != NumFileFormats ) { if( QString( __fileEncodeDevices[idx].m_extension ) == _ext ) { - return( __fileEncodeDevices[idx].m_fileType ); + return( __fileEncodeDevices[idx].m_fileFormat ); } ++idx; } @@ -143,13 +121,16 @@ projectRenderer::ExportFileTypes projectRenderer::getFileTypeFromExtension( void projectRenderer::startProcessing( void ) { - // have to do mixer stuff with GUI-thread-affinity in order to make - // slots connected to sampleRateChanged()-signals being called - // immediately - engine::getMixer()->setAudioDevice( m_fileDev, m_qualitySettings, - FALSE ); + if( isReady() ) + { + // have to do mixer stuff with GUI-thread-affinity in order to + // make slots connected to sampleRateChanged()-signals being + // called immediately + engine::getMixer()->setAudioDevice( m_fileDev, + m_qualitySettings, FALSE ); - start( QThread::HighestPriority ); + start( QThread::HighestPriority ); + } } diff --git a/src/gui/dialogs/export_project.ui b/src/gui/dialogs/export_project.ui index bded390a8..b0544ebc8 100644 --- a/src/gui/dialogs/export_project.ui +++ b/src/gui/dialogs/export_project.ui @@ -30,23 +30,12 @@ - File type: + File format: - - - - WAV - - - - - OGG - - - + @@ -90,16 +79,7 @@ -1 - - 0 - - - 0 - - - 0 - - + 0 @@ -152,16 +132,7 @@ - - 0 - - - 0 - - - 0 - - + 0 @@ -196,7 +167,7 @@ QSizePolicy::Fixed - + 1 10 @@ -207,7 +178,7 @@ - Please note that not all of the parameters above apply for all file types. + Please note that not all of the parameters above apply for all file formats. true @@ -219,7 +190,7 @@ Qt::Vertical - + 163 20 @@ -320,7 +291,7 @@ Qt::Vertical - + 20 40 @@ -340,7 +311,7 @@ Qt::Horizontal - + 40 20 diff --git a/src/gui/export_project_dialog.cpp b/src/gui/export_project_dialog.cpp index 4999c2176..f46dc77fe 100644 --- a/src/gui/export_project_dialog.cpp +++ b/src/gui/export_project_dialog.cpp @@ -26,6 +26,7 @@ #include +#include #include "export_project_dialog.h" @@ -45,6 +46,15 @@ exportProjectDialog::exportProjectDialog( const QString & _file_name, setWindowTitle( tr( "Export project to %1" ).arg( QFileInfo( _file_name ).fileName() ) ); + for( int i = 0; i < projectRenderer::NumFileFormats; ++i ) + { + if( __fileEncodeDevices[i].m_getDevInst != NULL ) + { + fileFormatCB->addItem( projectRenderer::tr( + __fileEncodeDevices[i].m_description ) ); + } + } + connect( startButton, SIGNAL( clicked() ), this, SLOT( startBtnClicked() ) ); @@ -90,6 +100,29 @@ void exportProjectDialog::closeEvent( QCloseEvent * _ce ) void exportProjectDialog::startBtnClicked( void ) { + projectRenderer::ExportFileFormats ft = projectRenderer::NumFileFormats; + + for( int i = 0; i < projectRenderer::NumFileFormats; ++i ) + { + if( fileFormatCB->currentText() == + projectRenderer::tr( + __fileEncodeDevices[i].m_description ) ) + { + ft = __fileEncodeDevices[i].m_fileFormat; + break; + } + } + + if( ft == projectRenderer::NumFileFormats ) + { + QMessageBox::information( this, tr( "Error" ), + tr( "Error while determining file-encoder device. " + "Please try to choose a different output " + "format." ) ); + reject(); + return; + } + startButton->setEnabled( FALSE ); progressBar->setEnabled( TRUE ); @@ -108,10 +141,7 @@ void exportProjectDialog::startBtnClicked( void ) FALSE, bitrateCB->currentText().section( " ", 0, 0 ).toUInt() ); - m_renderer = new projectRenderer( qs, os, - static_cast( - fileTypeCB->currentIndex() ), - m_fileName ); + m_renderer = new projectRenderer( qs, os, ft, m_fileName ); connect( m_renderer, SIGNAL( progressChanged( int ) ), progressBar, SLOT( setValue( int ) ) ); connect( m_renderer, SIGNAL( progressChanged( int ) ),