* introduced new project-export dialog

* new class for easily rendering a project into a file
* when changing quality-settings tell audio-devices about it so that they can adjust their output-samplerate



git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@958 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Tobias Doerffel
2008-05-11 20:08:34 +00:00
parent 5cfb1b2f96
commit e32eed940f
28 changed files with 956 additions and 522 deletions

View File

@@ -1,3 +1,39 @@
2008-05-1 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* include/controller.h:
* include/song.h:
* include/audio_file_device.h:
* include/song_editor.h:
* include/export.h:
* include/export_project_dialog.h:
* src/gui/dialogs/export_project.ui:
* src/gui/song_editor.cpp:
* src/gui/export_project_dialog.cpp:
* src/core/song.cpp:
* src/core/main.cpp:
* Makefile.am:
introduced new project-export dialog
* include/project_renderer.h:
* src/core/project_renderer.cpp:
new class for easily rendering a project into a file
* include/mixer.h:
* include/audio_sdl.h:
* include/audio_jack.h:
* include/audio_device.h:
* include/audio_oss.h:
* include/audio_alsa.h:
* src/core/audio/audio_alsa.cpp:
* src/core/audio/audio_device.cpp:
* src/core/audio/audio_file_wave.cpp:
* src/core/audio/audio_jack.cpp:
* src/core/audio/audio_oss.cpp:
* src/core/audio/audio_sdl.cpp:
* src/core/mixer.cpp:
when changing quality-settings tell audio-devices about it so that
they can adjust their output-samplerate
2008-05-05 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* plugins/ladspa_effect/ladspa_effect.cpp:

View File

@@ -32,6 +32,9 @@ bin_PROGRAMS = lmms
AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS)
ui_%.uic: $(srcdir)/src/gui/dialogs/%.ui
$(UIC) -o $@ $<
%.moc: $(srcdir)/include/%.h
$(MOC) -o $@ $<
@@ -60,7 +63,7 @@ lmms_MOC = \
./combobox.moc \
./config_mgr.moc \
./controller.moc \
./controller_connection_dialog.moc \
./controller_connection_dialog.moc \
./controller_dialog.moc \
./controller_rack_view.moc \
./controller_view.moc \
@@ -104,6 +107,7 @@ lmms_MOC = \
./pixmap_button.moc \
./plugin_browser.moc \
./project_notes.moc \
./project_renderer.moc \
./effect_view.moc \
./effect_rack_view.moc \
./rubberband.moc \
@@ -128,8 +132,12 @@ lmms_MOC = \
./visualization_widget.moc \
./volume_knob.moc
lmms_UIC = \
ui_export_project.uic
BUILT_SOURCES = $(lmms_MOC) $(lmms_UIC)
BUILT_SOURCES = $(lmms_MOC)
lmms_EMBEDDED_RESOURCES = $(srcdir)/AUTHORS $(srcdir)/COPYING
@@ -190,6 +198,7 @@ lmms_SOURCES = \
$(srcdir)/src/core/plugin.cpp \
$(srcdir)/src/core/preset_preview_play_handle.cpp \
$(srcdir)/src/core/project_journal.cpp \
$(srcdir)/src/core/project_renderer.cpp \
$(srcdir)/src/core/project_version.cpp \
$(srcdir)/src/core/sample_buffer.cpp \
$(srcdir)/src/core/sample_play_handle.cpp \
@@ -218,8 +227,8 @@ lmms_SOURCES = \
$(srcdir)/src/gui/about_dialog.cpp \
$(srcdir)/src/gui/automation_editor.cpp \
$(srcdir)/src/gui/bb_editor.cpp \
$(srcdir)/src/gui/controller_connection_dialog.cpp \
$(srcdir)/src/gui/controller_dialog.cpp \
$(srcdir)/src/gui/controller_connection_dialog.cpp \
$(srcdir)/src/gui/controller_dialog.cpp \
$(srcdir)/src/gui/effect_control_dialog.cpp \
$(srcdir)/src/gui/effect_select_dialog.cpp \
$(srcdir)/src/gui/embed.cpp \
@@ -319,6 +328,7 @@ lmms_SOURCES = \
$(srcdir)/include/fx_mixer_view.h \
$(srcdir)/include/pixmap_button.h \
$(srcdir)/include/rename_dialog.h \
$(srcdir)/include/project_renderer.h \
$(srcdir)/include/export_project_dialog.h \
$(srcdir)/include/note_play_handle.h \
$(srcdir)/include/piano_roll.h \
@@ -332,7 +342,6 @@ lmms_SOURCES = \
$(srcdir)/include/instrument_functions.h \
$(srcdir)/include/instrument_function_views.h \
$(srcdir)/include/instrument_sound_shaping_view.h \
$(srcdir)/include/export.h \
$(srcdir)/include/fader.h \
$(srcdir)/include/mv_base.h \
$(srcdir)/include/automatable_model.h \

View File

@@ -81,6 +81,7 @@ public:
private:
virtual void startProcessing( void );
virtual void stopProcessing( void );
virtual void applyQualitySettings( void );
virtual void run( void );
int setHWParams( const ch_cnt_t _channels, snd_pcm_access_t _access );

View File

@@ -83,11 +83,15 @@ public:
virtual void startProcessing( void )
{
m_in_process = TRUE;
m_inProcess = TRUE;
}
virtual void stopProcessing( void );
virtual void applyQualitySettings( void )
{
}
class setupWidget : public tabWidget
{
@@ -163,7 +167,7 @@ private:
sample_rate_t m_sampleRate;
ch_cnt_t m_channels;
mixer * m_mixer;
bool m_in_process;
bool m_inProcess;
QMutex m_devMutex;

View File

@@ -45,6 +45,10 @@ public:
mixer * _mixer );
virtual ~audioFileDevice();
QString outputFile( void ) const
{
return( m_outputFile.fileName() );
}
protected:
@@ -89,4 +93,16 @@ private:
} ;
typedef audioFileDevice * ( * audioFileDeviceInstantiaton )
( const sample_rate_t _sample_rate,
const ch_cnt_t _channels,
bool & _success_ful,
const QString & _file,
const bool _use_vbr,
const bitrate_t _nom_bitrate,
const bitrate_t _min_bitrate,
const bitrate_t _max_bitrate,
mixer * _mixer );
#endif

View File

@@ -80,6 +80,7 @@ public:
private:
virtual void startProcessing( void );
virtual void stopProcessing( void );
virtual void applyQualitySettings( void );
virtual void registerPort( audioPort * _port );
virtual void unregisterPort( audioPort * _port );

View File

@@ -76,6 +76,7 @@ public:
private:
virtual void startProcessing( void );
virtual void stopProcessing( void );
virtual void applyQualitySettings( void );
virtual void run( void );
int m_audioFD;

View File

@@ -77,6 +77,7 @@ public:
private:
virtual void startProcessing( void );
virtual void stopProcessing( void );
virtual void applyQualitySettings( void );
static void sdlAudioCallback( void * _udata, Uint8 * _buf, int _len );
void sdlAudioCallback( Uint8 * _buf, int _len );

View File

@@ -53,7 +53,7 @@ public:
inline bool isSampleExact( void ) const
{
return m_sampleExact ||
engine::getMixer()->qualitySettings().
engine::getMixer()->currentQualitySettings().
sampleExactControllers;
}

View File

@@ -1,69 +0,0 @@
/*
* export.h - header which is needed for song-export
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.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 (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef _EXPORT_H
#define _EXPORT_H
#include <QtCore/QString>
#include "types.h"
class audioFileDevice;
class mixer;
typedef audioFileDevice * ( * getDeviceInst)( const sample_rate_t _sample_rate,
const ch_cnt_t _channels,
bool & _success_ful,
const QString & _file,
const bool _use_vbr,
const bitrate_t _nom_bitrate,
const bitrate_t _min_bitrate,
const bitrate_t _max_bitrate,
mixer * _mixer );
enum ExportFileTypes
{
WaveFile,
OggFile,
NullFile = 0xFF
} ;
struct fileEncodeDevice
{
ExportFileTypes m_fileType;
const char * m_description;
const char * m_extension;
getDeviceInst m_getDevInst;
} ;
extern fileEncodeDevice fileEncodeDevices[];
#endif

View File

@@ -29,20 +29,12 @@
#include <QtGui/QDialog>
#include "export.h"
#include "automatable_model.h"
#include "combobox.h"
#include "ui_export_project.uic"
class projectRenderer;
class QLabel;
class QPushButton;
class QProgressBar;
class ledCheckBox;
class pixmapButton;
class exportProjectDialog : public QDialog
class exportProjectDialog : public QDialog, public Ui::ExportProjectDialog
{
Q_OBJECT
public:
@@ -50,47 +42,18 @@ public:
virtual ~exportProjectDialog();
public slots:
void exportBtnClicked( void );
protected:
virtual void keyPressEvent( QKeyEvent * _ke );
virtual void reject( void );
virtual void closeEvent( QCloseEvent * _ce );
private slots:
void changedType( const QString & );
void cancelBtnClicked( void );
void startBtnClicked( void );
private:
void finishProjectExport( void );
void abortProjectExport( void );
static ExportFileTypes getFileTypeFromExtension( const QString & _ext );
static Sint16 s_availableBitrates[];
comboBoxModel m_typeModel;
comboBoxModel m_kbpsModel;
boolModel m_vbrEnabledModel;
boolModel m_hqmEnabledModel;
QLabel * m_typeLbl;
comboBox * m_typeCombo;
QLabel * m_kbpsLbl;
comboBox * m_kbpsCombo;
ledCheckBox * m_vbrCb;
ledCheckBox * m_hqmCb;
QLabel * m_hourglassLbl;
QPushButton * m_exportBtn;
QPushButton * m_cancelBtn;
QProgressBar * m_exportProgressBar;
QString m_fileName;
ExportFileTypes m_fileType;
bool m_deleteFile;
projectRenderer * m_renderer;
} ;

View File

@@ -101,6 +101,7 @@ public:
Mode_HighQuality,
Mode_FinalMix
} ;
enum Interpolation
{
Interpolation_Linear,
@@ -199,6 +200,8 @@ public:
}
void setAudioDevice( audioDevice * _dev );
void setAudioDevice( audioDevice * _dev,
const struct qualitySettings & _qs );
void restoreAudioDevice( void );
inline audioDevice * audioDev( void )
{
@@ -291,7 +294,7 @@ public:
return( m_cpuLoad );
}
const qualitySettings & qualitySettings( void ) const
const qualitySettings & currentQualitySettings( void ) const
{
return( m_qualitySettings );
}

View File

@@ -0,0 +1,84 @@
/*
* project_renderer.h - projectRenderer-class for easily rendering projects
*
* Copyright (c) 2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.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 (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef _PROJECT_RENDERER_H
#define _PROJECT_RENDERER_H
#include "audio_file_device.h"
class projectRenderer : public QThread
{
Q_OBJECT
public:
enum ExportFileTypes
{
WaveFile,
OggFile,
NullFile = 0xFF
} ;
struct outputSettings
{
sample_rate_t samplerate;
bool vbr;
int bitrate;
outputSettings( sample_rate_t _sr, bool _vbr, int _bitrate ) :
samplerate( _sr ),
vbr( _vbr ),
bitrate( _bitrate )
{
}
} ;
projectRenderer( const mixer::qualitySettings & _qs,
const outputSettings & _os,
ExportFileTypes _file_type,
const QString & _out_file );
virtual ~projectRenderer();
static ExportFileTypes getFileTypeFromExtension( const QString & _ext );
public slots:
void startProcessing( void );
void abortProcessing( void );
signals:
void progressChanged( int );
private:
virtual void run( void );
audioFileDevice * m_fileDev;
mixer::qualitySettings m_qualitySettings;
volatile bool m_abort;
} ;
#endif

View File

@@ -194,7 +194,7 @@ public slots:
void exportProject( void );
void startExport( void );
void cancelExport( void );
void stopExport( void );
void setModified( void );

View File

@@ -57,6 +57,7 @@ signals:
private slots:
void setHighQuality( bool );
void scrolled( int _new_pos );
void updateTimeLinePosition( void );

View File

@@ -185,6 +185,43 @@ void audioALSA::stopProcessing( void )
void audioALSA::applyQualitySettings( void )
{
setSampleRate( engine::getMixer()->processingSampleRate() );
if( m_handle != NULL )
{
snd_pcm_close( m_handle );
}
int err;
if( ( err = snd_pcm_open( &m_handle,
probeDevice().toAscii().constData(),
SND_PCM_STREAM_PLAYBACK,
0 ) ) < 0 )
{
printf( "Playback open error: %s\n", snd_strerror( err ) );
return;
}
if( ( err = setHWParams( channels(),
SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 )
{
printf( "Setting of hwparams failed: %s\n",
snd_strerror( err ) );
return;
}
if( ( err = setSWParams() ) < 0 )
{
printf( "Setting of swparams failed: %s\n",
snd_strerror( err ) );
return;
}
}
void audioALSA::run( void )
{
surroundSampleFrame * temp =
@@ -327,10 +364,6 @@ int audioALSA::setHWParams( const ch_cnt_t _channels, snd_pcm_access_t _access )
return( err );
}
}
else
{
setSampleRate( getMixer()->processingSampleRate() );
}
m_periodSize = getMixer()->framesPerPeriod();
m_bufferSize = m_periodSize * 8;

View File

@@ -45,7 +45,7 @@ audioDevice::audioDevice( const ch_cnt_t _channels, mixer * _mixer ) :
{
int error;
if( ( m_srcState = src_new(
getMixer()->qualitySettings().libsrcInterpolation(),
getMixer()->currentQualitySettings().libsrcInterpolation(),
SURROUND_CHANNELS, &error ) ) == NULL )
{
printf( "Error: src_new() failed in audio_device.cpp!\n" );
@@ -77,7 +77,7 @@ void audioDevice::processNextBuffer( void )
}
else
{
m_in_process = FALSE;
m_inProcess = FALSE;
}
}
@@ -122,7 +122,7 @@ fpp_t audioDevice::getNextBuffer( surroundSampleFrame * _ab )
void audioDevice::stopProcessing( void )
{
while( m_in_process )
while( m_inProcess )
{
processNextBuffer();
}

View File

@@ -91,7 +91,7 @@ bool audioFileWave::startEncoding( void )
void FASTCALL audioFileWave::writeBuffer( const surroundSampleFrame * _ab,
void audioFileWave::writeBuffer( const surroundSampleFrame * _ab,
const fpp_t _frames,
const float _master_gain )
{

View File

@@ -232,6 +232,19 @@ void audioJACK::stopProcessing( void )
void audioJACK::applyQualitySettings( void )
{
setSampleRate( engine::getMixer()->processingSampleRate() );
if( jack_get_sample_rate( m_client ) != sampleRate() )
{
setSampleRate( jack_get_sample_rate( m_client ) );
}
}
void audioJACK::registerPort( audioPort * _port )
{
#ifdef AUDIO_PORT_SUPPORT

View File

@@ -268,6 +268,33 @@ void audioOSS::stopProcessing( void )
void audioOSS::applyQualitySettings( void )
{
setSampleRate( engine::getMixer()->processingSampleRate() );
unsigned int value = sampleRate();
if ( ioctl( m_audioFD, SNDCTL_DSP_SPEED, &value ) < 0 )
{
perror( "SNDCTL_DSP_SPEED" );
printf( "Couldn't set audio frequency\n" );
return;
}
if( value != sampleRate() )
{
value = getMixer()->baseSampleRate();
if ( ioctl( m_audioFD, SNDCTL_DSP_SPEED, &value ) < 0 )
{
perror( "SNDCTL_DSP_SPEED" );
printf( "Couldn't set audio frequency\n" );
return;
}
setSampleRate( value );
}
}
void audioOSS::run( void )
{
surroundSampleFrame * temp =

View File

@@ -33,6 +33,7 @@
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include "engine.h"
#include "debug.h"
#include "config_mgr.h"
#include "gui_templates.h"
@@ -128,6 +129,26 @@ void audioSDL::stopProcessing( void )
void audioSDL::applyQualitySettings( void )
{
SDL_CloseAudio();
setSampleRate( engine::getMixer()->processingSampleRate() );
m_audioHandle.freq = sampleRate();
SDL_AudioSpec actual;
// open the audio device, forcing the desired format
if( SDL_OpenAudio( &m_audioHandle, &actual ) < 0 )
{
printf( "Couldn't open SDL-audio: %s\n", SDL_GetError() );
}
}
void audioSDL::sdlAudioCallback( void * _udata, Uint8 * _buf, int _len )
{
audioSDL * _this = static_cast<audioSDL *>( _udata );

View File

@@ -41,7 +41,7 @@
#include "embed.h"
#include "engine.h"
#include "config_mgr.h"
#include "export_project_dialog.h"
#include "project_renderer.h"
#include "song.h"
#include "gui_templates.h"
#include "lmms_style.h"
@@ -53,8 +53,6 @@ static inline QString baseName( const QString & _file )
QFileInfo( _file ).completeBaseName() );
}
QString file_to_render;
int splash_alignment_flags = Qt::AlignTop | Qt::AlignLeft;
@@ -86,7 +84,7 @@ int main( int argc, char * * argv )
QApplication app( argc, argv );
QString extension = "wav";
QString file_to_load;
QString file_to_load, file_to_render;
for( int i = 1; i < argc; ++i )
{
@@ -248,14 +246,14 @@ int main( int argc, char * * argv )
{
engine::init( FALSE );
engine::getSong()->loadProject( file_to_load );
exportProjectDialog * e = new exportProjectDialog(
/* exportProjectDialog * e = new exportProjectDialog(
file_to_render,
engine::getMainWindow() );
e->show();
QTime t;
t.start();
e->exportBtnClicked();
printf("export took %d ms\n",t.elapsed());
printf("export took %d ms\n",t.elapsed());*/
}
return( app.exec() );

View File

@@ -793,11 +793,12 @@ void mixer::changeQuality( const struct qualitySettings & _qs )
stopProcessing();
m_qualitySettings = _qs;
startProcessing();
m_audioDev->applyQualitySettings();
emit sampleRateChanged();
emit qualitySettingsChanged();
startProcessing();
}
@@ -828,6 +829,35 @@ void mixer::setAudioDevice( audioDevice * _dev )
void mixer::setAudioDevice( audioDevice * _dev,
const struct qualitySettings & _qs )
{
// don't delete the audio-device
stopProcessing();
m_qualitySettings = _qs;
m_oldAudioDev = m_audioDev;
if( _dev == NULL )
{
printf( "param _dev == NULL in mixer::setAudioDevice(...). "
"Trying any working audio-device\n" );
m_audioDev = tryAudioDevices();
}
else
{
m_audioDev = _dev;
}
emit qualitySettingsChanged();
emit sampleRateChanged();
startProcessing();
}
void mixer::restoreAudioDevice( void )
{
if( m_oldAudioDev != NULL )

View File

@@ -0,0 +1,202 @@
/*
* project_renderer.cpp - projectRenderer-class for easily rendering projects
*
* Copyright (c) 2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.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 (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#include <QtCore/QFile>
#include "project_renderer.h"
#include "song.h"
#include "engine.h"
#include "audio_file_wave.h"
#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[] =
{
{ projectRenderer::WaveFile,/* QT_TRANSLATE_NOOP( "exportProjectDialog",
"Uncompressed Wave-File (*.wav)" ),*/
".wav", &audioFileWave::getInst },
#ifdef HAVE_VORBIS_CODEC_H
{ projectRenderer::OggFile, /*QT_TRANSLATE_NOOP( "exportProjectDialog",
"Compressed OGG-File (*.ogg)" ),*/
".ogg", &audioFileOgg::getInst },
#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::projectRenderer( const mixer::qualitySettings & _qs,
const outputSettings & _os,
ExportFileTypes _file_type,
const QString & _out_file ) :
QThread( engine::getMixer() ),
m_qualitySettings( _qs ),
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 )
{
return;
}
bool success_ful = FALSE;
m_fileDev = __fileEncodeDevices[idx].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;*/
}
}
projectRenderer::~projectRenderer()
{
}
// little help-function for getting file-type from a file-extension (only for
// registered file-encoders)
projectRenderer::ExportFileTypes projectRenderer::getFileTypeFromExtension(
const QString & _ext )
{
int idx = 0;
while( __fileEncodeDevices[idx].m_fileType != NullFile )
{
if( QString( __fileEncodeDevices[idx].m_extension ) == _ext )
{
return( __fileEncodeDevices[idx].m_fileType );
}
++idx;
}
return( WaveFile ); // default
}
void projectRenderer::startProcessing( void )
{
start( QThread::HighestPriority );
}
void projectRenderer::run( void )
{
const mixer::qualitySettings qs =
engine::getMixer()->currentQualitySettings();
engine::getMixer()->setAudioDevice( m_fileDev, m_qualitySettings );
engine::getSong()->startExport();
song::playPos & pp = engine::getSong()->getPlayPos(
song::Mode_PlaySong );
int progress = 0;
while( engine::getSong()->isExportDone() == FALSE &&
engine::getSong()->isExporting() == TRUE
&& !m_abort )
{
m_fileDev->processNextBuffer();
const int nprog = pp * 100 /
( ( engine::getSong()->length() + 1 ) * 192 );
if( progress != nprog )
{
progress = nprog;
emit progressChanged( progress );
}
}
engine::getSong()->stopExport();
const QString f = m_fileDev->outputFile();
engine::getMixer()->restoreAudioDevice(); // also deletes audio-dev
engine::getMixer()->changeQuality( qs );
// if the user aborted export-process, the file has to be deleted
if( m_abort )
{
QFile( f ).remove();
}
}
void projectRenderer::abortProcessing( void )
{
m_abort = TRUE;
}
#include "project_renderer.moc"

View File

@@ -348,7 +348,7 @@ void song::processNextBuffer( void )
}
f_cnt_t total_frames_played = 0;
float frames_per_tick = engine::framesPerTick();
const float frames_per_tick = engine::framesPerTick();
while( total_frames_played
< engine::getMixer()->framesPerPeriod() )
@@ -607,7 +607,7 @@ void song::startExport( void )
void song::cancelExport( void )
void song::stopExport( void )
{
stop();
m_exporting = FALSE;
@@ -616,8 +616,6 @@ void song::cancelExport( void )
void song::insertBar( void )
{
QList<track *> tl = tracks();
@@ -990,19 +988,19 @@ void song::exportProject( void )
{
base_filename = tr( "untitled" );
}
base_filename += fileEncodeDevices[0].m_extension;
base_filename += ".wav";//fileEncodeDevices[0].m_extension;
QFileDialog efd( engine::getMainWindow() );
efd.setFileMode( QFileDialog::AnyFile );
int idx = 0;
/* int idx = 0;
QStringList types;
while( fileEncodeDevices[idx].m_fileType != NullFile )
{
types << tr( fileEncodeDevices[idx].m_description );
++idx;
}
efd.setFilters( types );
efd.setFilters( types );*/
efd.selectFile( base_filename );
efd.setWindowTitle( tr( "Select file for project-export..." ) );
@@ -1011,7 +1009,7 @@ void song::exportProject( void )
)
{
const QString export_file_name = efd.selectedFiles()[0];
if( QFileInfo( export_file_name ).exists() == TRUE &&
/* if( QFileInfo( export_file_name ).exists() == TRUE &&
QMessageBox::warning( engine::getMainWindow(),
tr( "File already exists" ),
tr( "The file \"%1\" already "
@@ -1026,7 +1024,7 @@ void song::exportProject( void )
== QMessageBox::No )
{
return;
}
}*/
exportProjectDialog epd( export_file_name,
engine::getMainWindow() );
epd.exec();

View File

@@ -0,0 +1,379 @@
<ui version="4.0" >
<class>ExportProjectDialog</class>
<widget class="QDialog" name="ExportProjectDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>405</width>
<height>351</height>
</rect>
</property>
<property name="windowTitle" >
<string>Export project</string>
</property>
<layout class="QVBoxLayout" >
<item>
<layout class="QHBoxLayout" >
<item>
<widget class="QGroupBox" name="outputGroupBox" >
<property name="title" >
<string>Output</string>
</property>
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>-1</number>
</property>
<property name="leftMargin" >
<number>9</number>
</property>
<item>
<widget class="QLabel" name="label" >
<property name="text" >
<string>File type:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="fileTypeCB" >
<item>
<property name="text" >
<string>WAV</string>
</property>
</item>
<item>
<property name="text" >
<string>OGG</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3" >
<property name="text" >
<string>Samplerate:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="samplerateCB" >
<item>
<property name="text" >
<string>44100 Hz</string>
</property>
</item>
<item>
<property name="text" >
<string>48000 Hz</string>
</property>
</item>
<item>
<property name="text" >
<string>88200 Hz</string>
</property>
</item>
<item>
<property name="text" >
<string>96000 Hz</string>
</property>
</item>
<item>
<property name="text" >
<string>192000 Hz</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QWidget" native="1" name="bitrateWidget" >
<layout class="QVBoxLayout" >
<property name="spacing" >
<number>-1</number>
</property>
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_5" >
<property name="text" >
<string>Bitrate:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="bitrateCB" >
<property name="currentIndex" >
<number>2</number>
</property>
<item>
<property name="text" >
<string>64 KBit/s</string>
</property>
</item>
<item>
<property name="text" >
<string>128 KBit/s</string>
</property>
</item>
<item>
<property name="text" >
<string>160 KBit/s</string>
</property>
</item>
<item>
<property name="text" >
<string>192 KBit/s</string>
</property>
</item>
<item>
<property name="text" >
<string>256 KBit/s</string>
</property>
</item>
<item>
<property name="text" >
<string>320 KBit/s</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" native="1" name="depthWidget" >
<layout class="QVBoxLayout" >
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_6" >
<property name="text" >
<string>Depth:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="depthCB" >
<item>
<property name="text" >
<string>16 Bit Integer</string>
</property>
</item>
<item>
<property name="text" >
<string>24 Bit Float</string>
</property>
</item>
<item>
<property name="text" >
<string>32 Bit Float</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>163</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="qualityGroupBox" >
<property name="title" >
<string>Quality settings</string>
</property>
<layout class="QVBoxLayout" >
<item>
<widget class="QLabel" name="label_2" >
<property name="text" >
<string>Interpolation:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="interpolationCB" >
<item>
<property name="text" >
<string>Linear</string>
</property>
</item>
<item>
<property name="text" >
<string>Sinc Fastest</string>
</property>
</item>
<item>
<property name="text" >
<string>Sinc Medium</string>
</property>
</item>
<item>
<property name="text" >
<string>Sinc Best</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4" >
<property name="text" >
<string>Oversampling:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="oversamplingCB" >
<item>
<property name="text" >
<string>None</string>
</property>
</item>
<item>
<property name="text" >
<string>2x</string>
</property>
</item>
<item>
<property name="text" >
<string>4x</string>
</property>
</item>
<item>
<property name="text" >
<string>8x</string>
</property>
</item>
<item>
<property name="text" >
<string>16x (use with care!)</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QCheckBox" name="sampleExactControllersCB" >
<property name="text" >
<string>Sample-exact controllers</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="aliasFreeOscillatorsCB" >
<property name="text" >
<string>Alias-free oscillators</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" >
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="startButton" >
<property name="text" >
<string>Start</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="cancelButton" >
<property name="text" >
<string>Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QProgressBar" name="progressBar" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="value" >
<number>0</number>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>cancelButton</sender>
<signal>clicked()</signal>
<receiver>ExportProjectDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>357</x>
<y>293</y>
</hint>
<hint type="destinationlabel" >
<x>202</x>
<y>175</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -3,7 +3,7 @@
/*
* export_project_dialog.cpp - implementation of dialog for exporting project
*
* Copyright (c) 2004-2007 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -25,185 +25,26 @@
*/
#include <QtGui/QFileDialog>
#include <QtGui/QMessageBox>
#include <QtGui/QProgressBar>
#include <QtGui/QLabel>
#include <QtGui/QPushButton>
#include <QtGui/QCloseEvent>
#include <QtGui/QApplication>
#include <QtCore/QFileInfo>
#include "export_project_dialog.h"
#include "song.h"
#include "main_window.h"
#include "combobox.h"
#include "led_checkbox.h"
#include "embed.h"
#include "engine.h"
#include "project_renderer.h"
#include "audio_file_wave.h"
#include "audio_file_ogg.h"
extern QString file_to_render;
fileEncodeDevice fileEncodeDevices[] =
{
{ WaveFile, QT_TRANSLATE_NOOP( "exportProjectDialog",
"Uncompressed Wave-File (*.wav)" ),
".wav", &audioFileWave::getInst },
#ifdef HAVE_VORBIS_CODEC_H
{ OggFile, QT_TRANSLATE_NOOP( "exportProjectDialog",
"Compressed OGG-File (*.ogg)" ),
".ogg", &audioFileOgg::getInst },
#endif
// ... insert your own file-encoder-infos here... may be one day the
// user can add own encoders inside the program...
{ NullFile, NULL, NULL, NULL }
} ;
const int LABEL_MARGIN = 6;
const int LABEL_X = 10;
const int LABEL_WIDTH = 48;
const int TYPE_STUFF_Y = 10;
const int TYPE_HEIGHT = 22;
const int TYPE_COMBO_WIDTH = 256;
const int KBPS_STUFF_Y = TYPE_STUFF_Y + TYPE_HEIGHT + LABEL_MARGIN + 6;
const int KBPS_HEIGHT = TYPE_HEIGHT;
const int KBPS_COMBO_WIDTH = 64;
const int HQ_MODE_CB_Y = KBPS_STUFF_Y + KBPS_HEIGHT + LABEL_MARGIN;
const int HQ_MODE_CB_HEIGHT = TYPE_HEIGHT;
const int HQ_MODE_CB_WIDTH = 300;
const int CTL_BUTTONS_Y = HQ_MODE_CB_Y + HQ_MODE_CB_HEIGHT + LABEL_MARGIN + 6;
const int CTL_BUTTONS_HEIGHT = 30;
const int CTL_BUTTONS_WIDTH = 120;
const int HOURGLASS_X = LABEL_X;
const int HOURGLASS_Y = 24;
const int HOURGLASS_WIDTH = 44;
const int HOURGLASS_HEIGHT = 56;
const int EPB_X = LABEL_X + 60;
const int EPB_Y = HOURGLASS_Y;
const int EPB_WIDTH = 260;
const int EPB_HEIGHT = 24;
const int CANCEL_X_WHILE_EXPORT = 136;
const int CANCEL_Y_WHILE_EXPORT = EPB_Y + EPB_HEIGHT + 32;
Sint16 exportProjectDialog::s_availableBitrates[] =
{
64,
80,
96,
112,
128,
160,
192,
256,
320,
-1
};
// TODO: rewrite that crap using layouts!!
exportProjectDialog::exportProjectDialog( const QString & _file_name,
QWidget * _parent ) :
QDialog( _parent ),
m_typeModel( NULL /* this */ ),
m_kbpsModel( NULL /* this */ ),
m_vbrEnabledModel( TRUE, NULL /* this */ ),
m_hqmEnabledModel( FALSE, NULL/* this */ ),
Ui::ExportProjectDialog(),
m_fileName( _file_name ),
m_deleteFile( FALSE )
m_renderer( NULL )
{
m_fileType = getFileTypeFromExtension( "." +
QFileInfo( _file_name
).completeSuffix() );
setupUi( this );
setWindowTitle( tr( "Export project to %1" ).arg(
QFileInfo( _file_name ).fileName() ) );
// type-ui-stuff
m_typeLbl = new QLabel( tr( "Type:" ), this );
m_typeLbl->setGeometry( LABEL_X, TYPE_STUFF_Y, LABEL_WIDTH,
TYPE_HEIGHT );
Uint8 idx = 0;
while( fileEncodeDevices[idx].m_fileType != NullFile )
{
m_typeModel.addItem(
tr( fileEncodeDevices[idx].m_description ) );
++idx;
}
m_typeModel.setValue( m_typeModel.findText( tr(
fileEncodeDevices[m_fileType].m_description ) ) );
m_typeCombo = new comboBox( this );
m_typeCombo->setGeometry( LABEL_X + LABEL_WIDTH+LABEL_MARGIN,
TYPE_STUFF_Y, TYPE_COMBO_WIDTH,
TYPE_HEIGHT );
m_typeCombo->setModel( &m_typeModel );
/* connect( m_typeCombo, SIGNAL( activated( const QString & ) ), this,
SLOT( changedType( const QString & ) ) );*/
// kbps-ui-stuff
m_kbpsLbl = new QLabel( tr( "kbps:" ), this );
m_kbpsLbl->setGeometry( LABEL_X, KBPS_STUFF_Y, LABEL_WIDTH,
KBPS_HEIGHT );
idx = 0;
while( s_availableBitrates[idx] != -1 )
{
m_kbpsModel.addItem( QString::number(
s_availableBitrates[idx] ) );
++idx;
}
m_kbpsModel.setValue( m_kbpsModel.findText(
QString::number( 128 ) ) );
m_kbpsCombo = new comboBox( this );
m_kbpsCombo->setModel( &m_kbpsModel );
m_kbpsCombo->setGeometry( LABEL_X + LABEL_WIDTH + LABEL_MARGIN,
KBPS_STUFF_Y, KBPS_COMBO_WIDTH,
KBPS_HEIGHT );
m_vbrCb = new ledCheckBox( tr( "variable bitrate" ), this );
m_vbrCb->setModel( &m_vbrEnabledModel );
m_vbrCb->setGeometry( LABEL_X + LABEL_WIDTH + 3 * LABEL_MARGIN +
KBPS_COMBO_WIDTH, KBPS_STUFF_Y + 3, 190, 20 );
m_hqmCb = new ledCheckBox( tr( "use high-quality-mode (recommened)" ),
this );
m_hqmCb->setModel( &m_hqmEnabledModel );
m_hqmCb->setGeometry( LABEL_X, HQ_MODE_CB_Y + 3, HQ_MODE_CB_WIDTH,
HQ_MODE_CB_HEIGHT );
m_exportBtn = new QPushButton( embed::getIconPixmap( "apply" ),
tr( "Export" ), this );
m_exportBtn->setGeometry( LABEL_X + LABEL_WIDTH + LABEL_MARGIN,
CTL_BUTTONS_Y, CTL_BUTTONS_WIDTH,
CTL_BUTTONS_HEIGHT );
connect( m_exportBtn, SIGNAL( clicked() ), this,
SLOT( exportBtnClicked() ) );
m_cancelBtn = new QPushButton( embed::getIconPixmap( "cancel" ),
tr( "Cancel" ), this );
m_cancelBtn->setGeometry( LABEL_X + LABEL_WIDTH + 2 * LABEL_MARGIN +
CTL_BUTTONS_WIDTH, CTL_BUTTONS_Y,
CTL_BUTTONS_WIDTH, CTL_BUTTONS_HEIGHT );
connect( m_cancelBtn, SIGNAL( clicked() ), this,
SLOT( cancelBtnClicked() ) );
connect( startButton, SIGNAL( clicked() ),
this, SLOT( startBtnClicked() ) );
}
@@ -212,44 +53,21 @@ exportProjectDialog::exportProjectDialog( const QString & _file_name,
exportProjectDialog::~exportProjectDialog()
{
delete m_renderer;
}
// little help-function for getting file-type from a file-extension (only for
// registered file-encoders)
ExportFileTypes exportProjectDialog::getFileTypeFromExtension(
const QString & _ext )
void exportProjectDialog::reject( void )
{
int idx = 0;
while( fileEncodeDevices[idx].m_fileType != NullFile )
if( m_renderer == NULL )
{
if( QString( fileEncodeDevices[idx].m_extension ) == _ext )
{
return( fileEncodeDevices[idx].m_fileType );
}
++idx;
accept();
}
return( WaveFile ); // default
}
void exportProjectDialog::keyPressEvent( QKeyEvent * _ke )
{
if( _ke->key() == Qt::Key_Escape )
else
{
if( engine::getSong()->isExporting() == FALSE )
{
accept();
}
else
{
abortProjectExport();
}
m_renderer->abortProcessing();
}
}
@@ -258,193 +76,48 @@ void exportProjectDialog::keyPressEvent( QKeyEvent * _ke )
void exportProjectDialog::closeEvent( QCloseEvent * _ce )
{
if( engine::getSong()->isExporting() == TRUE )
if( m_renderer != NULL && m_renderer->isRunning() )
{
abortProjectExport();
_ce->ignore();
}
else
{
QDialog::closeEvent( _ce );
m_renderer->abortProcessing();
}
QDialog::closeEvent( _ce );
}
void exportProjectDialog::changedType( const QString & _new_type )
void exportProjectDialog::startBtnClicked( void )
{
int idx = 0;
while( fileEncodeDevices[idx].m_fileType != NullFile )
{
if( tr( fileEncodeDevices[idx].m_description ) == _new_type )
{
m_fileType = fileEncodeDevices[idx].m_fileType;
break;
}
++idx;
}
startButton->setEnabled( FALSE );
progressBar->setEnabled( TRUE );
mixer::qualitySettings qs = mixer::qualitySettings(
static_cast<mixer::qualitySettings::Interpolation>(
interpolationCB->currentIndex() ),
static_cast<mixer::qualitySettings::Oversampling>(
oversamplingCB->currentIndex() ),
sampleExactControllersCB->isChecked(),
aliasFreeOscillatorsCB->isChecked() );
projectRenderer::outputSettings os = projectRenderer::outputSettings(
samplerateCB->currentText().section( " ", 0, 0 ).toUInt(),
FALSE,
bitrateCB->currentText().section( " ", 0, 0 ).toUInt() );
m_renderer = new projectRenderer( qs, os,
static_cast<projectRenderer::ExportFileTypes>(
fileTypeCB->currentIndex() ),
m_fileName );
connect( m_renderer, SIGNAL( progressChanged( int ) ),
progressBar, SLOT( setValue( int ) ) );
connect( m_renderer, SIGNAL( finished() ),
this, SLOT( accept() ) );
m_renderer->startProcessing();
}
void exportProjectDialog::exportBtnClicked( void )
{
int idx = 0;
while( fileEncodeDevices[idx].m_fileType != NullFile )
{
if( fileEncodeDevices[idx].m_fileType == m_fileType )
{
break;
}
++idx;
}
if( fileEncodeDevices[idx].m_fileType == NullFile )
{
return;
}
bool success_ful = FALSE;
audioFileDevice * dev = fileEncodeDevices[idx].m_getDevInst(
44100,
DEFAULT_CHANNELS,
success_ful,
m_fileName,
m_vbrCb->model()->value(),
m_kbpsModel.currentText().toInt(),
m_kbpsModel.currentText().toInt() - 64,
m_kbpsModel.currentText().toInt() + 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;
}
setWindowTitle( tr( "Exporting project to %1" ).arg(
QFileInfo( m_fileName ).fileName() ) );
delete m_typeLbl;
delete m_typeCombo;
delete m_kbpsLbl;
delete m_kbpsCombo;
delete m_vbrCb;
delete m_exportBtn;
m_exportProgressBar = new QProgressBar( this );
m_exportProgressBar->setGeometry( EPB_X, EPB_Y, EPB_WIDTH, EPB_HEIGHT );
m_exportProgressBar->setMaximum( 100 );
m_exportProgressBar->show();
m_hourglassLbl = new QLabel( this );
m_hourglassLbl->setPixmap( embed::getIconPixmap( "hourglass" ) );
m_hourglassLbl->setGeometry( HOURGLASS_X, HOURGLASS_Y,
HOURGLASS_WIDTH, HOURGLASS_HEIGHT );
m_hourglassLbl->show();
m_cancelBtn->move( CANCEL_X_WHILE_EXPORT, CANCEL_Y_WHILE_EXPORT );
engine::getMixer()->setAudioDevice( dev );//, m_hqmCb->model()->value() );
engine::getSong()->startExport();
delete m_hqmCb;
song::playPos & pp = engine::getSong()->getPlayPos(
song::Mode_PlaySong );
while( engine::getSong()->isExportDone() == FALSE &&
engine::getSong()->isExporting() == TRUE
&& !m_deleteFile )
{
dev->processNextBuffer();
const int pval = pp * 100 /
( ( engine::getSong()->length() + 1 ) * 192 );
m_exportProgressBar->setValue( pval );
if( engine::getMainWindow() )
{
// update lmms-main-win-caption
engine::getMainWindow()->setWindowTitle( tr( "Rendering:" )
+ " " + QString::number( pval ) + "%" );
}
// process paint-events etc.
QCoreApplication::processEvents();
}
finishProjectExport();
}
void exportProjectDialog::cancelBtnClicked( void )
{
// is song-export-thread active?
if( engine::getSong()->isExporting() == TRUE )
{
// then dispose abort of export
abortProjectExport();
return;
}
reject();
}
// called whenever there's a reason for aborting song-export (like user-input)
void exportProjectDialog::abortProjectExport( void )
{
m_deleteFile = TRUE;
}
void exportProjectDialog::finishProjectExport( void )
{
engine::getMixer()->restoreAudioDevice();
// if the user aborted export-process, the file has to be deleted
if( m_deleteFile )
{
QFile( m_fileName ).remove();
}
if( engine::getMainWindow() )
{
// restore window-title
engine::getMainWindow()->resetWindowTitle();
}
engine::getSong()->cancelExport();
// if we rendered file from command line, quit after export
if( file_to_render != "" )
{
// qApp->quit(); - doesn't work for some reason...
exit( 0 );
}
// let's close us...
accept();
}
#include "export_project_dialog.moc"

View File

@@ -57,7 +57,6 @@
#include "cpuload_widget.h"
#include "embed.h"
#include "envelope_and_lfo_parameters.h"
#include "export_project_dialog.h"
#include "import_filter.h"
#include "instrument_track.h"
#include "lcd_spinbox.h"
@@ -132,8 +131,8 @@ songEditor::songEditor( song * _song, songEditor * & _engine_ptr ) :
tr( "High quality mode" ),
NULL, NULL, tb );
hq_btn->setCheckable( TRUE );
connect( hq_btn, SIGNAL( toggled( bool ) ), engine::getMixer(),
SLOT( setHighQuality( bool ) ) );
connect( hq_btn, SIGNAL( toggled( bool ) ),
this, SLOT( setHighQuality( bool ) ) );
hq_btn->setFixedWidth( 42 );
engine::getMainWindow()->addWidgetToToolBar( hq_btn, 1, col );
@@ -386,6 +385,16 @@ songEditor::~songEditor()
void songEditor::setHighQuality( bool _hq )
{
engine::getMixer()->changeQuality( mixer::qualitySettings(
_hq ? mixer::qualitySettings::Mode_HighQuality :
mixer::qualitySettings::Mode_Draft ) );
}
void songEditor::scrolled( int _new_pos )
{
update();