关于alaw转pcm的注意事项


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;
}

你可能感兴趣的:(mp4封装)