From 99f6ff8ad7fc29b1f5c9f3cbc0f6e372b0aa68c6 Mon Sep 17 00:00:00 2001 From: "rafael@riseup.net" Date: Tue, 12 Oct 2010 22:42:25 +0000 Subject: [PATCH] make darkice compatile with the libaacplus 2.0.0 api --- darkice/trunk/configure.in | 2 +- darkice/trunk/src/aacPlusEncoder.cpp | 229 ++++++++------------------- darkice/trunk/src/aacPlusEncoder.h | 91 +++-------- 3 files changed, 92 insertions(+), 230 deletions(-) diff --git a/darkice/trunk/configure.in b/darkice/trunk/configure.in index e1fd50d..4148127 100644 --- a/darkice/trunk/configure.in +++ b/darkice/trunk/configure.in @@ -166,7 +166,7 @@ AC_ARG_WITH(aacplus-prefix, 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, + LA_SEARCH_LIB( AACPLUS_LIB_LOC, AACPLUS_INC_LOC, libaacplus.a libaacplus.so, aacplus.h, ${CONFIG_AACPLUS_PREFIX}) if test "x${AACPLUS_LIB_LOC}" != "x" ; then AC_DEFINE( HAVE_AACPLUS_LIB, 1, [build with aacplus library] ) diff --git a/darkice/trunk/src/aacPlusEncoder.cpp b/darkice/trunk/src/aacPlusEncoder.cpp index 0a3f8e8..c0eb45f 100644 --- a/darkice/trunk/src/aacPlusEncoder.cpp +++ b/darkice/trunk/src/aacPlusEncoder.cpp @@ -76,82 +76,27 @@ aacPlusEncoder :: open ( void ) "aacplus lib opening underlying sink error"); } - reportEvent(1, "Using aacplus codec version", "720 3gpp"); + reportEvent(1, "Using aacplus codec"); - bitrate = getOutBitrate() * 1000; - bandwidth = 0; - useParametricStereo = 0; - numAncDataBytes=0; - coreWriteOffset = 0; - envReadOffset = 0; - writeOffset = INPUT_DELAY*MAX_CHANNELS; - writtenSamples = 0; - aacEnc = NULL; - hEnvEnc=NULL; + encoderHandle = aacplusEncOpen(getOutSampleRate(), + getInChannel(), + &inputSamples, + &maxOutputBytes); - /* 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; + aacplusEncConfiguration * aacplusConfig; + + aacplusConfig = aacplusEncGetCurrentConfiguration(encoderHandle); + + aacplusConfig->bitRate = getOutBitrate() * 1000; + aacplusConfig->bandWidth = lowpass; + aacplusConfig->outputFormat = 1; + aacplusConfig->inputFormat = AACPLUS_INPUT_16BIT; + aacplusConfig->nChannelsOut = getOutChannel(); + + if (!aacplusEncSetConfiguration(encoderHandle, aacplusConfig)) { + throw Exception(__FILE__, __LINE__, + "error configuring libaacplus library"); } - - sampleRateAAC = getOutSampleRate(); - 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 (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; - // initialize the resampling coverter if needed if ( converter ) { @@ -159,8 +104,8 @@ aacPlusEncoder :: open ( void ) converterData.input_frames = 4096/((getInBitsPerSample() / 8) * getInChannel()); converterData.data_in = new float[converterData.input_frames*getInChannel()]; converterData.output_frames = (int) (converterData.input_frames * resampleRatio + 1); - if ((int) inSamples > getInChannel() * converterData.output_frames) { - resampledOffset = new float[2 * inSamples]; + if ((int) inputSamples > getInChannel() * converterData.output_frames) { + resampledOffset = new float[2 * inputSamples]; } else { resampledOffset = new float[2 * getInChannel() * converterData.input_frames]; } @@ -178,13 +123,9 @@ aacPlusEncoder :: open ( void ) } aacplusOpen = true; - reportEvent(10, "bitrate=", bitrate); - reportEvent(10, "nChannelsIn", getInChannel()); - reportEvent(10, "nChannelsOut", getOutChannel()); - reportEvent(10, "nChannelsSBR", nChannelsSBR); - reportEvent(10, "nChannelsAAC", nChannelsAAC); - reportEvent(10, "sampleRateAAC", sampleRateAAC); - reportEvent(10, "inSamples", inSamples); + reportEvent(10, "nChannelsAAC", aacplusConfig->nChannelsOut); + reportEvent(10, "sampleRateAAC", aacplusConfig->sampleRate); + reportEvent(10, "inSamples", inputSamples); return true; } @@ -199,21 +140,23 @@ aacPlusEncoder :: write ( const void * buf, if ( !isOpen() || len == 0) { return 0; } - + unsigned int channels = getInChannel(); unsigned int bitsPerSample = getInBitsPerSample(); unsigned int sampleSize = (bitsPerSample / 8) * channels; + unsigned char * b = (unsigned char*) buf; unsigned int processed = len - (len % sampleSize); unsigned int nSamples = processed / sampleSize; - unsigned int samples = (unsigned int) nSamples * channels; - int processedSamples = 0; - - + unsigned char * aacplusBuf = new unsigned char[maxOutputBytes]; + int samples = (int) nSamples * channels; + int processedSamples = 0; + + if ( converter ) { unsigned int converted; #ifdef HAVE_SRC_LIB - src_short_to_float_array ((short *) buf, converterData.data_in, samples); + src_short_to_float_array ((short *) b, converterData.data_in, samples); converterData.input_frames = nSamples; converterData.data_out = resampledOffset + (resampledOffsetSize * channels); int srcError = src_process (converter, &converterData); @@ -224,7 +167,6 @@ aacPlusEncoder :: write ( const void * buf, int inCount = nSamples; short int * shortBuffer = new short int[samples]; int outCount = (int) (inCount * resampleRatio); - unsigned char * b = (unsigned char*) buf; Util::conv( bitsPerSample, b, processed, shortBuffer, isInBigEndian()); converted = converter->resample( inCount, outCount+1, @@ -235,18 +177,27 @@ aacPlusEncoder :: write ( const void * buf, resampledOffsetSize += converted; // encode samples (if enough) - while(resampledOffsetSize - processedSamples >= inSamples/channels) { + while(resampledOffsetSize - processedSamples >= inputSamples/channels) { + int outputBytes; #ifdef HAVE_SRC_LIB - short *shortData = new short[inSamples]; + short *shortData = new short[inputSamples]; src_float_to_short_array(resampledOffset + (processedSamples * channels), - shortData, inSamples) ; - - encodeAacSamples (shortData, inSamples, channels); + shortData, inputSamples) ; + outputBytes = aacplusEncEncode(encoderHandle, + (int32_t*) shortData, + inputSamples, + aacplusBuf, + maxOutputBytes); delete [] shortData; #else - encodeAacSamples (&resampledOffset[processedSamples*channels], inSamples, channels); + outputBytes = aacplusEncEncode(encoderHandle, + (int32_t*) &resampledOffset[processedSamples*channels], + inputSamples, + aacplusBuf, + maxOutputBytes); #endif - processedSamples+=inSamples/channels; + getSink()->write(aacplusBuf, outputBytes); + processedSamples+=inputSamples/channels; } if (processedSamples && (int) resampledOffsetSize >= processedSamples) { @@ -262,72 +213,29 @@ aacPlusEncoder :: write ( const void * buf, #endif } } else { - encodeAacSamples ((short *) buf, samples, channels); + while (processedSamples < samples) { + int outputBytes; + int inSamples = samples - processedSamples < (int) inputSamples + ? samples - processedSamples + : inputSamples; + + outputBytes = aacplusEncEncode(encoderHandle, + (int32_t*) (b + processedSamples/sampleSize), + inSamples, + aacplusBuf, + maxOutputBytes); + getSink()->write(aacplusBuf, outputBytes); + + processedSamples += inSamples; + } } + delete[] aacplusBuf; + +// return processedSamples; return samples; } -void -aacPlusEncoder :: encodeAacSamples (short *TimeDataPcm, unsigned int samples, int channels) - throw ( Exception ) -{ - unsigned int i; - int ch, outSamples, numOutBytes; - - for (i=0; iwrite(outBuf, numOutBytes+ADTS_HEADER_SIZE); - } - - writtenSamples=0; - - return; -} - /*------------------------------------------------------------------------------ * Flush the data from the encoder *----------------------------------------------------------------------------*/ @@ -352,12 +260,7 @@ aacPlusEncoder :: close ( void ) throw ( Exception ) if ( isOpen() ) { flush(); - destroy_plans(); - AacEncClose(aacEnc); - if (hEnvEnc) { - EnvClose(hEnvEnc); - } - + aacplusEncClose(encoderHandle); aacplusOpen = false; sink->close(); diff --git a/darkice/trunk/src/aacPlusEncoder.h b/darkice/trunk/src/aacPlusEncoder.h index 3443387..5aa9078 100644 --- a/darkice/trunk/src/aacPlusEncoder.h +++ b/darkice/trunk/src/aacPlusEncoder.h @@ -41,18 +41,7 @@ #endif #ifdef HAVE_AACPLUS_LIB -extern "C" { -#include -#include -#include -#include - -#include - -#include -#include -#include -} +#include #else #error configure with aacplus #endif @@ -87,12 +76,6 @@ extern "C" { * @version $Revision$ */ -#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: @@ -124,31 +107,26 @@ class aacPlusEncoder : public AudioEncoder, public virtual Reporter */ 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]; + /** + * The handle to the AAC+ encoder instance. + */ + aacplusEncHandle encoderHandle; - AACENC_CONFIG config; - - int nChannelsAAC, nChannelsSBR; - unsigned int sampleRateAAC; + /** + * The maximum number of input samples to supply to the encoder. + */ + unsigned long inputSamples; - int bitrate; - int bandwidth; - - unsigned int numAncDataBytes; - unsigned char ancDataBytes[MAX_PAYLOAD_SIZE]; - - bool useParametricStereo; - int coreWriteOffset; - int envReadOffset; - int writeOffset; - struct AAC_ENCODER *aacEnc; - unsigned int inSamples; - unsigned int writtenSamples; - - HANDLE_SBR_ENCODER hEnvEnc; - sbrConfiguration sbrConfig; + /** + * The maximum number of output bytes the encoder returns in one call. + */ + unsigned long maxOutputBytes; + + /** + * Lowpass filter. Sound frequency in Hz, from where up the + * input is cut. + */ + int lowpass; /** * Initialize the object. @@ -157,10 +135,11 @@ class aacPlusEncoder : public AudioEncoder, public virtual Reporter * @exception Exception */ inline void - init ( Sink * sink) throw (Exception) + init ( Sink * sink, int lowpass) throw (Exception) { this->aacplusOpen = false; this->sink = sink; + this->lowpass = lowpass; /* TODO: if we have float as input, we don't need conversion */ if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 32 ) { @@ -179,11 +158,6 @@ class aacPlusEncoder : public AudioEncoder, public virtual Reporter "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"); - } if ( getOutSampleRate() == getInSampleRate() ) { resampleRatio = 1; @@ -237,17 +211,6 @@ class aacPlusEncoder : public AudioEncoder, public virtual Reporter "specified bits per sample with samplerate conversion not supported", getInBitsPerSample() ); } - - bitrate = getOutBitrate() * 1000; - bandwidth = 0; - useParametricStereo = 0; - numAncDataBytes=0; - coreWriteOffset = 0; - envReadOffset = 0; - writeOffset = INPUT_DELAY*MAX_CHANNELS; - writtenSamples = 0; - aacEnc = NULL; - hEnvEnc=NULL; } /** @@ -269,10 +232,6 @@ class aacPlusEncoder : public AudioEncoder, public virtual Reporter } } - void - encodeAacSamples (short *TimeDataPcm, unsigned int samples, int channels) - throw ( Exception ); - protected: /** @@ -335,7 +294,7 @@ class aacPlusEncoder : public AudioEncoder, public virtual Reporter outSampleRate, outChannel ) { - init( sink); + init( sink, lowpass); } /** @@ -376,7 +335,7 @@ class aacPlusEncoder : public AudioEncoder, public virtual Reporter outSampleRate, outChannel ) { - init( sink); + init( sink, lowpass ); } /** @@ -389,7 +348,7 @@ class aacPlusEncoder : public AudioEncoder, public virtual Reporter throw ( Exception ) : AudioEncoder( encoder ) { - init( encoder.sink.get()); + init( encoder.sink.get(), encoder.lowpass); } @@ -420,7 +379,7 @@ class aacPlusEncoder : public AudioEncoder, public virtual Reporter if ( this != &encoder ) { strip(); AudioEncoder::operator=( encoder); - init( encoder.sink.get()); + init( encoder.sink.get(), encoder.lowpass); } return *this;