From 2a98f1f03b68c4c4e7dda76a4b51bf99910e385e Mon Sep 17 00:00:00 2001 From: tipok Date: Wed, 5 Nov 2008 12:15:05 +0000 Subject: [PATCH] added aac+ encoding support, re #2 --- darkice/branches/darkice-aacp/configure.in | 39 +- darkice/branches/darkice-aacp/src/DarkIce.cpp | 49 +- .../branches/darkice-aacp/src/IceCast2.cpp | 4 + darkice/branches/darkice-aacp/src/IceCast2.h | 2 +- darkice/branches/darkice-aacp/src/Makefile.am | 6 +- .../darkice-aacp/src/aacPlusEncoder.cpp | 309 ++++++++++++ .../darkice-aacp/src/aacPlusEncoder.h | 477 ++++++++++++++++++ 7 files changed, 881 insertions(+), 5 deletions(-) create mode 100644 darkice/branches/darkice-aacp/src/aacPlusEncoder.cpp create mode 100644 darkice/branches/darkice-aacp/src/aacPlusEncoder.h diff --git a/darkice/branches/darkice-aacp/configure.in b/darkice/branches/darkice-aacp/configure.in index 0d4b138..25d98ec 100644 --- a/darkice/branches/darkice-aacp/configure.in +++ b/darkice/branches/darkice-aacp/configure.in @@ -149,6 +149,42 @@ else fi +dnl----------------------------------------------------------------------------- +dnl link the aacplus library if requested +dnl----------------------------------------------------------------------------- +AC_SUBST(AACPLUS_INCFLAGS) +AC_SUBST(AACPLUS_LDFLAGS) + +AC_ARG_WITH(aacplus, +[ --with-aacplus use aacplus for encoding AAC HEv2 streams [yes] ], + USE_AACPLUS=${withval}, USE_AACPLUS="yes" ) +AC_ARG_WITH(aacplus-prefix, +[ --with-aacplus-prefix=DIR alternate location for aacplus [/usr] + look for libraries in AACPLUS-PREFIX/lib, + for headers in AACPLUS-PREFIX/include], + CONFIG_AACPLUS_PREFIX="${withval}", CONFIG_AACPLUS_PREFIX="/usr") + +if test "x${USE_AACPLUS}" = "xyes" ; then + AC_MSG_CHECKING( [for aacplus library at ${CONFIG_AACPLUS_PREFIX}] ) + LA_SEARCH_LIB( AACPLUS_LIB_LOC, AACPLUS_INC_LOC, libaacplus.a libaacplus.so, sbr_main.h, + ${CONFIG_AACPLUS_PREFIX}) + if test "x${AACPLUS_LIB_LOC}" != "x" ; then + AC_DEFINE( HAVE_AACPLUS_LIB, 1, [build with aacplus library] ) + if test "x${AACPLUS_INC_LOC}" != "x${SYSTEM_INCLUDE}" ; then + AACPLUS_INCFLAGS="-I${AACPLUS_INC_LOC}" + fi + AACPLUS_LDFLAGS="-L${AACPLUS_LIB_LOC} -laacplus" + # TODO: we have to define _FFTW3 only if libaacplus builded with fftw3f + AC_DEFINE( _FFTW3, 1, [libaacplus have to be builded with fftw3f library] ) + AC_MSG_RESULT( [found at ${CONFIG_AACPLUS_PREFIX}] ) + else + AC_MSG_WARN( [not found, building without aacplus]) + fi +else + AC_MSG_RESULT( [building without aacplus] ) +fi + + dnl----------------------------------------------------------------------------- dnl link the twolame library if requested dnl----------------------------------------------------------------------------- @@ -189,8 +225,9 @@ dnl----------------------------------------------------------------------------- if test "x${LAME_LDFLAGS}" = "x" \ -a "x${VORBIS_LDFLAGS}" = "x" \ -a "x${FAAC_LDFLAGS}" = "x" \ + -a "x${AACPLUS_LDFLAGS}" = "x" \ -a "x${TWOLAME_LDFLAGS}" = "x"; then - AC_MSG_ERROR([neither lame, Ogg Vorbis, faac nor twolame configured]) + AC_MSG_ERROR([neither lame, Ogg Vorbis, faac, aac+ nor twolame configured]) fi diff --git a/darkice/branches/darkice-aacp/src/DarkIce.cpp b/darkice/branches/darkice-aacp/src/DarkIce.cpp index 28796bb..e1c3095 100644 --- a/darkice/branches/darkice-aacp/src/DarkIce.cpp +++ b/darkice/branches/darkice-aacp/src/DarkIce.cpp @@ -96,6 +96,10 @@ #include "FaacEncoder.h" #endif +#ifdef HAVE_AACPLUS_LIB +#include "aacPlusEncoder.h" +#endif + /* =================================================== local data structures */ @@ -454,6 +458,8 @@ DarkIce :: configIceCast2 ( const Config & config, format = IceCast2::mp2; } else if ( Util::strEq( str, "aac") ) { format = IceCast2::aac; + } else if ( Util::strEq( str, "aacp") ) { + format = IceCast2::aacp; } else { throw Exception( __FILE__, __LINE__, "unsupported stream format: ", str); @@ -643,6 +649,24 @@ DarkIce :: configIceCast2 ( const Config & config, #endif // HAVE_FAAC_LIB break; + case IceCast2::aacp: +#ifndef HAVE_AACPLUS_LIB + throw Exception( __FILE__, __LINE__, + "DarkIce not compiled with AAC+ support, " + "thus can't aacp stream: ", + stream); +#else + audioOuts[u].encoder = new aacPlusEncoder( + audioOuts[u].server.get(), + dsp.get(), + bitrateMode, + bitrate, + quality, + sampleRate, + dsp->getChannel()); +#endif // HAVE_AACPLUS_LIB + break; + default: throw Exception( __FILE__, __LINE__, "Illegal stream format: ", format); @@ -878,7 +902,8 @@ DarkIce :: configFileCast ( const Config & config ) if ( !Util::strEq( format, "vorbis") && !Util::strEq( format, "mp3") && !Util::strEq( format, "mp2") - && !Util::strEq( format, "aac") ) { + && !Util::strEq( format, "aac") + && !Util::strEq( format, "aacp") ) { throw Exception( __FILE__, __LINE__, "unsupported stream format: ", format); } @@ -936,6 +961,12 @@ DarkIce :: configFileCast ( const Config & config ) "average bitrate mode"); } + if (Util::strEq(format, "aacp") && bitrateMode != AudioEncoder::cbr) { + throw Exception(__FILE__, __LINE__, + "currently the AAC+ format only supports " + "constant bitrate mode"); + } + str = cs->get( "lowpass"); lowpass = str ? Util::strToL( str) : 0; str = cs->get( "highpass"); @@ -1031,6 +1062,22 @@ DarkIce :: configFileCast ( const Config & config ) sampleRate, dsp->getChannel()); #endif // HAVE_FAAC_LIB + } else if ( Util::strEq( format, "aacp") ) { +#ifndef HAVE_AACPLUS_LIB + throw Exception( __FILE__, __LINE__, + "DarkIce not compiled with AAC+ support, " + "thus can't aacplus stream: ", + stream); +#else + audioOuts[u].encoder = new aacPlusEncoder( + audioOuts[u].server.get(), + dsp.get(), + bitrateMode, + bitrate, + quality, + sampleRate, + dsp->getChannel()); +#endif // HAVE_AACPLUS_LIB } else { throw Exception( __FILE__, __LINE__, "Illegal stream format: ", format); diff --git a/darkice/branches/darkice-aacp/src/IceCast2.cpp b/darkice/branches/darkice-aacp/src/IceCast2.cpp index 917e50e..b1469fb 100644 --- a/darkice/branches/darkice-aacp/src/IceCast2.cpp +++ b/darkice/branches/darkice-aacp/src/IceCast2.cpp @@ -161,6 +161,10 @@ IceCast2 :: sendLogin ( void ) throw ( Exception ) str = "audio/aac"; break; + case aacp: + str = "audio/aacp"; + break; + default: throw Exception( __FILE__, __LINE__, "unsupported stream format", format); diff --git a/darkice/branches/darkice-aacp/src/IceCast2.h b/darkice/branches/darkice-aacp/src/IceCast2.h index a1d54a8..483e749 100644 --- a/darkice/branches/darkice-aacp/src/IceCast2.h +++ b/darkice/branches/darkice-aacp/src/IceCast2.h @@ -63,7 +63,7 @@ class IceCast2 : public CastSink /** * Type for specifying the format of the stream. */ - enum StreamFormat { mp3, mp2, oggVorbis, aac }; + enum StreamFormat { mp3, mp2, oggVorbis, aac, aacp }; private: diff --git a/darkice/branches/darkice-aacp/src/Makefile.am b/darkice/branches/darkice-aacp/src/Makefile.am index 502f2f7..b718b54 100644 --- a/darkice/branches/darkice-aacp/src/Makefile.am +++ b/darkice/branches/darkice-aacp/src/Makefile.am @@ -1,8 +1,8 @@ bin_PROGRAMS = darkice AM_CXXFLAGS = -O2 -pedantic -Wall @DEBUG_CXXFLAGS@ @PTHREAD_CFLAGS@ @JACK_CFLAGS@ -INCLUDES = @LAME_INCFLAGS@ @VORBIS_INCFLAGS@ @FAAC_INCFLAGS@ @TWOLAME_INCFLAGS@ @ALSA_INCFLAGS@ -LDADD = @PTHREAD_LIBS@ @LAME_LDFLAGS@ @VORBIS_LDFLAGS@ @FAAC_LDFLAGS@ @TWOLAME_LDFLAGS@ \ +INCLUDES = @LAME_INCFLAGS@ @VORBIS_INCFLAGS@ @FAAC_INCFLAGS@ @AACPLUS_INCFLAGS@ @TWOLAME_INCFLAGS@ @ALSA_INCFLAGS@ +LDADD = @PTHREAD_LIBS@ @LAME_LDFLAGS@ @VORBIS_LDFLAGS@ @FAAC_LDFLAGS@ @AACPLUS_LDFLAGS@ @TWOLAME_LDFLAGS@ \ @ALSA_LDFLAGS@ @JACK_LDFLAGS@ darkice_SOURCES = AudioEncoder.h\ @@ -38,6 +38,8 @@ darkice_SOURCES = AudioEncoder.h\ VorbisLibEncoder.h\ FaacEncoder.cpp\ FaacEncoder.h\ + aacPlusEncoder.cpp\ + aacPlusEncoder.h\ aflibDebug.h\ aflibDebug.cc\ aflibConverter.h\ diff --git a/darkice/branches/darkice-aacp/src/aacPlusEncoder.cpp b/darkice/branches/darkice-aacp/src/aacPlusEncoder.cpp new file mode 100644 index 0000000..f9dbcd5 --- /dev/null +++ b/darkice/branches/darkice-aacp/src/aacPlusEncoder.cpp @@ -0,0 +1,309 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2005 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : aacPlusEncoder.cpp + Version : $Revision: 0.2 $ + Author : $Author: tipok $ + Location : $Source: /darkice-aacplus/src/aacPlusEncoder.cpp,v $ + + 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 aacplus support configured in +#ifdef HAVE_AACPLUS_LIB + + + +#include "Exception.h" +#include "Util.h" +#include "aacPlusEncoder.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id: aacPlusEncoder.cpp,v 0.2 2005/04/16 22:19:20 klaus Exp $"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Open an encoding session + *----------------------------------------------------------------------------*/ +bool +aacPlusEncoder :: open ( void ) + throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + // open the underlying sink + if ( !sink->open() ) { + throw Exception( __FILE__, __LINE__, + "aacplus lib opening underlying sink error"); + } + + reportEvent(1, "Using aacplus codec version", "720 3gpp"); + + + /* set up basic parameters for aacPlus codec */ + AacInitDefaultConfig(&config); + nChannelsAAC = nChannelsSBR = getOutChannel(); + + if ( (getInChannel() == 2) && (bitrate >= 16000) && (bitrate < 44001) ) { + useParametricStereo = 1; + nChannelsAAC = 1; + nChannelsSBR = 2; + + reportEvent(10, "use Parametric Stereo"); + + envReadOffset = (MAX_DS_FILTER_DELAY + INPUT_DELAY)*MAX_CHANNELS; + coreWriteOffset = CORE_INPUT_OFFSET_PS; + writeOffset = envReadOffset; + } else { + /* set up 2:1 downsampling */ + InitIIR21_Resampler(&(IIR21_reSampler[0])); + InitIIR21_Resampler(&(IIR21_reSampler[1])); + + if(IIR21_reSampler[0].delay > MAX_DS_FILTER_DELAY){ + throw Exception(__FILE__, __LINE__, "IIR21 resampler delay is bigger then MAX_DS_FILTER_DELAY"); + } + writeOffset += IIR21_reSampler[0].delay*MAX_CHANNELS; + } + + sampleRateAAC = getInSampleRate(); + config.bitRate = bitrate; + config.nChannelsIn=getInChannel(); + config.nChannelsOut=nChannelsAAC; + config.bandWidth=bandwidth; + + /* set up SBR configuration */ + if(!IsSbrSettingAvail (bitrate, nChannelsAAC, sampleRateAAC, &sampleRateAAC)) { + throw Exception(__FILE__, __LINE__, "No valid SBR configuration found"); + } + + InitializeSbrDefaults (&sbrConfig); + sbrConfig.usePs = useParametricStereo; + + AdjustSbrSettings( &sbrConfig, + bitrate, + nChannelsAAC, + sampleRateAAC, + AACENC_TRANS_FAC, + 24000); + + EnvOpen( &hEnvEnc, + inBuf + coreWriteOffset, + &sbrConfig, + &config.bandWidth); + + /* set up AAC encoder, now that samling rate is known */ + config.sampleRate = sampleRateAAC; + if ((error = AacEncOpen(&aacEnc, config)) != 0){ + AacEncClose(aacEnc); + throw Exception(__FILE__, __LINE__, "Initialisation of AAC failed !"); + } + + init_plans(); + + /* create the ADTS header */ + adts_hdr(outBuf, &config); + + inSamples = AACENC_BLOCKSIZE * getInChannel() * 2; + + aacplusOpen = true; + reportEvent(10, "bitrate=", bitrate); + reportEvent(10, "nChannelsIn", getInChannel()); + reportEvent(10, "nChannelsSBR", nChannelsSBR); + reportEvent(10, "nChannelsOut", nChannelsAAC); + reportEvent(10, "sampleRateAAC", sampleRateAAC); + reportEvent(10, "inSamples", inSamples); + return true; +} + + +/*------------------------------------------------------------------------------ + * Write data to the encoder + *----------------------------------------------------------------------------*/ +unsigned int +aacPlusEncoder :: write ( const void * buf, + unsigned int len ) throw ( Exception ) +{ + if ( !isOpen() || len == 0) { + return 0; + } + + unsigned int channels = getInChannel(); + unsigned int bitsPerSample = getInBitsPerSample(); + unsigned int sampleSize = (bitsPerSample / 8) * channels; + unsigned int processed = len - (len % sampleSize); + unsigned int nSamples = processed / sampleSize; + int samples = (int) nSamples * channels; + + + + + int i; + int ch, outSamples, numOutBytes; + + + reportEvent(10, "converting short to float"); + short *TimeDataPcm = (short *) buf; + for (i=0; iwrite(outBuf, numOutBytes+ADTS_HEADER_SIZE); + } + writtenSamples=0; + + return samples; +} + + +/*------------------------------------------------------------------------------ + * Flush the data from the encoder + *----------------------------------------------------------------------------*/ +void +aacPlusEncoder :: flush ( void ) + throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + sink->flush(); +} + + +/*------------------------------------------------------------------------------ + * Close the encoding session + *----------------------------------------------------------------------------*/ +void +aacPlusEncoder :: close ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + flush(); + + destroy_plans(); + AacEncClose(aacEnc); + if (hEnvEnc) { + EnvClose(hEnvEnc); + } + + aacplusOpen = false; + + sink->close(); + } +} + + +#endif // HAVE_AACPLUS_LIB + + +/*------------------------------------------------------------------------------ + + $Source: /cvsroot/darkice/darkice/src/aacPlusEncoder.cpp,v $ + + $Log: aacPlusEncoder.cpp,v $ + Revision 0.1 2005/04/16 21:57:34 klaus + added AAC support through the aacplus codec, http://www.audiocoding.com/ + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/branches/darkice-aacp/src/aacPlusEncoder.h b/darkice/branches/darkice-aacp/src/aacPlusEncoder.h new file mode 100644 index 0000000..487f637 --- /dev/null +++ b/darkice/branches/darkice-aacp/src/aacPlusEncoder.h @@ -0,0 +1,477 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000-2007 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : aacPlusEncoder.h + Version : $Revision: 0.2 $ + Author : $Author: tipok $ + Location : $HeadURL$ + + 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 AACP_ENCODER_H +#define AACP_ENCODER_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_AACPLUS_LIB +extern "C" { +#include +#include +#include +#include + +#include + +#include +#include +#include +} +#else +#error configure with aacplus +#endif + +#include +#include + +#include "Ref.h" +#include "Exception.h" +#include "Reporter.h" +#include "AudioEncoder.h" +#include "Sink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A class representing aacplus AAC+ encoder. + * + * @author $Author: tipok $ + * @version $Revision: 1 $ + */ + +#define CORE_DELAY (1600) +#define INPUT_DELAY ((CORE_DELAY)*2 +6*64-2048+1) /* ((1600 (core codec)*2 (multi rate) + 6*64 (sbr dec delay) - 2048 (sbr enc delay) + magic*/ +#define MAX_DS_FILTER_DELAY 16 /* the additional max resampler filter delay (source fs)*/ + +#define CORE_INPUT_OFFSET_PS (0) /* (96-64) makes AAC still some 64 core samples too early wrt SBR ... maybe -32 would be even more correct, but 1024-32 would need additional SBR bitstream delay by one frame */ + +class aacPlusEncoder : public AudioEncoder, public virtual Reporter +{ + private: + /** + * A flag to indicate if the encoding session is open. + */ + bool aacplusOpen; + + /** + * The Sink to dump aac+ data to + */ + Ref sink; + + float inBuf[(AACENC_BLOCKSIZE*2 + MAX_DS_FILTER_DELAY + INPUT_DELAY)*MAX_CHANNELS]; + char outBuf[(6144/8)*MAX_CHANNELS+ADTS_HEADER_SIZE]; + IIR21_RESAMPLER IIR21_reSampler[MAX_CHANNELS]; + + AACENC_CONFIG config; + + int error; + int nChannelsAAC, nChannelsSBR; + unsigned int sampleRateAAC; + int bitrate; + int bandwidth; + + unsigned int numAncDataBytes; + unsigned char ancDataBytes[MAX_PAYLOAD_SIZE]; + + int numSamplesRead; + int useParametricStereo; + int coreWriteOffset; + int coreReadOffset; + int envReadOffset; + int writeOffset; + struct AAC_ENCODER *aacEnc; + unsigned int inSamples; + unsigned int writtenSamples; + + HANDLE_SBR_ENCODER hEnvEnc; + sbrConfiguration sbrConfig; + + /** + * Initialize the object. + * + * @param sink the sink to send mp3 output to + * @exception Exception + */ + inline void + init ( Sink * sink) throw (Exception) + { + this->aacplusOpen = false; + this->sink = sink; + + /* TODO: if we have float as input, we don't need conversion */ + if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 32 ) { + throw Exception( __FILE__, __LINE__, + "specified bits per sample not supported", + getInBitsPerSample() ); + } + + if ( getInChannel() != 2 ) { + throw Exception( __FILE__, __LINE__, + "unsupported number of input channels for the encoder", + getInChannel() ); + } + if ( getOutChannel() != 2 ) { + throw Exception( __FILE__, __LINE__, + "unsupported number of output channels for the encoder", + getOutChannel() ); + } + /* TODO: this will be neede when we implement mono aac+ encoding */ + if ( getInChannel() != getOutChannel() ) { + throw Exception( __FILE__, __LINE__, + "input channels and output channels do not match"); + } + + bitrate = getOutBitrate() * 1000; + bandwidth = 0; + useParametricStereo = 0; + numAncDataBytes=0; + coreWriteOffset = 0; + coreReadOffset = 0; + envReadOffset = 0; + writeOffset = INPUT_DELAY*MAX_CHANNELS; + writtenSamples = 0; + aacEnc = NULL; + hEnvEnc=NULL; + + } + + /** + * De-initialize the object. + * + * @exception Exception + */ + inline void + strip ( void ) throw ( Exception ) + { + } + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + aacPlusEncoder ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + public: + + /** + * Constructor. + * + * @param sink the sink to send mp3 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 outQuality the quality of the stream. + * @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. + * @param lowpass frequency threshold for the lowpass filter. + * Input above this frequency is cut. + * If 0, aacplus's default values are used, + * which depends on the out sample rate. + * @exception Exception + */ + inline + aacPlusEncoder ( Sink * sink, + unsigned int inSampleRate, + unsigned int inBitsPerSample, + unsigned int inChannel, + bool inBigEndian, + BitrateMode outBitrateMode, + unsigned int outBitrate, + double outQuality, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0, + int lowpass = 0) + throw ( Exception ) + + : AudioEncoder ( sink, + inSampleRate, + inBitsPerSample, + inChannel, + inBigEndian, + outBitrateMode, + outBitrate, + outQuality, + outSampleRate, + outChannel ) + { + init( sink); + } + + /** + * Constructor. + * + * @param sink the sink to send mp3 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 outQuality the quality of the stream. + * @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. + * @param lowpass frequency threshold for the lowpass filter. + * Input above this frequency is cut. + * If 0, aacplus's default values are used, + * which depends on the out sample rate. + * @exception Exception + */ + inline + aacPlusEncoder ( Sink * sink, + const AudioSource * as, + BitrateMode outBitrateMode, + unsigned int outBitrate, + double outQuality, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0, + int lowpass = 0) + throw ( Exception ) + + : AudioEncoder ( sink, + as, + outBitrateMode, + outBitrate, + outQuality, + outSampleRate, + outChannel ) + { + init( sink); + } + + /** + * Copy constructor. + * + * @param encoder the aacPlusEncoder to copy. + */ + inline + aacPlusEncoder ( const aacPlusEncoder & encoder ) + throw ( Exception ) + : AudioEncoder( encoder ) + { + init( encoder.sink.get()); + } + + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~aacPlusEncoder ( void ) throw ( Exception ) + { + if ( isOpen() ) { + close(); + } + strip(); + } + + /** + * Assignment operator. + * + * @param encoder the aacPlusEncoder to assign this to. + * @return a reference to this aacPlusEncoder. + * @exception Exception + */ + inline virtual aacPlusEncoder & + operator= ( const aacPlusEncoder & encoder ) throw ( Exception ) + { + if ( this != &encoder ) { + strip(); + AudioEncoder::operator=( encoder); + init( encoder.sink.get()); + } + + return *this; + } + + /** + * Get the version string of the underlying aacplus library. + * + * @return the version string of the underlying aacplus library. + */ + inline const char * + getAacPlusVersion( void ) + { + char * id; + //char * copyright; + + /* aacplusEncGetVersion(&id, ©right); */ + return id; + } + + /** + * 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 aacplusOpen; + } + + /** + * 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 /* AACP_ENCODER_H */ +