bool HEAACCodec::Init(unsigned long sampleRate, unsigned int numChannels, unsigned long &inputSamples, unsigned long bitRate, unsigned int inputFormat) { Close(); //不支持低音质的参数 if(sampleRate < 44100 || bitRate < 24000 || numChannels < 2) { return false; } if(bitRate > DEFAULT_BITRATE) bitRate = DEFAULT_BITRATE; //默认参数 sample_rate_ = sampleRate; bitrate_ = bitRate; channels_ = numChannels; useParametricStereo = 0; if ((numChannels == 2) && (bitRate > 16000) && (bitRate < 36000)) { useParametricStereo = 1; } unsigned int sample_rate_AAC = sample_rate_; unsigned int channels_AAC = numChannels; unsigned int channels_SBR = numChannels; if (useParametricStereo) { channels_AAC = 1; channels_SBR = 2; } AACENC_CONFIG config; config.sampleRate = sampleRate; config.bitRate = bitRate; config.nChannelsIn = numChannels; config.nChannelsOut = channels_AAC; config.bandWidth = 0; //初始化SBR if(!IsSbrSettingAvail(bitRate, channels_AAC, sample_rate_AAC, &sample_rate_AAC)) { return false; } HANDLE_SBR_ENCODER hEnvEnc = NULL; sbrConfiguration sbrConfig; //ParametricStereo的位置 envReadOffset = 0; coreWriteOffset = 0; if(useParametricStereo) { envReadOffset = (MAX_DS_FILTER_DELAY + INPUT_DELAY)*MAX_CHANNELS; coreWriteOffset = CORE_INPUT_OFFSET_PS; writeOffset = envReadOffset; } //获得SBR初始化参数 InitializeSbrDefaults(&sbrConfig); AdjustSbrSettings(&sbrConfig, bitRate, channels_AAC, sample_rate_AAC, AACENC_TRANS_FAC, 24000); //使用ParametricStereo sbrConfig.usePs = useParametricStereo; EnvOpen(&hEnvEnc, inputBuffer + coreWriteOffset, &sbrConfig, &config.bandWidth); sbr_handler_ = (void *)hEnvEnc; //初始化AAC config.sampleRate = sample_rate_AAC; struct AAC_ENCODER *aacEnc = 0; if(AacEncOpen(&aacEnc, config) != 0) { AacEncClose(aacEnc); EnvClose(hEnvEnc); return false; } aac_handler_ = (void *)aacEnc; //开辟编码器内存 inputBuffer = new float[(AACENC_BLOCKSIZE*2 + MAX_DS_FILTER_DELAY + INPUT_DELAY)*MAX_CHANNELS]; outputBuffer = new unsigned int[(6144/8)*MAX_CHANNELS/(sizeof(int))]; inputSamples = AACENC_BLOCKSIZE * 4; m_outputBuffer = auto_ptr<unsigned char>(new unsigned char [m_maxOutputBytes]); encode_frame_ = false; return true; }
virtual bool Init(unsigned int nSampleRate, unsigned int nChannels, unsigned int nBitrate) { int nChannelsAAC, nChannelsSBR; int useParametricStereo = 0; int bDoIIR32Resample = 0; assert(nChannels == 2); if(nChannels != 2) return false; AacInitDefaultConfig(&m_encConfig); nChannelsAAC = nChannelsSBR = nChannels; if ( (nChannels == 2) && (nBitrate >= 16000) && (nBitrate < 36000)) { useParametricStereo = 1; } if (useParametricStereo) { nChannelsAAC = 1; nChannelsSBR = 2; } if ( (nSampleRate == 48000) && (nChannelsAAC == 2) && (nBitrate < 24000)) { bDoIIR32Resample = 1; } if (nSampleRate == 16000) { assert(0); return false; } unsigned int sampleRateAAC = nSampleRate; if (bDoIIR32Resample) sampleRateAAC = 32000; m_encConfig.bitRate = nBitrate; m_encConfig.nChannelsIn = nChannels; m_encConfig.nChannelsOut = nChannelsAAC; m_encConfig.bandWidth = 0; ///bandwidth; /*set up SBR configuration*/ if(!IsSbrSettingAvail (nBitrate, nChannelsAAC, sampleRateAAC, &sampleRateAAC)) { assert(0); return false; } sbrConfiguration sbrConfig; m_envReadOffset = 0; m_coreWriteOffset = 0; if(useParametricStereo) { m_envReadOffset = (MAX_DS_FILTER_DELAY + INPUT_DELAY)*MAX_CHANNELS; m_coreWriteOffset = CORE_INPUT_OFFSET_PS; m_writeOffset = m_envReadOffset; } InitializeSbrDefaults (&sbrConfig); sbrConfig.usePs = useParametricStereo; AdjustSbrSettings(&sbrConfig, nBitrate, nChannelsAAC, sampleRateAAC, AACENC_TRANS_FAC, 24000); EnvOpen(&m_hEnvEnc, m_inputBuffer + m_coreWriteOffset, &sbrConfig, &m_encConfig.bandWidth); //only support ParametricStereo if(!useParametricStereo) { assert(0); } //aac init m_encConfig.sampleRate = sampleRateAAC; if(AacEncOpen(&m_pAacEnc,m_encConfig)) { assert(0); AacEncClose(m_pAacEnc); return false; } /*set up input samples block size feed*/ m_inSamples_enc = AACENC_BLOCKSIZE * nChannels * 2; return true; }
/*------------------------------------------------------------------------------ * 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"); bitrate = getOutBitrate() * 1000; bandwidth = 0; useParametricStereo = 0; numAncDataBytes=0; coreWriteOffset = 0; envReadOffset = 0; writeOffset = INPUT_DELAY*MAX_CHANNELS; writtenSamples = 0; aacEnc = NULL; hEnvEnc=NULL; /* 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 = 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 ) { #ifdef HAVE_SRC_LIB 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]; } else { resampledOffset = new float[2 * getInChannel() * converterData.input_frames]; } converterData.src_ratio = resampleRatio; converterData.end_of_input = 0; #else converter->initialize( resampleRatio, getInChannel()); //needed 2x(converted input samples) to handle offsets int outCount = 2 * getInChannel() * (inSamples + 1); if (resampleRatio > 1) outCount = (int) (outCount * resampleRatio); resampledOffset = new short int[outCount]; #endif resampledOffsetSize = 0; } 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); return true; }
/*------------------------------------------------------------------------------ * 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"); bitrate = getOutBitrate() * 1000; bandwidth = 0; useParametricStereo = 0; numAncDataBytes=0; coreWriteOffset = 0; envReadOffset = 0; writeOffset = INPUT_DELAY*MAX_CHANNELS; writtenSamples = 0; aacEnc = NULL; hEnvEnc=NULL; /* 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 (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, "nChannelsOut", getOutChannel()); reportEvent(10, "nChannelsSBR", nChannelsSBR); reportEvent(10, "nChannelsAAC", nChannelsAAC); reportEvent(10, "sampleRateAAC", sampleRateAAC); reportEvent(10, "inSamples", inSamples); return true; }
int FloatAACPlusEncodeCodec::init(unsigned int sample_rate, unsigned int bitrate, unsigned int channels) { if(sample_rate < 44100 || bitrate < 24000 || channels < 2) { return -1; } m_iSampleRate = sample_rate; m_iBitRate = bitrate; m_iChannel = channels; useParametricStereo = 0; if ((channels == 2) && (bitrate > 16000) && (bitrate < 36000)) { useParametricStereo = 1; } unsigned int sample_rate_AAC = m_iSampleRate; unsigned int channels_AAC = channels; unsigned int channels_SBR = channels; if (useParametricStereo) { channels_AAC = 1; channels_SBR = 2; } AACENC_CONFIG config; AacInitDefaultConfig(&config); config.sampleRate = sample_rate; config.bitRate = bitrate; config.nChannelsIn = channels; config.nChannelsOut = channels_AAC; config.bandWidth = 0; //初始化SBR if(!IsSbrSettingAvail(bitrate, channels_AAC, sample_rate_AAC, &sample_rate_AAC)) { return -2; } HANDLE_SBR_ENCODER hEnvEnc = NULL; sbrConfiguration sbrConfig; //ParametricStereo的位置 envReadOffset = 0; coreWriteOffset = 0; if(useParametricStereo) { envReadOffset = (MAX_DS_FILTER_DELAY + INPUT_DELAY)*MAX_CHANNELS; coreWriteOffset = CORE_INPUT_OFFSET_PS; writeOffset = envReadOffset; } //获得SBR初始化参数 InitializeSbrDefaults(&sbrConfig); //使用ParametricStereo sbrConfig.usePs = useParametricStereo; AdjustSbrSettings(&sbrConfig, bitrate, channels_AAC, sample_rate_AAC, AACENC_TRANS_FAC, 24000); //开辟编码器内存 inputBuffer = new float[(AACENC_BLOCKSIZE*2 + MAX_DS_FILTER_DELAY + INPUT_DELAY)*MAX_CHANNELS]; outputBuffer = new unsigned int[(6144/8)*MAX_CHANNELS/(sizeof(int))]; EnvOpen(&hEnvEnc, inputBuffer + coreWriteOffset, &sbrConfig, &config.bandWidth); m_hSbr = (void *)hEnvEnc; //初始化AAC config.sampleRate = sample_rate_AAC; struct AAC_ENCODER *aacEnc = 0; if(AacEncOpen(&aacEnc, config) != 0) { AacEncClose(aacEnc); EnvClose(hEnvEnc); return -3; } m_hAac = (void *)aacEnc; return 0; }
/*** * Init the audio codec module and return codec handle * \param phCodec [OUT] Return the video codec handle * \param vType [IN] The codec type if the module support multi codec. * \param pUserData [IN] The init param. It is memory operator or alloced memory * \retval VO_ERR_NONE Succeeded. */ VO_U32 VO_API voAACEncInit(VO_HANDLE * phCodec,VO_AUDIO_CODINGTYPE vType, VO_CODEC_INIT_USERDATA *pUserData) { AAC_ENCODER*hAacEnc; AACENC_CONFIG config; int error; #ifdef USE_DEAULT_MEM VO_MEM_OPERATOR voMemoprator; #endif VO_MEM_OPERATOR *pMemOP; int interMem; interMem = 0; error = 0; /** init the memory operator */ if(pUserData == NULL || pUserData->memflag != VO_IMF_USERMEMOPERATOR || pUserData->memData == NULL ) { #ifdef USE_DEAULT_MEM voMemoprator.Alloc = cmnMemAlloc; voMemoprator.Copy = cmnMemCopy; voMemoprator.Free = cmnMemFree; voMemoprator.Set = cmnMemSet; voMemoprator.Check = cmnMemCheck; interMem = 1; pMemOP = &voMemoprator; #else *phCodec = NULL; return VO_ERR_INVALID_ARG; #endif } else { pMemOP = (VO_MEM_OPERATOR *)pUserData->memData; } /** init the aac encoder handle */ hAacEnc = (AAC_ENCODER*)mem_malloc(pMemOP, sizeof(AAC_ENCODER), 32, VO_INDEX_ENC_AAC); if(NULL == hAacEnc) { error = 1; } if(!error) { /** init the aac encoder intra memory */ hAacEnc->intbuf = (short *)mem_malloc(pMemOP, AACENC_BLOCKSIZE*MAX_CHANNELS*sizeof(short), 32, VO_INDEX_ENC_AAC); if(NULL == hAacEnc->intbuf) { error = 1; } } if (!error) { /** init the aac encoder psychoacoustic */ error = (PsyNew(&hAacEnc->psyKernel, MAX_CHANNELS, pMemOP) || PsyOutNew(&hAacEnc->psyOut, pMemOP)); } if (!error) { /** init the aac encoder quantization elements */ error = QCOutNew(&hAacEnc->qcOut,MAX_CHANNELS, pMemOP); } if (!error) { /** init the aac encoder quantization state */ error = QCNew(&hAacEnc->qcKernel, pMemOP); } /** uninit the aac encoder if error is nozero */ if(error) { AacEncClose(hAacEnc, pMemOP); if(hAacEnc) { mem_free(pMemOP, hAacEnc, VO_INDEX_ENC_AAC); hAacEnc = NULL; } *phCodec = NULL; return VO_ERR_OUTOF_MEMORY; } /** init the aac encoder memory operator */ #ifdef USE_DEAULT_MEM if(interMem) { hAacEnc->voMemoprator.Alloc = cmnMemAlloc; hAacEnc->voMemoprator.Copy = cmnMemCopy; hAacEnc->voMemoprator.Free = cmnMemFree; hAacEnc->voMemoprator.Set = cmnMemSet; hAacEnc->voMemoprator.Check = cmnMemCheck; pMemOP = &hAacEnc->voMemoprator; } #endif /** init the aac encoder default parameter */ if(hAacEnc->initOK == 0) { AACENC_CONFIG config; config.adtsUsed = 1; config.bitRate = 128000; config.nChannelsIn = 2; config.nChannelsOut = 2; config.sampleRate = 44100; config.bandWidth = 20000; AacEncOpen(hAacEnc, config); } hAacEnc->voMemop = pMemOP; *phCodec = hAacEnc; return VO_ERR_NONE; }
/*** * Set the param for special target. * \param hCodec [IN]] The Codec Handle which was created by Init function. * \param uParamID [IN] The param ID. * \param pData [IN] The param value depend on the ID> * \retval VO_ERR_NONE Succeeded. */ VO_U32 VO_API voAACEncSetParam(VO_HANDLE hCodec, VO_S32 uParamID, VO_PTR pData) { AACENC_CONFIG config; AACENC_PARAM* pAAC_param; VO_AUDIO_FORMAT *pWAV_Format; AAC_ENCODER* hAacEnc = (AAC_ENCODER*)hCodec; int ret, i, bitrate, tmp; int SampleRateIdx; if(NULL == hAacEnc) return VO_ERR_INVALID_ARG; switch(uParamID) { case VO_PID_AAC_ENCPARAM: /** init aac encoder parameter*/ AacInitDefaultConfig(&config); if(pData == NULL) return VO_ERR_INVALID_ARG; pAAC_param = (AACENC_PARAM*)pData; config.adtsUsed = pAAC_param->adtsUsed; config.bitRate = pAAC_param->bitRate; config.nChannelsIn = pAAC_param->nChannels; config.nChannelsOut = pAAC_param->nChannels; config.sampleRate = pAAC_param->sampleRate; /** check the channel */ if(config.nChannelsIn< 1 || config.nChannelsIn > MAX_CHANNELS || config.nChannelsOut < 1 || config.nChannelsOut > MAX_CHANNELS || config.nChannelsIn < config.nChannelsOut) return VO_ERR_AUDIO_UNSCHANNEL; /** check the samplerate */ ret = -1; for(i = 0; i < NUM_SAMPLE_RATES; i++) { if(config.sampleRate == sampRateTab[i]) { ret = 0; break; } } if(ret < 0) return VO_ERR_AUDIO_UNSSAMPLERATE; SampleRateIdx = i; tmp = 441; if(config.sampleRate%8000 == 0) tmp =480; /** check the bitrate */ if(config.bitRate!=0 && (config.bitRate/config.nChannelsOut < 4000) || (config.bitRate/config.nChannelsOut > 160000) || (config.bitRate > config.sampleRate*6*config.nChannelsOut)) { config.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut; if(config.bitRate/config.nChannelsOut < 4000) config.bitRate = 4000 * config.nChannelsOut; else if(config.bitRate > config.sampleRate*6*config.nChannelsOut) config.bitRate = config.sampleRate*6*config.nChannelsOut; else if(config.bitRate/config.nChannelsOut > 160000) config.bitRate = config.nChannelsOut*160000; } /** check the bandwidth */ bitrate = config.bitRate / config.nChannelsOut; bitrate = bitrate * tmp / config.sampleRate; for (i = 0; rates[i]; i++) { if (rates[i] >= bitrate) break; } config.bandWidth = BandwithCoefTab[i][SampleRateIdx]; /** init aac encoder core */ ret = AacEncOpen(hAacEnc, config); if(ret) return VO_ERR_AUDIO_UNSFEATURE; break; case VO_PID_AUDIO_FORMAT: /** init pcm channel and samplerate*/ AacInitDefaultConfig(&config); if(pData == NULL) return VO_ERR_INVALID_ARG; pWAV_Format = (VO_AUDIO_FORMAT*)pData; config.adtsUsed = 1; config.nChannelsIn = pWAV_Format->Channels; config.nChannelsOut = pWAV_Format->Channels; config.sampleRate = pWAV_Format->SampleRate; /** check the channel */ if(config.nChannelsIn< 1 || config.nChannelsIn > MAX_CHANNELS || config.nChannelsOut < 1 || config.nChannelsOut > MAX_CHANNELS || config.nChannelsIn < config.nChannelsOut) return VO_ERR_AUDIO_UNSCHANNEL; /** check the samplebits */ if(pWAV_Format->SampleBits != 16) { return VO_ERR_AUDIO_UNSFEATURE; } /** check the samplerate */ ret = -1; for(i = 0; i < NUM_SAMPLE_RATES; i++) { if(config.sampleRate == sampRateTab[i]) { ret = 0; break; } } if(ret < 0) return VO_ERR_AUDIO_UNSSAMPLERATE; SampleRateIdx = i; /** update the bitrates */ tmp = 441; if(config.sampleRate%8000 == 0) tmp =480; config.bitRate = 640*config.sampleRate/tmp*config.nChannelsOut; if(config.bitRate/config.nChannelsOut < 4000) config.bitRate = 4000 * config.nChannelsOut; else if(config.bitRate > config.sampleRate*6*config.nChannelsOut) config.bitRate = config.sampleRate*6*config.nChannelsOut; else if(config.bitRate/config.nChannelsOut > 160000) config.bitRate = config.nChannelsOut*160000; /** check the bandwidth */ bitrate = config.bitRate / config.nChannelsOut; bitrate = bitrate * tmp / config.sampleRate; for (i = 0; rates[i]; i++) { if (rates[i] >= bitrate) break; } config.bandWidth = BandwithCoefTab[i][SampleRateIdx]; /** init aac encoder core */ ret = AacEncOpen(hAacEnc, config); if(ret) return VO_ERR_AUDIO_UNSFEATURE; break; default: return VO_ERR_WRONG_PARAM_ID; } return VO_ERR_NONE; }
int main(/*int argc, char *argv[]*/) { AACENC_CONFIG config; FILE* inputFile = NULL; SBRDECODER sbrDecoderInfo = 0; FILE *fOut=NULL; HANDLE_MP4_FILE hMp4File; int error; int bitrate; int nChannelsAAC, nChannelsSBR; unsigned int sampleRateAAC; int frmCnt; int bandwidth = 0; unsigned int numAncDataBytes=0; unsigned char ancDataBytes[MAX_PAYLOAD_SIZE]; /*!< required only for interfacing with audio output library, thus not counted into RAM requirements */ short TimeDataPcm[AACENC_BLOCKSIZE*2*MAX_CHANNELS]; int numSamplesRead; int bDoIIR2Downsample = 0; int bDingleRate = 0; int useParametricStereo = 0; int coreWriteOffset = 0; int coreReadOffset = 0; int envWriteOffset = 0; int envReadOffset = 0; int writeOffset=INPUT_DELAY*MAX_CHANNELS; struct AAC_ENCODER *aacEnc = 0; int bDoUpsample = 0; int upsampleReadOffset = 0; int inSamples_enc; int bDoIIR32Resample = 0; const int nRuns = 4; float *resamplerScratch = sbr_envRBuffer; HANDLE_SBR_ENCODER hEnvEnc=NULL; bitrate = 24000; /*open audio input file*/ int sampleRate = 48000 ; /* only relevant if valid == 1 */ int nChannels = 2 ; /* only relevant if valid == 1 */ inputFile = fopen("f:\\xxxx.wav", "rb"); if(inputFile == NULL) { assert(0); return 0; } /* set up basic parameters for aacPlus codec*/ AacInitDefaultConfig(&config); nChannelsAAC = nChannelsSBR = nChannels; if ( (nChannels == 2) && (bitrate > 16000) && (bitrate < 36000) ) { useParametricStereo = 1; } if (useParametricStereo) { nChannelsAAC = 1; nChannelsSBR = 2; } if ( (sampleRate == 48000) && (nChannelsAAC == 2) && (bitrate < 24000) ) { bDoIIR32Resample = 1; } if (sampleRate == 16000) { bDoUpsample = 1; sampleRate = 32000; bDingleRate = 1; } sampleRateAAC = sampleRate; if (bDoIIR32Resample) sampleRateAAC = 32000; config.bitRate = bitrate; config.nChannelsIn=nChannels; config.nChannelsOut=nChannelsAAC; config.bandWidth=bandwidth; /*set up SBR configuration*/ if(!IsSbrSettingAvail (bitrate, nChannelsAAC, sampleRateAAC, &sampleRateAAC)) { fprintf(stderr,"No valid SBR configuration found\n"); exit(10); } { sbrConfiguration sbrConfig; envReadOffset = 0; coreWriteOffset = 0; if(useParametricStereo) { envReadOffset = (MAX_DS_FILTER_DELAY + INPUT_DELAY)*MAX_CHANNELS; coreWriteOffset = CORE_INPUT_OFFSET_PS; writeOffset = envReadOffset; } InitializeSbrDefaults (&sbrConfig); sbrConfig.usePs = useParametricStereo; AdjustSbrSettings(&sbrConfig, bitrate, nChannelsAAC, sampleRateAAC, AACENC_TRANS_FAC, 24000); EnvOpen(&hEnvEnc, inputBuffer + coreWriteOffset, &sbrConfig, &config.bandWidth); /* set IIR 2:1 downsampling */ bDoIIR2Downsample = (bDoUpsample) ? 0 : 1; if (useParametricStereo) { bDoIIR2Downsample = 0; }else{ assert(0); } } if (bDoUpsample) { assert(0); } else { if (bDoIIR2Downsample){ assert(0); } } /* set up AAC encoder, now that samling rate is known */ config.sampleRate = sampleRateAAC; error = AacEncOpen( &aacEnc,config); if (error){ assert(0); AacEncClose(aacEnc); fclose(inputFile); if (fOut) fclose(fOut); return 1; } /*set up MPEG-4/3GPP file format library (not instrumented nor accounted for RAM requirements)*/ { unsigned char ASConfigBuffer[80]; unsigned int nConfigBits; unsigned int nConfigBytes; memset (ASConfigBuffer, 0, 80); if ( GetMPEG4ASConfig( sampleRateAAC, nChannelsAAC, ASConfigBuffer, &nConfigBits, 1, bDingleRate) ) { fprintf(stderr, "\nCould not initialize Audio Specific Config\n"); exit(10); } nConfigBytes = (nConfigBits+7)>>3; if (OpenMP4File(&hMp4File, ASConfigBuffer, nConfigBytes, "f:/out2.3gp", (!bDingleRate) ? sampleRateAAC*2 : sampleRateAAC, /* output sampleRate */ config.bitRate, nChannelsAAC, 1, 1) ) { fprintf(stderr, "\nFailed to create 3GPP file\n") ; exit(10); } } frmCnt = 0; memset(TimeDataPcm,0,sizeof(TimeDataPcm)); /*set up input samples block size feed*/ inSamples_enc = AACENC_BLOCKSIZE * nChannels * 2; ////decodec//////////////////////////////////////////////////////////////////////////////////////// #define INPUT_BUF_SIZE (6144*2/8) /*!< Size of Input buffer in bytes*/ unsigned int inBuffer[INPUT_BUF_SIZE/(sizeof(int))]; /*!< Input buffer */ struct BIT_BUF bitBuf, *hBitBuf; AACDECODER aacDecoderInfo = 0; SBRBITSTREAM streamSBR; hBitBuf = CreateBitBuffer(&bitBuf,(unsigned char*) inBuffer,INPUT_BUF_SIZE); aacDecoderInfo = CAacDecoderOpen(hBitBuf, &streamSBR, TimeDataFloat); if(0 == aacDecoderInfo) { assert(0); return 0; } if(0 != CAacDecoderInit (aacDecoderInfo,sampleRate/2,bitrate)) { assert(0); return 0; } /////////////////////////////////////////////////////////////////////////////////////////////////// FILE* fw = fopen("f:\\uuu.pcm", "wb"); /* The frame loop */ while (1) { int i, numOutBytes; numSamplesRead = fread(TimeDataPcm, 2, inSamples_enc, inputFile); if(numSamplesRead <= 0) { break; } /* copy from short to float input buffer */ if ( nChannels == nChannelsSBR ) { for (i=0; i<numSamplesRead; i++) { inputBuffer[i+writeOffset] = (float) TimeDataPcm[i]; } } #if (MAX_CHANNELS==2) /* copy from short to float input buffer, reordering necessary since the encoder takes interleaved data */ if(nChannels == 1) { int i; for (i=0; i<numSamplesRead; i++) { inputBuffer[writeOffset+2*i] = (float) TimeDataPcm[i]; } } #endif /*encode one SBR frame*/ EnvEncodeFrame (hEnvEnc, inputBuffer + envReadOffset, inputBuffer + coreWriteOffset, MAX_CHANNELS, &numAncDataBytes, ancDataBytes); /*encode one AAC frame*/ if (hEnvEnc && useParametricStereo) { AacEncEncode(aacEnc, inputBuffer, 1, /* stride */ ancDataBytes, &numAncDataBytes, outputBuffer, &numOutBytes); if(hEnvEnc) { memcpy( inputBuffer,inputBuffer+AACENC_BLOCKSIZE,CORE_INPUT_OFFSET_PS*sizeof(float)); } } else { assert(0); } ////////////////////////////////////////dec unsigned char* pData = (unsigned char*)outputBuffer; for(int i = 0; i < numOutBytes; i++) WriteBits(hBitBuf,pData[i],8); streamSBR.NrElements = 0; int frameSize_dec= 0, sampleRate_dec = 0, numChannels_dec = 2; char frameOk_dec = 1, channelMode_dec = 0; int ErrorStatus = CAacDecoder_DecodeFrame(aacDecoderInfo,&frameSize_dec,&sampleRate_dec, &numChannels_dec, &channelMode_dec, frameOk_dec); assert(ErrorStatus == 0); if ((!sbrDecoderInfo) && streamSBR.NrElements) sbrDecoderInfo = openSBR (sampleRate_dec,frameSize_dec, 0,0); if (sbrDecoderInfo) { /* apply SBR processing */ if (applySBR(sbrDecoderInfo, &streamSBR, TimeDataFloat, &numChannels_dec, frameOk_dec, 0, 0) != SBRDEC_OK){ sbrDecoderInfo = 0; } else { frameSize_dec = frameSize_dec * 2; sampleRate_dec *= 2; } } short* pwData = new short[frameSize_dec * 2]; /* clip time samples */ for (i = 0; i < frameSize_dec * numChannels_dec; i++) { if (TimeDataFloat[i] < -32768.0) { TimeDataFloat[i] = -32768.0; } else { if (TimeDataFloat[i] > 32767.0) { TimeDataFloat[i] = 32767.0; } } //pwData[i] = TimeDataFloat[i]; } interleaveSamples(&TimeDataFloat[0],&TimeDataFloat[frameSize_dec],pwData,frameSize_dec,&numChannels_dec); fwrite(pwData, 2, frameSize_dec * numChannels_dec, fw); delete [] pwData; //////////////////////////////////////////////////////////////////////// if (numOutBytes) { MP4FileAddFrame( hMp4File, outputBuffer, numOutBytes ); } frmCnt++; /* 3GPP instrumenting tool: measure worst case work load at end of each decoding loop */ fprintf(stderr,"[%d]\r",frmCnt); fflush(stderr); } fprintf(stderr,"\n"); fflush(stderr); AacEncClose(aacEnc); fclose(inputFile); if (WriteMP4File( hMp4File)) { fprintf(stderr, "Writing of 3GPP file failed."); exit(10); } CloseMP4File( hMp4File); if(hEnvEnc) { EnvClose(hEnvEnc); } printf("\nencoding finished\n"); return 0; }