alaw转pcm后size会扩大一倍,malloc时需要放大为maxInputBytes*2,否则用pcmbuffer进行encode后会导致faacEncClose(hFaac)段错误
#include
#include
#include
#include "stdint.h"
#include
//要在faac.h前定义,确保FAACAPI定义为空,否则可能被定义为# define FAACAPI __stdcall造成链接失败
#define FAACAPI
#include "faac.h"
#define SEG_SHIFT (4)
#define SEG_MASK (0x70)
#define SIGN_BIT (0x80)
#define QUANT_MASK (0xf)
#define NSEGS (8)
#define BIAS (0x84) /* Bias for linear code. */
short ulaw2linear(unsigned char u_val) //ulaw
{
short t;
/* Complement to obtain normal u-law value. */
u_val = ~u_val;
/*
* Extract and bias the quantization bits. Then
* shift up by the segment number and subtract out the bias.
*/
t = ((u_val & QUANT_MASK) << 3) + BIAS;
t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
}
short decode(unsigned char alaw) //alaw
{
alaw ^= 0xD5;
int sign = alaw & 0x80;
int exponent = (alaw & 0x70) >> 4;
int data = alaw & 0x0f;
data <<= 4;
data += 8;
if (exponent != 0)
data += 0x100;
if (exponent > 1)
data <<= (exponent - 1);
return (short)(sign == 0 ? data : -data);
}
int g711_decode(char* pRawData, const unsigned char* pBuffer, int nBufferSize)
{
short *out_data = (short*)pRawData;
int i;
for(i=0; iconfig.outputFormat = 1;
PCM Sample Input Format
0 FAAC_INPUT_NULL invalid, signifies a misconfigured config
1 FAAC_INPUT_16BIT native endian 16bit
2 FAAC_INPUT_24BIT native endian 24bit in 24 bits (not implemented)
3 FAAC_INPUT_32BIT native endian 24bit in 32 bits (DEFAULT)
4 FAAC_INPUT_FLOAT 32bit floating point
hEncoder->config.inputFormat = FAAC_INPUT_32BIT;
hEncoder->config.version = FAAC_CFG_VERSION;
hEncoder->config.name = libfaacName;
hEncoder->config.copyright = libCopyright;
hEncoder->config.mpegVersion = MPEG4;
hEncoder->config.aacObjectType = LTP;
hEncoder->config.allowMidside = 1;
hEncoder->config.useLfe = 1;
hEncoder->config.useTns = 0;
hEncoder->config.bitRate = 0;
hEncoder->config.bandWidth = 0.45 * hEncoder->sampleRate;
if(hEncoder->config.bandWidth > 16000)
hEncoder->config.bandWidth = 16000;
hEncoder->config.quantqual = 100;
hEncoder->config.shortctl = SHORTCTL_NORMAL;
*/
pFaacConf->inputFormat=FAAC_INPUT_16BIT;//默认32bit
pFaacConf->aacObjectType = MAIN;//推荐MAIN
//设置配置
// pFaacConf->bitRate = 48000;
// pFaacConf->bandWidth = 60000;
faacEncSetConfiguration(hFaac,pFaacConf);
maxInputBytes=inputSamples*waveFormat.wBitsPerSample/8;
pcmBuffer=(uint8_t*)malloc(sizeof(uint8_t)*maxInputBytes*2);
g711_Buffer=(uint8_t*)malloc(sizeof(uint8_t)*maxInputBytes);
aacBuffer=(uint8_t*)malloc(sizeof(uint8_t)*maxOutputBytes);
timestamp=clock();
while(CountDataSize0)
fwrite(aacBuffer,1,RealOutputBytes,ffaac);
}
//
while((RealOutputBytes=faacEncEncode(hFaac,NULL,0,aacBuffer,maxOutputBytes))>0){
fwrite(aacBuffer,1,RealOutputBytes,ffaac);
}
printf("time:%u ms\n",clock()-timestamp);
//关闭编码器
faacEncClose(hFaac);
free(pcmBuffer);
free(g711_Buffer);
free(aacBuffer);
fclose(fp);
fclose(ffaac);
return 0;
}
typedef struct _RIFF_HEADER{
uint32_t RiffID;//'RIFF'
uint32_t RiffSize;//文件总长度-8
uint32_t RiffFormat;//类型'WAVE'
}RIFF_HEADER;
typedef struct _BLOCK_HEADER{
uint32_t BlockID;//'fmt ' 'fact' 'Data'
uint32_t BlockSize;//
}BLOCK_HEADER;
#define MAKETAG(a,b,c,d) ((a&0xff)|((b<<8)&(0xff00))|((c<<16)&(0xff0000))|((d<<24)&(0xff000000)))//'abcd'
uint32_t ReadWaveFormat(FILE*fp,WAVE_FORMAT*format){
RIFF_HEADER Riff_Header={0};
BLOCK_HEADER BlockHeader={0};
uint32_t dataPos=0;
uint32_t dataSize=0;
fread(&Riff_Header,1,sizeof(Riff_Header),fp);
// printf("RiffID:%0.4s RiffSize:%u RiffFormat:%0.4s\n",(char*)&(Riff_Header.RiffID),Riff_Header.RiffSize,(char*)&(Riff_Header.RiffFormat));
// 坚持是否是WAV文件
if((Riff_Header.RiffID!=MAKETAG('R','I','F','F'))||(Riff_Header.RiffFormat!=MAKETAG('W','A','V','E'))){
return 0;
}
while(fread(&BlockHeader,1,sizeof(BlockHeader),fp)==sizeof(BlockHeader)){
// printf("BlockID:%0.4s BlockSize:%u\n",(char*)&(BlockHeader.BlockID),BlockHeader.BlockSize);
//读取格式信息
if(BlockHeader.BlockID==MAKETAG('f','m','t',' ')){
uint32_t Pos=ftell(fp);
fread(format,1,sizeof(WAVE_FORMAT),fp);
fseek(fp,Pos,SEEK_SET);
}
//定位数据未知和数据大小
if(BlockHeader.BlockID==MAKETAG('d','a','t','a')){
dataPos=ftell(fp);
dataSize=BlockHeader.BlockSize;
}
if(BlockHeader.BlockSize>0){
fseek(fp,BlockHeader.BlockSize,SEEK_CUR);
}else{
break;
}
}
fseek(fp,dataPos,SEEK_SET);
return dataSize;
}