* 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:
36
ChangeLog
36
ChangeLog
@@ -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:
|
||||
|
||||
19
Makefile.am
19
Makefile.am
@@ -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 \
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
inline bool isSampleExact( void ) const
|
||||
{
|
||||
return m_sampleExact ||
|
||||
engine::getMixer()->qualitySettings().
|
||||
engine::getMixer()->currentQualitySettings().
|
||||
sampleExactControllers;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
84
include/project_renderer.h
Normal file
84
include/project_renderer.h
Normal 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
|
||||
@@ -194,7 +194,7 @@ public slots:
|
||||
void exportProject( void );
|
||||
|
||||
void startExport( void );
|
||||
void cancelExport( void );
|
||||
void stopExport( void );
|
||||
|
||||
|
||||
void setModified( void );
|
||||
|
||||
@@ -57,6 +57,7 @@ signals:
|
||||
|
||||
|
||||
private slots:
|
||||
void setHighQuality( bool );
|
||||
void scrolled( int _new_pos );
|
||||
void updateTimeLinePosition( void );
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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() );
|
||||
|
||||
@@ -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 )
|
||||
|
||||
202
src/core/project_renderer.cpp
Normal file
202
src/core/project_renderer.cpp
Normal 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"
|
||||
|
||||
@@ -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();
|
||||
|
||||
379
src/gui/dialogs/export_project.ui
Normal file
379
src/gui/dialogs/export_project.ui
Normal 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>
|
||||
@@ -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"
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user