added mpeg2 support thanks to Nicholas J Humfrey
This commit is contained in:
parent
9ba6d64d1f
commit
0c4f4847c4
|
@ -0,0 +1,317 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2005 Tyrell Corporation. All rights reserved.
|
||||
|
||||
Tyrell DarkIce
|
||||
|
||||
File : TwoLameLibEncoder.cpp
|
||||
Version : $Revision$
|
||||
Author : $Author$
|
||||
Location : $Source$
|
||||
|
||||
Copyright notice:
|
||||
|
||||
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; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
// compile the whole file only if TwoLame support configured in
|
||||
#ifdef HAVE_TWOLAME_LIB
|
||||
|
||||
|
||||
|
||||
#include "Exception.h"
|
||||
#include "Util.h"
|
||||
#include "TwoLameLibEncoder.h"
|
||||
|
||||
|
||||
/* =================================================== local data structures */
|
||||
|
||||
|
||||
/* ================================================ local constants & macros */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* File identity
|
||||
*----------------------------------------------------------------------------*/
|
||||
static const char fileid[] = "$Id$";
|
||||
|
||||
|
||||
/* =============================================== local function prototypes */
|
||||
|
||||
|
||||
/* ============================================================= module code */
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Initialize the object
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
TwoLameLibEncoder :: init ( Sink * sink ) throw ( Exception )
|
||||
{
|
||||
this->twolame_opts = NULL;
|
||||
this->sink = sink;
|
||||
|
||||
if ( getInBitsPerSample() != 16 ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"specified bits per sample not supported",
|
||||
getInBitsPerSample() );
|
||||
}
|
||||
|
||||
if ( getInChannel() != 1 && getInChannel() != 2 ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"unsupported number of input channels for the encoder",
|
||||
getInChannel() );
|
||||
}
|
||||
if ( getOutChannel() != 1 && getOutChannel() != 2 ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"unsupported number of output channels for the encoder",
|
||||
getOutChannel() );
|
||||
}
|
||||
if ( getInChannel() < getOutChannel() ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"output channels greater then input channels",
|
||||
getOutChannel() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Open an encoding session
|
||||
*----------------------------------------------------------------------------*/
|
||||
bool
|
||||
TwoLameLibEncoder :: open ( void )
|
||||
throw ( Exception )
|
||||
{
|
||||
if ( isOpen() ) {
|
||||
close();
|
||||
}
|
||||
|
||||
// open the underlying sink
|
||||
if ( !sink->open() ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"TwoLAME lib opening underlying sink error");
|
||||
}
|
||||
|
||||
twolame_opts = ::twolame_init();
|
||||
|
||||
// ugly twolame returns -1 in a pointer on allocation errors
|
||||
if ( !twolame_opts ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"TwoLAME lib init error",
|
||||
(int) twolame_opts);
|
||||
}
|
||||
|
||||
if ( 0 > twolame_set_num_channels( twolame_opts, getInChannel()) ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"TwoLAME lib setting channels error",
|
||||
getInChannel() );
|
||||
}
|
||||
|
||||
if ( 0 > twolame_set_mode( twolame_opts,
|
||||
getOutChannel() == 1 ? TWOLAME_MONO : TWOLAME_JOINT_STEREO) ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"TwoLAME lib setting mode error",
|
||||
TWOLAME_JOINT_STEREO );
|
||||
}
|
||||
|
||||
if ( 0 > twolame_set_in_samplerate( twolame_opts, getInSampleRate()) ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"TwoLAME lib setting input sample rate error",
|
||||
getInSampleRate() );
|
||||
}
|
||||
|
||||
if ( 0 > twolame_set_out_samplerate( twolame_opts, getOutSampleRate()) ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"TwoLAME lib setting output sample rate error",
|
||||
getOutSampleRate() );
|
||||
}
|
||||
|
||||
switch ( getOutBitrateMode() ) {
|
||||
|
||||
case cbr: {
|
||||
|
||||
if ( 0 > twolame_set_brate( twolame_opts, getOutBitrate()) ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"TwoLAME lib setting output bit rate error",
|
||||
getOutBitrate() );
|
||||
}
|
||||
} break;
|
||||
|
||||
default: {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"Unsupported bitrate mode." );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// let TwoLAME init its own params based on our settings
|
||||
if ( 0 > twolame_init_params( twolame_opts) ) {
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"TwoLAME lib initializing params error" );
|
||||
}
|
||||
|
||||
// Information about TwoLame's setup
|
||||
if (getReportVerbosity() >= 3) {
|
||||
twolame_print_config( twolame_opts);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Write data to the encoder
|
||||
*----------------------------------------------------------------------------*/
|
||||
unsigned int
|
||||
TwoLameLibEncoder :: write ( const void * buf,
|
||||
unsigned int len ) throw ( Exception )
|
||||
{
|
||||
if ( !isOpen() || len == 0 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int bitsPerSample = getInBitsPerSample();
|
||||
unsigned int inChannels = getInChannel();
|
||||
|
||||
unsigned int sampleSize = (bitsPerSample / 8) * inChannels;
|
||||
unsigned char * b = (unsigned char*) buf;
|
||||
unsigned int processed = len - (len % sampleSize);
|
||||
unsigned int nSamples = processed / sampleSize;
|
||||
short int * leftBuffer = new short int[nSamples];
|
||||
short int * rightBuffer = new short int[nSamples];
|
||||
|
||||
if ( bitsPerSample == 8 ) {
|
||||
Util::conv8( b, processed, leftBuffer, rightBuffer, inChannels);
|
||||
} else if ( bitsPerSample == 16 ) {
|
||||
Util::conv16( b,
|
||||
processed,
|
||||
leftBuffer,
|
||||
rightBuffer,
|
||||
inChannels,
|
||||
isInBigEndian());
|
||||
} else {
|
||||
delete[] leftBuffer;
|
||||
delete[] rightBuffer;
|
||||
throw Exception( __FILE__, __LINE__,
|
||||
"unsupported number of bits per sample for the encoder",
|
||||
bitsPerSample );
|
||||
}
|
||||
|
||||
// data chunk size estimate according to TwoLAME documentation
|
||||
// NOTE: mp2Size is calculated based on the number of input channels
|
||||
// which may be bigger than need, as output channels can be less
|
||||
unsigned int mp2Size = (unsigned int) (1.25 * nSamples + 7200);
|
||||
unsigned char * mp2Buf = new unsigned char[mp2Size];
|
||||
int ret;
|
||||
|
||||
ret = twolame_encode_buffer( twolame_opts,
|
||||
leftBuffer,
|
||||
inChannels == 2 ? rightBuffer : leftBuffer,
|
||||
nSamples,
|
||||
mp2Buf,
|
||||
mp2Size );
|
||||
|
||||
delete[] leftBuffer;
|
||||
delete[] rightBuffer;
|
||||
|
||||
if ( ret < 0 ) {
|
||||
reportEvent( 3, "TwoLAME encoding error", ret);
|
||||
delete[] mp2Buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int written = sink->write( mp2Buf, ret);
|
||||
delete[] mp2Buf;
|
||||
// just let go data that could not be written
|
||||
if ( written < (unsigned int) ret ) {
|
||||
reportEvent( 2,
|
||||
"couldn't write all from encoder to underlying sink",
|
||||
ret - written);
|
||||
}
|
||||
|
||||
return processed;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Flush the data from the encoder
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
TwoLameLibEncoder :: flush ( void )
|
||||
throw ( Exception )
|
||||
{
|
||||
if ( !isOpen() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// data chunk size estimate according to TwoLAME documentation
|
||||
unsigned int mp2Size = 7200;
|
||||
unsigned char * mp2Buf = new unsigned char[mp2Size];
|
||||
int ret;
|
||||
|
||||
ret = twolame_encode_flush( twolame_opts, mp2Buf, mp2Size );
|
||||
|
||||
unsigned int written = sink->write( mp2Buf, ret);
|
||||
delete[] mp2Buf;
|
||||
|
||||
// just let go data that could not be written
|
||||
if ( written < (unsigned int) ret ) {
|
||||
reportEvent( 2,
|
||||
"couldn't write all from encoder to underlying sink",
|
||||
ret - written);
|
||||
}
|
||||
|
||||
sink->flush();
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Close the encoding session
|
||||
*----------------------------------------------------------------------------*/
|
||||
void
|
||||
TwoLameLibEncoder :: close ( void ) throw ( Exception )
|
||||
{
|
||||
if ( isOpen() ) {
|
||||
flush();
|
||||
twolame_close( &twolame_opts );
|
||||
sink->close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // HAVE_TWOLAME_LIB
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
|
||||
$Source$
|
||||
|
||||
$Log$
|
||||
Revision 1.1 2006/01/25 22:49:59 darkeye
|
||||
added mpeg2 support thanks to Nicholas J Humfrey
|
||||
|
||||
|
||||
Revision 1.1 2005/05/02 23:05:02 nhumfrey
|
||||
initial version - based on LameLibEncoder 1.19
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
|
@ -0,0 +1,385 @@
|
|||
/*------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2005 Tyrell Corporation. All rights reserved.
|
||||
|
||||
Tyrell DarkIce
|
||||
|
||||
File : TwoLameLibEncoder.cpp
|
||||
Version : $Revision$
|
||||
Author : $Author$
|
||||
Location : $Source$
|
||||
|
||||
Copyright notice:
|
||||
|
||||
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; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef TWOLAME_LIB_ENCODER_H
|
||||
#define TWOLAME_LIB_ENCODER_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error This is a C++ include file
|
||||
#endif
|
||||
|
||||
|
||||
/* ============================================================ include files */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TWOLAME_LIB
|
||||
#include <twolame.h>
|
||||
#else
|
||||
#error configure with twolame
|
||||
#endif
|
||||
|
||||
|
||||
#include "Ref.h"
|
||||
#include "Exception.h"
|
||||
#include "Reporter.h"
|
||||
#include "AudioEncoder.h"
|
||||
#include "Sink.h"
|
||||
|
||||
|
||||
/* ================================================================ constants */
|
||||
|
||||
|
||||
/* =================================================================== macros */
|
||||
|
||||
|
||||
/* =============================================================== data types */
|
||||
|
||||
/**
|
||||
* A class representing the TwoLame encoder linked as a shared object or as
|
||||
* a static library.
|
||||
*
|
||||
* @author $Author$
|
||||
* @version $Revision$
|
||||
*/
|
||||
class TwoLameLibEncoder : public AudioEncoder, public virtual Reporter
|
||||
{
|
||||
private:
|
||||
|
||||
/**
|
||||
* TwoLame library global flags
|
||||
*/
|
||||
twolame_options * twolame_opts;
|
||||
|
||||
/**
|
||||
* The Sink to dump mp2 data to
|
||||
*/
|
||||
Ref<Sink> sink;
|
||||
|
||||
/**
|
||||
* Initialize the object.
|
||||
*
|
||||
* @param sink the sink to send mp2 output to
|
||||
* @exception Exception
|
||||
*/
|
||||
void
|
||||
init ( Sink * sink ) throw ( Exception );
|
||||
|
||||
/**
|
||||
* De-initialize the object.
|
||||
*
|
||||
* @exception Exception
|
||||
*/
|
||||
inline void
|
||||
strip ( void ) throw ( Exception )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Default constructor. Always throws an Exception.
|
||||
*
|
||||
* @exception Exception
|
||||
*/
|
||||
inline
|
||||
TwoLameLibEncoder ( void ) throw ( Exception )
|
||||
{
|
||||
throw Exception( __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param sink the sink to send mp2 output to
|
||||
* @param inSampleRate sample rate of the input.
|
||||
* @param inBitsPerSample number of bits per sample of the input.
|
||||
* @param inChannel number of channels of the input.
|
||||
* @param inBigEndian shows if the input is big or little endian
|
||||
* @param outBitrateMode the bit rate mode of the output.
|
||||
* @param outBitrate bit rate of the output (kbits/sec).
|
||||
* @param outSampleRate sample rate of the output.
|
||||
* If 0, inSampleRate is used.
|
||||
* @param outChannel number of channels of the output.
|
||||
* If 0, inChannel is used.
|
||||
* @exception Exception
|
||||
*/
|
||||
inline
|
||||
TwoLameLibEncoder ( Sink * sink,
|
||||
unsigned int inSampleRate,
|
||||
unsigned int inBitsPerSample,
|
||||
unsigned int inChannel,
|
||||
bool inBigEndian,
|
||||
BitrateMode outBitrateMode,
|
||||
unsigned int outBitrate,
|
||||
unsigned int outSampleRate = 0,
|
||||
unsigned int outChannel = 0 )
|
||||
throw ( Exception )
|
||||
|
||||
: AudioEncoder ( inSampleRate,
|
||||
inBitsPerSample,
|
||||
inChannel,
|
||||
inBigEndian,
|
||||
outBitrateMode,
|
||||
outBitrate,
|
||||
0.0f, // outQuality
|
||||
outSampleRate,
|
||||
outChannel )
|
||||
{
|
||||
init( sink );
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param sink the sink to send mp2 output to
|
||||
* @param as get input sample rate, bits per sample and channels
|
||||
* from this AudioSource.
|
||||
* @param outBitrateMode the bit rate mode of the output.
|
||||
* @param outBitrate bit rate of the output (kbits/sec).
|
||||
* @param outSampleRate sample rate of the output.
|
||||
* If 0, input sample rate is used.
|
||||
* @param outChannel number of channels of the output.
|
||||
* If 0, input channel is used.
|
||||
* @exception Exception
|
||||
*/
|
||||
inline
|
||||
TwoLameLibEncoder ( Sink * sink,
|
||||
const AudioSource * as,
|
||||
BitrateMode outBitrateMode,
|
||||
unsigned int outBitrate,
|
||||
unsigned int outSampleRate = 0,
|
||||
unsigned int outChannel = 0 )
|
||||
throw ( Exception )
|
||||
|
||||
: AudioEncoder ( as,
|
||||
outBitrateMode,
|
||||
outBitrate,
|
||||
0.0f, // outQuality
|
||||
outSampleRate,
|
||||
outChannel )
|
||||
{
|
||||
init( sink );
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*
|
||||
* @param encoder the TwoLameLibEncoder to copy.
|
||||
*/
|
||||
inline
|
||||
TwoLameLibEncoder ( const TwoLameLibEncoder & encoder )
|
||||
throw ( Exception )
|
||||
: AudioEncoder( encoder )
|
||||
{
|
||||
init( encoder.sink.get() );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*
|
||||
* @exception Exception
|
||||
*/
|
||||
inline virtual
|
||||
~TwoLameLibEncoder ( void ) throw ( Exception )
|
||||
{
|
||||
if ( isOpen() ) {
|
||||
close();
|
||||
}
|
||||
strip();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assignment operator.
|
||||
*
|
||||
* @param encoder the TwoLameLibEncoder to assign this to.
|
||||
* @return a reference to this TwoLameLibEncoder.
|
||||
* @exception Exception
|
||||
*/
|
||||
inline virtual TwoLameLibEncoder &
|
||||
operator= ( const TwoLameLibEncoder & encoder ) throw ( Exception )
|
||||
{
|
||||
if ( this != &encoder ) {
|
||||
strip();
|
||||
AudioEncoder::operator=( encoder);
|
||||
init( encoder.sink.get() );
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version string of the underlying lame library.
|
||||
*
|
||||
* @return the version string of the underlying lame library.
|
||||
*/
|
||||
inline const char *
|
||||
getLameVersion( void )
|
||||
{
|
||||
return get_twolame_version();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check wether encoding is in progress.
|
||||
*
|
||||
* @return true if encoding is in progress, false otherwise.
|
||||
*/
|
||||
inline virtual bool
|
||||
isRunning ( void ) const throw ()
|
||||
{
|
||||
return isOpen();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start encoding. This function returns as soon as possible,
|
||||
* with encoding started in the background.
|
||||
*
|
||||
* @return true if encoding has started, false otherwise.
|
||||
* @exception Exception
|
||||
*/
|
||||
inline virtual bool
|
||||
start ( void ) throw ( Exception )
|
||||
{
|
||||
return open();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop encoding. Stops the encoding running in the background.
|
||||
*
|
||||
* @exception Exception
|
||||
*/
|
||||
inline virtual void
|
||||
stop ( void ) throw ( Exception )
|
||||
{
|
||||
return close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Open an encoding session.
|
||||
*
|
||||
* @return true if opening was successfull, false otherwise.
|
||||
* @exception Exception
|
||||
*/
|
||||
virtual bool
|
||||
open ( void ) throw ( Exception );
|
||||
|
||||
/**
|
||||
* Check if the encoding session is open.
|
||||
*
|
||||
* @return true if the encoding session is open, false otherwise.
|
||||
*/
|
||||
inline virtual bool
|
||||
isOpen ( void ) const throw ()
|
||||
{
|
||||
return twolame_opts != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the encoder is ready to accept data.
|
||||
*
|
||||
* @param sec the maximum seconds to block.
|
||||
* @param usec micro seconds to block after the full seconds.
|
||||
* @return true if the encoder is ready to accept data,
|
||||
* false otherwise.
|
||||
* @exception Exception
|
||||
*/
|
||||
inline virtual bool
|
||||
canWrite ( unsigned int sec,
|
||||
unsigned int usec ) throw ( Exception )
|
||||
{
|
||||
if ( !isOpen() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data to the encoder.
|
||||
* Buf is expected to be a sequence of big-endian 16 bit values,
|
||||
* with left and right channels interleaved. Len is the number of
|
||||
* bytes, must be a multiple of 4.
|
||||
*
|
||||
* @param buf the data to write.
|
||||
* @param len number of bytes to write from buf.
|
||||
* @return the number of bytes written (may be less than len).
|
||||
* @exception Exception
|
||||
*/
|
||||
virtual unsigned int
|
||||
write ( const void * buf,
|
||||
unsigned int len ) throw ( Exception );
|
||||
|
||||
/**
|
||||
* Flush all data that was written to the encoder to the underlying
|
||||
* connection.
|
||||
*
|
||||
* @exception Exception
|
||||
*/
|
||||
virtual void
|
||||
flush ( void ) throw ( Exception );
|
||||
|
||||
/**
|
||||
* Close the encoding session.
|
||||
*
|
||||
* @exception Exception
|
||||
*/
|
||||
virtual void
|
||||
close ( void ) throw ( Exception );
|
||||
};
|
||||
|
||||
|
||||
/* ================================================= external data structures */
|
||||
|
||||
|
||||
/* ====================================================== function prototypes */
|
||||
|
||||
|
||||
#endif /* TWOLAME_LIB_ENCODER_H */
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
|
||||
$Source$
|
||||
|
||||
$Log$
|
||||
Revision 1.1 2006/01/25 22:49:59 darkeye
|
||||
added mpeg2 support thanks to Nicholas J Humfrey
|
||||
|
||||
|
||||
Revision 1.1 2005/05/02 23:05:02 nhumfrey
|
||||
initial version - based on LameLibEncoder 1.19
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
Loading…
Reference in New Issue