Merge pull request #3516 from michaelgregorius/3021-24-Bit-Export
Implement 24 bit support for WAV export (#3021) and improve the export dialog (only show widgets relevant to output format, add variable bitrates for Ogg)
This commit is contained in:
@@ -29,19 +29,15 @@
|
||||
#include <QtCore/QFile>
|
||||
|
||||
#include "AudioDevice.h"
|
||||
#include "OutputSettings.h"
|
||||
|
||||
|
||||
class AudioFileDevice : public AudioDevice
|
||||
{
|
||||
public:
|
||||
AudioFileDevice( const sample_rate_t _sample_rate,
|
||||
const ch_cnt_t _channels, const QString & _file,
|
||||
const bool _use_vbr,
|
||||
const bitrate_t _nom_bitrate,
|
||||
const bitrate_t _min_bitrate,
|
||||
const bitrate_t _max_bitrate,
|
||||
const int _depth,
|
||||
Mixer* mixer );
|
||||
AudioFileDevice(OutputSettings const & outputSettings,
|
||||
const ch_cnt_t _channels, const QString & _file,
|
||||
Mixer* mixer );
|
||||
virtual ~AudioFileDevice();
|
||||
|
||||
QString outputFile() const
|
||||
@@ -49,35 +45,12 @@ public:
|
||||
return m_outputFile.fileName();
|
||||
}
|
||||
|
||||
OutputSettings const & getOutputSettings() const { return m_outputSettings; }
|
||||
|
||||
|
||||
protected:
|
||||
int writeData( const void* data, int len );
|
||||
|
||||
inline bool useVBR() const
|
||||
{
|
||||
return m_useVbr;
|
||||
}
|
||||
|
||||
inline bitrate_t nominalBitrate() const
|
||||
{
|
||||
return m_nomBitrate;
|
||||
}
|
||||
|
||||
inline bitrate_t minBitrate() const
|
||||
{
|
||||
return m_minBitrate;
|
||||
}
|
||||
|
||||
inline bitrate_t maxBitrate() const
|
||||
{
|
||||
return m_maxBitrate;
|
||||
}
|
||||
|
||||
inline int depth() const
|
||||
{
|
||||
return m_depth;
|
||||
}
|
||||
|
||||
inline bool outputFileOpened() const
|
||||
{
|
||||
return m_outputFile.isOpen();
|
||||
@@ -86,29 +59,16 @@ protected:
|
||||
|
||||
private:
|
||||
QFile m_outputFile;
|
||||
|
||||
bool m_useVbr;
|
||||
|
||||
bitrate_t m_nomBitrate;
|
||||
bitrate_t m_minBitrate;
|
||||
bitrate_t m_maxBitrate;
|
||||
|
||||
int m_depth;
|
||||
|
||||
OutputSettings m_outputSettings;
|
||||
} ;
|
||||
|
||||
|
||||
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,
|
||||
const int _depth,
|
||||
Mixer* mixer );
|
||||
( const QString & outputFilename,
|
||||
OutputSettings const & outputSettings,
|
||||
const ch_cnt_t channels,
|
||||
Mixer* mixer,
|
||||
bool & successful );
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -38,33 +38,21 @@
|
||||
class AudioFileOgg : public AudioFileDevice
|
||||
{
|
||||
public:
|
||||
AudioFileOgg( const sample_rate_t _sample_rate,
|
||||
AudioFileOgg( OutputSettings const & outputSettings,
|
||||
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,
|
||||
const int _depth,
|
||||
Mixer* mixer );
|
||||
virtual ~AudioFileOgg();
|
||||
|
||||
static AudioFileDevice * getInst( 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,
|
||||
const int _depth,
|
||||
Mixer* mixer )
|
||||
static AudioFileDevice * getInst( const QString & outputFilename,
|
||||
OutputSettings const & outputSettings,
|
||||
const ch_cnt_t channels,
|
||||
Mixer* mixer,
|
||||
bool & successful )
|
||||
{
|
||||
return new AudioFileOgg( _sample_rate, _channels, _success_ful,
|
||||
_file, _use_vbr, _nom_bitrate,
|
||||
_min_bitrate, _max_bitrate,
|
||||
_depth, mixer );
|
||||
return new AudioFileOgg( outputSettings, channels, successful,
|
||||
outputFilename, mixer );
|
||||
}
|
||||
|
||||
|
||||
@@ -77,15 +65,33 @@ private:
|
||||
void finishEncoding();
|
||||
inline int writePage();
|
||||
|
||||
inline bitrate_t nominalBitrate() const
|
||||
{
|
||||
return getOutputSettings().getBitRateSettings().getBitRate();
|
||||
}
|
||||
|
||||
inline bitrate_t minBitrate() const
|
||||
{
|
||||
if (nominalBitrate() > 64)
|
||||
{
|
||||
return nominalBitrate() - 64;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
}
|
||||
|
||||
inline bitrate_t maxBitrate() const
|
||||
{
|
||||
return nominalBitrate() + 64;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_ok;
|
||||
ch_cnt_t m_channels;
|
||||
sample_rate_t m_rate;
|
||||
|
||||
// Various bitrate/quality options
|
||||
bitrate_t m_minBitrate;
|
||||
bitrate_t m_maxBitrate;
|
||||
|
||||
uint32_t m_serialNo;
|
||||
|
||||
vorbis_comment * m_comments;
|
||||
|
||||
@@ -35,34 +35,21 @@
|
||||
class AudioFileWave : public AudioFileDevice
|
||||
{
|
||||
public:
|
||||
AudioFileWave( 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,
|
||||
const int _depth,
|
||||
AudioFileWave( OutputSettings const & outputSettings,
|
||||
const ch_cnt_t channels,
|
||||
bool & successful,
|
||||
const QString & file,
|
||||
Mixer* mixer );
|
||||
virtual ~AudioFileWave();
|
||||
|
||||
static AudioFileDevice * getInst( 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,
|
||||
const int _depth,
|
||||
Mixer* mixer )
|
||||
static AudioFileDevice * getInst( const QString & outputFilename,
|
||||
OutputSettings const & outputSettings,
|
||||
const ch_cnt_t channels,
|
||||
Mixer* mixer,
|
||||
bool & successful )
|
||||
{
|
||||
return new AudioFileWave( _sample_rate, _channels,
|
||||
_success_ful, _file, _use_vbr,
|
||||
_nom_bitrate, _min_bitrate,
|
||||
_max_bitrate, _depth,
|
||||
mixer );
|
||||
return new AudioFileWave( outputSettings, channels, successful,
|
||||
outputFilename, mixer );
|
||||
}
|
||||
|
||||
|
||||
@@ -74,11 +61,9 @@ private:
|
||||
bool startEncoding();
|
||||
void finishEncoding();
|
||||
|
||||
|
||||
private:
|
||||
SF_INFO m_si;
|
||||
SNDFILE * m_sf;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -53,6 +53,8 @@ private slots:
|
||||
void accept();
|
||||
void startExport();
|
||||
|
||||
void onFileFormatChanged(int);
|
||||
|
||||
private:
|
||||
QString m_fileName;
|
||||
QString m_dirName;
|
||||
|
||||
85
include/OutputSettings.h
Normal file
85
include/OutputSettings.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* OutputSettings.h - Stores the settings for file rendering
|
||||
*
|
||||
* Copyright (c) 2008-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2017 Michael Gregorius <michael.gregorius.git/at/arcor[dot]de>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* 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 OUTPUT_SETTINGS_H
|
||||
#define OUTPUT_SETTINGS_H
|
||||
|
||||
|
||||
class OutputSettings
|
||||
{
|
||||
public:
|
||||
enum BitDepth
|
||||
{
|
||||
Depth_16Bit,
|
||||
Depth_24Bit,
|
||||
Depth_32Bit,
|
||||
NumDepths
|
||||
};
|
||||
|
||||
class BitRateSettings
|
||||
{
|
||||
public:
|
||||
BitRateSettings(bitrate_t bitRate, bool isVariableBitRate) :
|
||||
m_bitRate(bitRate),
|
||||
m_isVariableBitRate(isVariableBitRate)
|
||||
{}
|
||||
|
||||
bool isVariableBitRate() const { return m_isVariableBitRate; }
|
||||
void setVariableBitrate(bool variableBitRate = true) { m_isVariableBitRate = variableBitRate; }
|
||||
|
||||
bitrate_t getBitRate() const { return m_bitRate; }
|
||||
void setBitRate(bitrate_t bitRate) { m_bitRate = bitRate; }
|
||||
|
||||
private:
|
||||
bitrate_t m_bitRate;
|
||||
bool m_isVariableBitRate;
|
||||
};
|
||||
|
||||
public:
|
||||
OutputSettings( sample_rate_t sampleRate,
|
||||
BitRateSettings const & bitRateSettings,
|
||||
BitDepth bitDepth ) :
|
||||
m_sampleRate(sampleRate),
|
||||
m_bitRateSettings(bitRateSettings),
|
||||
m_bitDepth(bitDepth)
|
||||
{
|
||||
}
|
||||
|
||||
sample_rate_t getSampleRate() const { return m_sampleRate; }
|
||||
void setSampleRate(sample_rate_t sampleRate) { m_sampleRate = sampleRate; }
|
||||
|
||||
BitRateSettings const & getBitRateSettings() const { return m_bitRateSettings; }
|
||||
void setBitRateSettings(BitRateSettings const & bitRateSettings) { m_bitRateSettings = bitRateSettings; }
|
||||
|
||||
BitDepth getBitDepth() const { return m_bitDepth; }
|
||||
void setBitDepth(BitDepth bitDepth) { m_bitDepth = bitDepth; }
|
||||
|
||||
private:
|
||||
sample_rate_t m_sampleRate;
|
||||
BitRateSettings m_bitRateSettings;
|
||||
BitDepth m_bitDepth;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "AudioFileDevice.h"
|
||||
#include "lmmsconfig.h"
|
||||
#include "Mixer.h"
|
||||
#include "OutputSettings.h"
|
||||
|
||||
|
||||
class ProjectRenderer : public QThread
|
||||
@@ -41,30 +42,6 @@ public:
|
||||
NumFileFormats
|
||||
} ;
|
||||
|
||||
enum Depths
|
||||
{
|
||||
Depth_16Bit,
|
||||
Depth_32Bit,
|
||||
NumDepths
|
||||
} ;
|
||||
|
||||
struct OutputSettings
|
||||
{
|
||||
sample_rate_t samplerate;
|
||||
bool vbr;
|
||||
int bitrate;
|
||||
Depths depth;
|
||||
|
||||
OutputSettings( sample_rate_t _sr, bool _vbr, int _bitrate,
|
||||
Depths _d ) :
|
||||
samplerate( _sr ),
|
||||
vbr( _vbr ),
|
||||
bitrate( _bitrate ),
|
||||
depth( _d )
|
||||
{
|
||||
}
|
||||
} ;
|
||||
|
||||
struct FileEncodeDevice
|
||||
{
|
||||
ExportFileFormats m_fileFormat;
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "ProjectRenderer.h"
|
||||
#include "OutputSettings.h"
|
||||
|
||||
|
||||
class RenderManager : public QObject
|
||||
{
|
||||
@@ -36,7 +38,7 @@ class RenderManager : public QObject
|
||||
public:
|
||||
RenderManager(
|
||||
const Mixer::qualitySettings & qualitySettings,
|
||||
const ProjectRenderer::OutputSettings & outputSettings,
|
||||
const OutputSettings & outputSettings,
|
||||
ProjectRenderer::ExportFileFormats fmt,
|
||||
QString outputPath);
|
||||
|
||||
@@ -63,7 +65,7 @@ private:
|
||||
void restoreMutedState();
|
||||
|
||||
const Mixer::qualitySettings m_qualitySettings;
|
||||
const ProjectRenderer::OutputSettings m_outputSettings;
|
||||
const OutputSettings m_outputSettings;
|
||||
ProjectRenderer::ExportFileFormats m_format;
|
||||
QString m_outputPath;
|
||||
|
||||
|
||||
@@ -60,35 +60,32 @@ const ProjectRenderer::FileEncodeDevice ProjectRenderer::fileEncodeDevices[] =
|
||||
|
||||
|
||||
|
||||
ProjectRenderer::ProjectRenderer( const Mixer::qualitySettings & _qs,
|
||||
const OutputSettings & _os,
|
||||
ExportFileFormats _file_format,
|
||||
const QString & _out_file ) :
|
||||
ProjectRenderer::ProjectRenderer( const Mixer::qualitySettings & qualitySettings,
|
||||
const OutputSettings & outputSettings,
|
||||
ExportFileFormats exportFileFormat,
|
||||
const QString & outputFilename ) :
|
||||
QThread( Engine::mixer() ),
|
||||
m_fileDev( NULL ),
|
||||
m_qualitySettings( _qs ),
|
||||
m_qualitySettings( qualitySettings ),
|
||||
m_oldQualitySettings( Engine::mixer()->currentQualitySettings() ),
|
||||
m_progress( 0 ),
|
||||
m_abort( false )
|
||||
{
|
||||
if( fileEncodeDevices[_file_format].m_getDevInst == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
AudioFileDeviceInstantiaton audioEncoderFactory = fileEncodeDevices[exportFileFormat].m_getDevInst;
|
||||
|
||||
bool success_ful = false;
|
||||
m_fileDev = fileEncodeDevices[_file_format].m_getDevInst(
|
||||
_os.samplerate, DEFAULT_CHANNELS, success_ful,
|
||||
_out_file, _os.vbr,
|
||||
_os.bitrate, _os.bitrate - 64, _os.bitrate + 64,
|
||||
_os.depth == Depth_32Bit ? 32 : 16,
|
||||
Engine::mixer() );
|
||||
if( success_ful == false )
|
||||
if (audioEncoderFactory)
|
||||
{
|
||||
delete m_fileDev;
|
||||
m_fileDev = NULL;
|
||||
}
|
||||
bool successful = false;
|
||||
|
||||
m_fileDev = audioEncoderFactory(
|
||||
outputFilename, outputSettings, DEFAULT_CHANNELS,
|
||||
Engine::mixer(), successful );
|
||||
if( !successful )
|
||||
{
|
||||
delete m_fileDev;
|
||||
m_fileDev = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,9 +30,10 @@
|
||||
#include "BBTrackContainer.h"
|
||||
#include "BBTrack.h"
|
||||
|
||||
|
||||
RenderManager::RenderManager(
|
||||
const Mixer::qualitySettings & qualitySettings,
|
||||
const ProjectRenderer::OutputSettings & outputSettings,
|
||||
const OutputSettings & outputSettings,
|
||||
ProjectRenderer::ExportFileFormats fmt,
|
||||
QString outputPath) :
|
||||
m_qualitySettings(qualitySettings),
|
||||
|
||||
@@ -30,24 +30,15 @@
|
||||
#include "GuiApplication.h"
|
||||
|
||||
|
||||
AudioFileDevice::AudioFileDevice( const sample_rate_t _sample_rate,
|
||||
AudioFileDevice::AudioFileDevice( OutputSettings const & outputSettings,
|
||||
const ch_cnt_t _channels,
|
||||
const QString & _file,
|
||||
const bool _use_vbr,
|
||||
const bitrate_t _nom_bitrate,
|
||||
const bitrate_t _min_bitrate,
|
||||
const bitrate_t _max_bitrate,
|
||||
const int _depth,
|
||||
Mixer* _mixer ) :
|
||||
AudioDevice( _channels, _mixer ),
|
||||
m_outputFile( _file ),
|
||||
m_useVbr( _use_vbr ),
|
||||
m_nomBitrate( _nom_bitrate ),
|
||||
m_minBitrate( _min_bitrate ),
|
||||
m_maxBitrate( _max_bitrate ),
|
||||
m_depth( _depth )
|
||||
m_outputSettings(outputSettings)
|
||||
{
|
||||
setSampleRate( _sample_rate );
|
||||
setSampleRate( outputSettings.getSampleRate() );
|
||||
|
||||
if( m_outputFile.open( QFile::WriteOnly | QFile::Truncate ) == false )
|
||||
{
|
||||
|
||||
@@ -36,21 +36,14 @@
|
||||
#include "Mixer.h"
|
||||
|
||||
|
||||
AudioFileOgg::AudioFileOgg( 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,
|
||||
const int _depth,
|
||||
Mixer* _mixer ) :
|
||||
AudioFileDevice( _sample_rate, _channels, _file, _use_vbr,
|
||||
_nom_bitrate, _min_bitrate, _max_bitrate,
|
||||
_depth, _mixer )
|
||||
AudioFileOgg::AudioFileOgg( OutputSettings const & outputSettings,
|
||||
const ch_cnt_t channels,
|
||||
bool & successful,
|
||||
const QString & file,
|
||||
Mixer* mixer ) :
|
||||
AudioFileDevice( outputSettings, channels, file, mixer )
|
||||
{
|
||||
m_ok = _success_ful = outputFileOpened() && startEncoding();
|
||||
m_ok = successful = outputFileOpened() && startEncoding();
|
||||
}
|
||||
|
||||
|
||||
@@ -89,18 +82,18 @@ bool AudioFileOgg::startEncoding()
|
||||
vc.vendor = NULL;
|
||||
|
||||
m_channels = channels();
|
||||
// vbr enabled?
|
||||
if( useVBR() == 0 )
|
||||
|
||||
bool useVariableBitRate = getOutputSettings().getBitRateSettings().isVariableBitRate();
|
||||
bitrate_t minimalBitrate = nominalBitrate();
|
||||
bitrate_t maximumBitrate = nominalBitrate();
|
||||
|
||||
if( useVariableBitRate )
|
||||
{
|
||||
m_minBitrate = nominalBitrate(); // min for vbr
|
||||
m_maxBitrate = nominalBitrate(); // max for vbr
|
||||
}
|
||||
else
|
||||
{
|
||||
m_minBitrate = minBitrate(); // min for vbr
|
||||
m_maxBitrate = maxBitrate(); // max for vbr
|
||||
minimalBitrate = minBitrate(); // min for vbr
|
||||
maximumBitrate = maxBitrate(); // max for vbr
|
||||
}
|
||||
|
||||
|
||||
m_rate = sampleRate(); // default-samplerate
|
||||
if( m_rate > 48000 )
|
||||
{
|
||||
@@ -114,9 +107,9 @@ bool AudioFileOgg::startEncoding()
|
||||
vorbis_info_init( &m_vi );
|
||||
|
||||
if( vorbis_encode_setup_managed( &m_vi, m_channels, m_rate,
|
||||
( m_maxBitrate > 0 )? m_maxBitrate * 1000 : -1,
|
||||
( maximumBitrate > 0 )? maximumBitrate * 1000 : -1,
|
||||
nominalBitrate() * 1000,
|
||||
( m_minBitrate > 0 )? m_minBitrate * 1000 : -1 ) )
|
||||
( minimalBitrate > 0 )? minimalBitrate * 1000 : -1 ) )
|
||||
{
|
||||
printf( "Mode initialization failed: invalid parameters for "
|
||||
"bitrate\n" );
|
||||
@@ -125,15 +118,15 @@ bool AudioFileOgg::startEncoding()
|
||||
return false;
|
||||
}
|
||||
|
||||
if( useVBR() == false )
|
||||
{
|
||||
vorbis_encode_ctl( &m_vi, OV_ECTL_RATEMANAGE_AVG, NULL );
|
||||
}
|
||||
else if( useVBR() == true )
|
||||
if( useVariableBitRate )
|
||||
{
|
||||
// Turn off management entirely (if it was turned on).
|
||||
vorbis_encode_ctl( &m_vi, OV_ECTL_RATEMANAGE_SET, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
vorbis_encode_ctl( &m_vi, OV_ECTL_RATEMANAGE_AVG, NULL );
|
||||
}
|
||||
|
||||
vorbis_encode_setup_init( &m_vi );
|
||||
|
||||
|
||||
@@ -28,21 +28,14 @@
|
||||
#include "Mixer.h"
|
||||
|
||||
|
||||
AudioFileWave::AudioFileWave( 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,
|
||||
const int _depth,
|
||||
Mixer* _mixer ) :
|
||||
AudioFileDevice( _sample_rate, _channels, _file, _use_vbr,
|
||||
_nom_bitrate, _min_bitrate, _max_bitrate,
|
||||
_depth, _mixer ),
|
||||
AudioFileWave::AudioFileWave( OutputSettings const & outputSettings,
|
||||
const ch_cnt_t channels, bool & successful,
|
||||
const QString & file,
|
||||
Mixer* mixer ) :
|
||||
AudioFileDevice( outputSettings, channels, file, mixer ),
|
||||
m_sf( NULL )
|
||||
{
|
||||
_success_ful = outputFileOpened() && startEncoding();
|
||||
successful = outputFileOpened() && startEncoding();
|
||||
}
|
||||
|
||||
|
||||
@@ -64,11 +57,20 @@ bool AudioFileWave::startEncoding()
|
||||
m_si.sections = 1;
|
||||
m_si.seekable = 0;
|
||||
|
||||
switch( depth() )
|
||||
m_si.format = SF_FORMAT_WAV;
|
||||
|
||||
switch( getOutputSettings().getBitDepth() )
|
||||
{
|
||||
case 32: m_si.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT; break;
|
||||
case 16:
|
||||
default: m_si.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; break;
|
||||
case OutputSettings::Depth_32Bit:
|
||||
m_si.format |= SF_FORMAT_FLOAT;
|
||||
break;
|
||||
case OutputSettings::Depth_24Bit:
|
||||
m_si.format |= SF_FORMAT_PCM_24;
|
||||
break;
|
||||
case OutputSettings::Depth_16Bit:
|
||||
default:
|
||||
m_si.format |= SF_FORMAT_PCM_16;
|
||||
break;
|
||||
}
|
||||
m_sf = sf_open(
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
@@ -88,7 +90,9 @@ void AudioFileWave::writeBuffer( const surroundSampleFrame * _ab,
|
||||
const fpp_t _frames,
|
||||
const float _master_gain )
|
||||
{
|
||||
if( depth() == 32 )
|
||||
OutputSettings::BitDepth bitDepth = getOutputSettings().getBitDepth();
|
||||
|
||||
if( bitDepth == OutputSettings::Depth_32Bit || bitDepth == OutputSettings::Depth_24Bit )
|
||||
{
|
||||
float * buf = new float[_frames*channels()];
|
||||
for( fpp_t frame = 0; frame < _frames; ++frame )
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
#include "GuiApplication.h"
|
||||
#include "ImportFilter.h"
|
||||
#include "MainWindow.h"
|
||||
#include "OutputSettings.h"
|
||||
#include "ProjectRenderer.h"
|
||||
#include "RenderManager.h"
|
||||
#include "Song.h"
|
||||
@@ -259,8 +260,7 @@ int main( int argc, char * * argv )
|
||||
new MainApplication( argc, argv );
|
||||
|
||||
Mixer::qualitySettings qs( Mixer::qualitySettings::Mode_HighQuality );
|
||||
ProjectRenderer::OutputSettings os( 44100, false, 160,
|
||||
ProjectRenderer::Depth_16Bit );
|
||||
OutputSettings os( 44100, OutputSettings::BitRateSettings(160, false), OutputSettings::Depth_16Bit );
|
||||
ProjectRenderer::ExportFileFormats eff = ProjectRenderer::WaveFile;
|
||||
|
||||
// second of two command-line parsing stages
|
||||
@@ -414,7 +414,7 @@ int main( int argc, char * * argv )
|
||||
sample_rate_t sr = QString( argv[i] ).toUInt();
|
||||
if( sr >= 44100 && sr <= 192000 )
|
||||
{
|
||||
os.samplerate = sr;
|
||||
os.setSampleRate(sr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -439,7 +439,9 @@ int main( int argc, char * * argv )
|
||||
|
||||
if( br >= 64 && br <= 384 )
|
||||
{
|
||||
os.bitrate = br;
|
||||
OutputSettings::BitRateSettings bitRateSettings = os.getBitRateSettings();
|
||||
bitRateSettings.setBitRate(br);
|
||||
os.setBitRateSettings(bitRateSettings);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -450,7 +452,7 @@ int main( int argc, char * * argv )
|
||||
}
|
||||
else if( arg =="--float" || arg == "-a" )
|
||||
{
|
||||
os.depth = ProjectRenderer::Depth_32Bit;
|
||||
os.setBitDepth(OutputSettings::Depth_32Bit);
|
||||
}
|
||||
else if( arg == "--interpolation" || arg == "-i" )
|
||||
{
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "Song.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "MainWindow.h"
|
||||
#include "OutputSettings.h"
|
||||
|
||||
|
||||
ExportProjectDialog::ExportProjectDialog( const QString & _file_name,
|
||||
@@ -137,13 +138,15 @@ void ExportProjectDialog::startExport()
|
||||
static_cast<Mixer::qualitySettings::Oversampling>(oversamplingCB->currentIndex()) );
|
||||
|
||||
const int samplerates[5] = { 44100, 48000, 88200, 96000, 192000 };
|
||||
const int bitrates[6] = { 64, 128, 160, 192, 256, 320 };
|
||||
const bitrate_t bitrates[6] = { 64, 128, 160, 192, 256, 320 };
|
||||
|
||||
ProjectRenderer::OutputSettings os = ProjectRenderer::OutputSettings(
|
||||
bool useVariableBitRate = checkBoxVariableBitRate->isChecked();
|
||||
|
||||
OutputSettings::BitRateSettings bitRateSettings(bitrates[ bitrateCB->currentIndex() ], useVariableBitRate);
|
||||
OutputSettings os = OutputSettings(
|
||||
samplerates[ samplerateCB->currentIndex() ],
|
||||
false,
|
||||
bitrates[ bitrateCB->currentIndex() ],
|
||||
static_cast<ProjectRenderer::Depths>( depthCB->currentIndex() ) );
|
||||
bitRateSettings,
|
||||
static_cast<OutputSettings::BitDepth>( depthCB->currentIndex() ) );
|
||||
|
||||
m_renderManager = new RenderManager( qs, os, m_ft, m_fileName );
|
||||
|
||||
@@ -170,7 +173,35 @@ void ExportProjectDialog::startExport()
|
||||
}
|
||||
|
||||
|
||||
ProjectRenderer::ExportFileFormats convertIndexToExportFileFormat(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return ProjectRenderer::WaveFile;
|
||||
case 1:
|
||||
return ProjectRenderer::OggFile;
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return ProjectRenderer::NumFileFormats;
|
||||
}
|
||||
|
||||
|
||||
void ExportProjectDialog::onFileFormatChanged(int index)
|
||||
{
|
||||
ProjectRenderer::ExportFileFormats exportFormat =
|
||||
convertIndexToExportFileFormat(index);
|
||||
|
||||
bool bitRateControlsEnabled = exportFormat == ProjectRenderer::OggFile;
|
||||
bool bitDepthControlEnabled = exportFormat == ProjectRenderer::WaveFile;
|
||||
|
||||
bitrateWidget->setVisible(bitRateControlsEnabled);
|
||||
|
||||
depthWidget->setVisible(bitDepthControlEnabled);
|
||||
}
|
||||
|
||||
void ExportProjectDialog::startBtnClicked()
|
||||
{
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>519</width>
|
||||
<height>412</height>
|
||||
<width>715</width>
|
||||
<height>447</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
@@ -80,26 +80,61 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="depthWidget" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelBitDepth">
|
||||
<property name="text">
|
||||
<string>Depth:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="depthCB">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>16 Bit Integer</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>24 Bit Integer</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>32 Bit Float</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="bitrateWidget" native="true">
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</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">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<widget class="QLabel" name="labelBitRate">
|
||||
<property name="text">
|
||||
<string>Bitrate:</string>
|
||||
</property>
|
||||
@@ -142,74 +177,16 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="depthWidget" native="true">
|
||||
<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">
|
||||
<widget class="QCheckBox" name="checkBoxVariableBitRate">
|
||||
<property name="text">
|
||||
<string>Depth:</string>
|
||||
<string>Use variable bitrate</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>32 Bit Float</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Please note that not all of the parameters above apply for all file formats.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
@@ -381,8 +358,8 @@
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>357</x>
|
||||
<y>293</y>
|
||||
<x>511</x>
|
||||
<y>372</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>202</x>
|
||||
@@ -390,5 +367,24 @@
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>fileFormatCB</sender>
|
||||
<signal>currentIndexChanged(int)</signal>
|
||||
<receiver>ExportProjectDialog</receiver>
|
||||
<slot>onFileFormatChanged(int)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>111</x>
|
||||
<y>85</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>518</x>
|
||||
<y>212</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>onFileFormatChanged(int)</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
|
||||
Reference in New Issue
Block a user