virtual bool Enc(const short* pwData, std::string& encData) { unsigned char ancDataBytes[MAX_PAYLOAD_SIZE]; unsigned int numAncDataBytes = 0; unsigned int outputBuffer[(6144/8)*MAX_CHANNELS/(sizeof(int))]; int numOutBytes = 0; if(!m_hEnvEnc) { return false; } for(register int i=0; i<m_inSamples_enc; i++) { m_inputBuffer[i+m_writeOffset] = (float) pwData[i]; } EnvEncodeFrame(m_hEnvEnc, m_inputBuffer + m_envReadOffset, m_inputBuffer + m_coreWriteOffset, MAX_CHANNELS, &numAncDataBytes, ancDataBytes); /*encode one AAC frame*/ AacEncEncode(m_pAacEnc, m_inputBuffer, 1, ancDataBytes, &numAncDataBytes, outputBuffer, &numOutBytes); memcpy(m_inputBuffer, m_inputBuffer+AACENC_BLOCKSIZE, CORE_INPUT_OFFSET_PS*sizeof(float)); encData.assign((char*)outputBuffer,numOutBytes); return true; }
void aacPlusEncoder :: encodeAacSamples (short *TimeDataPcm, unsigned int samples, int channels) throw ( Exception ) { unsigned int i; int ch, outSamples, numOutBytes; for (i=0; i<samples; i++) inBuf[(2/channels)*i+writeOffset+writtenSamples] = (float) TimeDataPcm[i]; writtenSamples+=samples; if (writtenSamples < inSamples) return; /* encode one SBR frame */ EnvEncodeFrame( hEnvEnc, inBuf + envReadOffset, inBuf + coreWriteOffset, MAX_CHANNELS, &numAncDataBytes, ancDataBytes); /* 2:1 downsampling for AAC core */ if (!useParametricStereo) { for( ch=0; ch<nChannelsAAC; ch++ ) IIR21_Downsample( &(IIR21_reSampler[ch]), inBuf + writeOffset+ch, writtenSamples/channels, MAX_CHANNELS, inBuf+ch, &outSamples, MAX_CHANNELS); } /* encode one AAC frame */ AacEncEncode( aacEnc, inBuf, useParametricStereo ? 1 : MAX_CHANNELS, /* stride (step) */ ancDataBytes, &numAncDataBytes, (unsigned *) (outBuf+ADTS_HEADER_SIZE), &numOutBytes); if (useParametricStereo) { memcpy( inBuf,inBuf+AACENC_BLOCKSIZE,CORE_INPUT_OFFSET_PS*sizeof(float)); } else { memmove( inBuf,inBuf+AACENC_BLOCKSIZE*2*MAX_CHANNELS,writeOffset*sizeof(float)); } /* Write one frame of encoded audio */ if (numOutBytes) { adts_hdr_up(outBuf, numOutBytes); sink->write(outBuf, numOutBytes+ADTS_HEADER_SIZE); } writtenSamples=0; return; }
bool FloatAACPlusEncodeCodec::Encode(unsigned char* p,int len,unsigned char* outp,int&outl) { if(m_hSbr == NULL || m_hAac == NULL) return false; unsigned int numAncDataBytes=0; short* inputStream = (short*)p; memset(ancDataBytes,0,MAX_PAYLOAD_SIZE); for(register int i=0; i<len/sizeof(short); ++ i) { inputBuffer[i+writeOffset] = (float) inputStream[i]; } EnvEncodeFrame ((HANDLE_SBR_ENCODER)m_hSbr, inputBuffer + envReadOffset, inputBuffer + coreWriteOffset, MAX_CHANNELS, &numAncDataBytes, ancDataBytes); if(useParametricStereo) { AacEncEncode((struct AAC_ENCODER *)m_hAac, inputBuffer, 1, ancDataBytes, &numAncDataBytes, outputBuffer, &outl); } else { AacEncEncode((struct AAC_ENCODER *)m_hAac, inputBuffer+0, MAX_CHANNELS, ancDataBytes, &numAncDataBytes, outputBuffer, &outl); } memcpy(inputBuffer,inputBuffer+AACENC_BLOCKSIZE,CORE_INPUT_OFFSET_PS*sizeof(float)); memcpy(outp, outputBuffer, outl); return true; }
int HEAACCodec::Encode(unsigned char *pBufIn, unsigned int nLenIn) { int code_size = 0; if(sbr_handler_ == NULL || aac_handler_ == NULL || nLenIn <= 0) { return -1; } short* raw = (short *)pBufIn; unsigned int numAncDataBytes=0; unsigned char ancDataBytes[MAX_PAYLOAD_SIZE]; unsigned int ancDataLength = 0; //转成FLOAT进行编码 for(register int i=0; i<nLenIn / 2; ++ i) { inputBuffer[i+writeOffset] = (float) raw[i]; } //sbr EnvEncodeFrame((HANDLE_SBR_ENCODER)sbr_handler_, inputBuffer + envReadOffset, inputBuffer + coreWriteOffset, MAX_CHANNELS, &numAncDataBytes, ancDataBytes); int out_size = 0; if(useParametricStereo) { AacEncEncode((struct AAC_ENCODER *)aac_handler_, inputBuffer, 1, /* stride */ ancDataBytes, &numAncDataBytes, outputBuffer, &out_size); } else { AacEncEncode((struct AAC_ENCODER *)aac_handler_, inputBuffer+0, MAX_CHANNELS, ancDataBytes, &numAncDataBytes, outputBuffer, &out_size); } code_size = out_size; memcpy(inputBuffer,inputBuffer+AACENC_BLOCKSIZE,CORE_INPUT_OFFSET_PS*sizeof(float)); unsigned char *code = GetBuffer(); memcpy(code, outputBuffer, code_size); encode_frame_ = true; return out_size; }
/*------------------------------------------------------------------------------ * 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; unsigned int samples = (unsigned int) nSamples * channels; unsigned int i; int ch, outSamples, numOutBytes; reportEvent(10, "converting short to float"); short *TimeDataPcm = (short *) buf; if(channels == 2) { for (i=0; i<samples; i++) inBuf[i+writeOffset+writtenSamples] = (float) TimeDataPcm[i]; } else { /* using only left channel buffer for mono encoder */ for (i=0; i<samples; i++) inBuf[writeOffset+2*writtenSamples+2*i] = (float) TimeDataPcm[i]; } writtenSamples+=samples; reportEvent(10, "writtenSamples", writtenSamples); if (writtenSamples < inSamples) return samples; /* encode one SBR frame */ reportEvent(10, "encode one SBR frame"); EnvEncodeFrame( hEnvEnc, inBuf + envReadOffset, inBuf + coreWriteOffset, MAX_CHANNELS, &numAncDataBytes, ancDataBytes); reportEvent(10, "numAncDataBytes=", numAncDataBytes); /* 2:1 downsampling for AAC core */ if (!useParametricStereo) { reportEvent(10, "2:1 downsampling for AAC core"); for( ch=0; ch<nChannelsAAC; ch++ ) IIR21_Downsample( &(IIR21_reSampler[ch]), inBuf + writeOffset+ch, writtenSamples/channels, MAX_CHANNELS, inBuf+ch, &outSamples, MAX_CHANNELS); reportEvent(10, "outSamples=", outSamples); } /* encode one AAC frame */ reportEvent(10, "encode one AAC frame"); AacEncEncode( aacEnc, inBuf, useParametricStereo ? 1 : MAX_CHANNELS, /* stride (step) */ ancDataBytes, &numAncDataBytes, (unsigned *) (outBuf+ADTS_HEADER_SIZE), &numOutBytes); if (useParametricStereo) { memcpy( inBuf,inBuf+AACENC_BLOCKSIZE,CORE_INPUT_OFFSET_PS*sizeof(float)); } else { memmove( inBuf,inBuf+AACENC_BLOCKSIZE*2*MAX_CHANNELS,writeOffset*sizeof(float)); } /* Write one frame of encoded audio */ if (numOutBytes) { reportEvent(10, "Write one frame of encoded audio:", numOutBytes+ADTS_HEADER_SIZE); adts_hdr_up(outBuf, numOutBytes); sink->write(outBuf, numOutBytes+ADTS_HEADER_SIZE); } writtenSamples=0; return samples; }
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; }