added FLAC as an export format

This commit is contained in:
Andrew Kelley
2009-08-12 07:18:16 -07:00
parent 6cf2d83808
commit fb733051bd
8 changed files with 281 additions and 4 deletions

View File

@@ -68,6 +68,7 @@ OPTION(WANT_VST "Include VST support" ON)
OPTION(WANT_VST_NOWINE "Include partial VST support (without wine)" OFF)
OPTION(WANT_WINMM "Include WinMM MIDI support" OFF)
OPTION(WANT_ZIP "Include zip support" ON)
OPTION(WANT_FLAC "Include flac support" ON)
IF(LMMS_BUILD_WIN32)
SET(WANT_ALSA OFF)
@@ -199,6 +200,18 @@ IF(WANT_ZIP)
ENDIF(ZIP_FOUND)
ENDIF(WANT_ZIP)
# check for libflac++
IF(WANT_FLAC)
FIND_PACKAGE(FLAC)
IF(FLAC_FOUND)
SET(LMMS_HAVE_FLAC TRUE)
SET(STATUS_FLAC "OK")
ELSE(FLAC_FOUND)
SET(STATUS_FLAC "not found, install libflac++-dev (or similar) "
"if you want flac as an export format")
ENDIF(FLAC_FOUND)
ENDIF(WANT_FLAC)
# check for Stk
IF(WANT_STK)
FIND_PACKAGE(STK)
@@ -528,9 +541,9 @@ ADD_SUBDIRECTORY(data)
#
ADD_DEFINITIONS(-D'LIB_DIR="${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/"' -D'PLUGIN_DIR="${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/lmms/"' ${PULSEAUDIO_DEFINITIONS} ${PORTAUDIO_DEFINITIONS})
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/include ${SDL_INCLUDE_DIR} ${PORTAUDIO_INCLUDE_DIR} ${PULSEAUDIO_INCLUDE_DIR} ${JACK_INCLUDE_DIRS} ${OGGVORBIS_INCLUDE_DIR} ${SAMPLERATE_INCLUDE_DIRS} ${SNDFILE_INCLUDE_DIRS} ${ZIP_INCLUDE_DIR})
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/include ${SDL_INCLUDE_DIR} ${PORTAUDIO_INCLUDE_DIR} ${PULSEAUDIO_INCLUDE_DIR} ${JACK_INCLUDE_DIRS} ${OGGVORBIS_INCLUDE_DIR} ${SAMPLERATE_INCLUDE_DIRS} ${SNDFILE_INCLUDE_DIRS} ${ZIP_INCLUDE_DIR} ${FLAC_INCLUDE_DIR})
LINK_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/lib ${ASOUND_LIBRARY_DIR} ${JACK_LIBRARY_DIRS} ${SAMPLERATE_LIBRARY_DIRS} ${SNDFILE_LIBRARY_DIRS})
LINK_LIBRARIES(${QT_LIBRARIES} ${ASOUND_LIBRARY} ${SDL_LIBRARY} ${PORTAUDIO_LIBRARIES} ${PULSEAUDIO_LIBRARIES} ${JACK_LIBRARIES} ${OGGVORBIS_LIBRARIES} ${SAMPLERATE_LIBRARIES} ${SNDFILE_LIBRARIES} ${ZIP_LIBRARIES} ${SLV2_LIBRARY})
LINK_LIBRARIES(${QT_LIBRARIES} ${ASOUND_LIBRARY} ${SDL_LIBRARY} ${PORTAUDIO_LIBRARIES} ${PULSEAUDIO_LIBRARIES} ${JACK_LIBRARIES} ${OGGVORBIS_LIBRARIES} ${SAMPLERATE_LIBRARIES} ${SNDFILE_LIBRARIES} ${ZIP_LIBRARIES} ${FLAC_LIBRARIES} ${SLV2_LIBRARY})
ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_BINARY_DIR}/lmms.1.gz COMMAND gzip -c ${CMAKE_SOURCE_DIR}/lmms.1 > ${CMAKE_BINARY_DIR}/lmms.1.gz DEPENDS ${CMAKE_SOURCE_DIR}/lmms.1 COMMENT "Generating lmms.1.gz")
@@ -698,6 +711,7 @@ MESSAGE(
"-----------------------------------------\n"
"* WAVE : OK\n"
"* OGG/VORBIS : ${STATUS_OGGVORBIS}\n"
"* FLAC : ${STATUS_FLAC}\n"
)
MESSAGE(

View File

@@ -0,0 +1,31 @@
# Find libflac++
# find the native libflac++ includes and library
#
#
# FLAC_INCLUDE_DIRS - where to find the .h files
# FLAC_LIBRARIES - list of libraries when using libflac++
# FLAC_FOUND - True if libflac++ found.
FIND_PATH(FLAC_INCLUDE_DIRS all.h /usr/include/FLAC++ /local/usr/include/FLAC++)
FIND_PATH(FLAC_INCLUDE_DIRS decoder.h /usr/include/FLAC++ /local/usr/include/FLAC++)
FIND_PATH(FLAC_INCLUDE_DIRS encoder.h /usr/include/FLAC++ /local/usr/include/FLAC++)
FIND_PATH(FLAC_INCLUDE_DIRS export.h /usr/include/FLAC++ /local/usr/include/FLAC++)
FIND_PATH(FLAC_INCLUDE_DIRS metadata.h /usr/include/FLAC++ /local/usr/include/FLAC++)
FIND_LIBRARY(FLAC_LIBRARIES NAMES FLAC++ PATH /usr/lib /usr/local/lib)
IF(FLAC_INCLUDE_DIRS AND FLAC_LIBRARIES)
SET(FLAC_FOUND TRUE)
ENDIF(FLAC_INCLUDE_DIRS AND FLAC_LIBRARIES)
IF(FLAC_FOUND)
IF(NOT FLAC_FIND_QUIETLY)
MESSAGE(STATUS "Found libflac++: ${FLAC_LIBRARIES}")
ENDIF(NOT FLAC_FIND_QUIETLY)
ELSE(FLAC_FOUND)
SET(FLAC_LIBRARIES "")
SET(FLAC_INCLUDE_DIRS "")
MESSAGE(STATUS "Could not find libflac++")
ENDIF(FLAC_FOUND)
MARK_AS_ADVANCED( FLAC_LIBRARIES FLAC_INCLUDE_DIRS )

89
include/audio_file_flac.h Normal file
View File

@@ -0,0 +1,89 @@
/*
* audio_file_flac.h - Audio-device which encodes a flac stream and writes it
* into a flac file. This is used for song-export.
*
* Copyright (c) 2009 Andrew Kelley <superjoe30@gmail.com>
*
* 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 _AUDIO_FILE_FLAC_H_
#define _AUDIO_FILE_FLAC_H_
#include <QFile>
#include "audio_file_device.h"
#include "FLAC++/metadata.h"
#include "FLAC++/encoder.h"
class AudioFileFlac : public audioFileDevice
{
public:
AudioFileFlac( 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 );
virtual ~AudioFileFlac();
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 )
{
return( new AudioFileFlac( _sample_rate, _channels,
_success_ful, _file, _use_vbr,
_nom_bitrate, _min_bitrate,
_max_bitrate, _depth,
_mixer ) );
}
private:
short int rescale(float sample); // convert float flame to short int frame
// overloaded functions
virtual void writeBuffer( const surroundSampleFrame * _ab,
const fpp_t _frames,
float _master_gain );
bool startEncoding( void );
void finishEncoding( void );
FLAC::Encoder::File m_encoder;
} ;
#endif //_AUDIO_FILE_FLAC_H_
/* vim: set tw=0 noexpandtab: */

View File

@@ -39,6 +39,7 @@ public:
WaveFile,
OggFile,
Mp3File,
FlacFile,
NumFileFormats
} ;

View File

@@ -19,6 +19,7 @@
#cmakedefine LMMS_HAVE_STK
#cmakedefine LMMS_HAVE_VST
#cmakedefine LMMS_HAVE_ZIP
#cmakedefine LMMS_HAVE_FLAC
#cmakedefine LMMS_HAVE_STDINT_H
#cmakedefine LMMS_HAVE_STDBOOL_H

View File

@@ -0,0 +1,125 @@
/*
* audio_file_flac.cpp - Audio-device which encodes a flac stream and writes it
* into a flac file. This is used for song-export.
*
* Copyright (c) 2009 Andrew Kelley <superjoe30@gmail.com>
*
* 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 "audio_file_flac.h"
#include <QtDebug>
#include "lmms_basics.h"
AudioFileFlac::AudioFileFlac( 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 )
{
_success_ful = startEncoding();
}
bool AudioFileFlac::startEncoding( void )
{
// check the encoder
if( ! m_encoder )
{
qWarning() << "AudioFileFlac: unable to allocate encoder";
return false;
}
bool ok = true;
ok &= m_encoder.set_verify(true);
ok &= m_encoder.set_compression_level(5);
ok &= m_encoder.set_channels(channels());
ok &= m_encoder.set_bits_per_sample(16);
ok &= m_encoder.set_sample_rate(sampleRate());
//ok &= encoder.set_total_samples_estimate(??);
if( ! ok ) return false;
// TODO: set metadata: http://flac.cvs.sourceforge.net/viewvc/flac/flac/examples/cpp/encode/file/main.cpp?view=markup
// initialize encoder
FLAC__StreamEncoderInitStatus init_status = m_encoder.init(
outputFile().toAscii());
if( init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK )
{
qWarning() << "AudioFileFlac: unable to initialize encoder:" <<
FLAC__StreamEncoderInitStatusString[init_status];
return false;
}
return true;
}
Sint16 AudioFileFlac::rescale(float sample) {
return (qMax<float>(qMin<float>(sample, 1), -1) / 1)
* std::numeric_limits<Sint16>::max();
}
// encode data and write to file
void AudioFileFlac::writeBuffer( const surroundSampleFrame * _ab,
const fpp_t _frames, const float _master_gain )
{
// scale to short int instead of float
FLAC__int32 * in = new FLAC__int32[_frames*channels()];
for(int i=0; i < _frames; ++i)
{
for(int c=0; c < channels(); ++c)
{
in[i*channels()+c] = (FLAC__int32) rescale( _ab[i][c]
* _master_gain );
}
}
// feed to the encoder
m_encoder.process_interleaved(in, _frames);
// clean up
delete[] in;
}
void AudioFileFlac::finishEncoding( void )
{
m_encoder.finish();
}
AudioFileFlac::~AudioFileFlac()
{
finishEncoding();
}
/* vim: set tw=0 noexpandtab: */

View File

@@ -160,7 +160,7 @@ int main( int argc, char * * argv )
"-r, --render <project file> render given project file\n"
"-o, --output <file> render into <file>\n"
"-f, --output-format <format> specify format of render-output where\n"
" format is either 'wav', 'ogg', or 'mp3'.\n"
" format is either 'wav', 'ogg', 'mp3', or 'flac'.\n"
"-s, --samplerate <samplerate> specify output samplerate in Hz\n"
" range: 44100 (default) to 192000\n"
"-b, --bitrate <bitrate> specify output bitrate in kHz\n"
@@ -229,6 +229,12 @@ int main( int argc, char * * argv )
{
eff = projectRenderer::Mp3File;
}
#ifdef LMMS_HAVE_FLAC
else if( ext == "flac" )
{
eff = projectRenderer::FlacFile;
}
#endif
else
{
printf( "\nInvalid output format %s.\n\n"

View File

@@ -33,6 +33,7 @@
#include "audio_file_wave.h"
#include "audio_file_ogg.h"
#include "audio_file_mp3.h"
#include "audio_file_flac.h"
#ifdef LMMS_HAVE_PTHREAD_H
#include <pthread.h>
@@ -58,6 +59,15 @@ fileEncodeDevice __fileEncodeDevices[] =
{ projectRenderer::Mp3File,
QT_TRANSLATE_NOOP( "projectRenderer", "MP3 File (*.mp3)" ),
".mp3", &AudioFileMp3::getInst },
{ projectRenderer::FlacFile,
QT_TRANSLATE_NOOP( "projectRenderer", "FLAC File (*.flac)" ),
".flac",
#ifdef LMMS_HAVE_FLAC
&AudioFileFlac::getInst
#else
NULL
#endif
},
// ... insert your own file-encoder-infos here... may be one day the
// user can add own encoders inside the program...
@@ -65,7 +75,7 @@ fileEncodeDevice __fileEncodeDevices[] =
} ;
const char * projectRenderer::EFF_ext[] = {"wav", "ogg", "mp3"};
const char * projectRenderer::EFF_ext[] = {"wav", "ogg", "mp3", "flac"};
projectRenderer::projectRenderer( const mixer::qualitySettings & _qs,