cfaac.cpp
来自「faac-1.25.rar音频编解码器demo」· C++ 代码 · 共 720 行 · 第 1/2 页
CPP
720 行
#endif
{
// swap bytes
for (i = 0; i < size; i++)
{
int s = bufi[i];
buf[i] = SWAP32(s);
}
}
else
memcpy(buf,bufi,size*sizeof(u_int32_t));
/*
int exponent, mantissa;
float *bufo=(float *)buf;
for (i = 0; i < size; i++)
{
exponent=bufi[(i<<2)+3]<<1;
if(bufi[i*4+2] & 0x80)
exponent|=0x01;
exponent-=126;
mantissa=(DWORD)bufi[(i<<2)+2]<<16;
mantissa|=(DWORD)bufi[(i<<2)+1]<<8;
mantissa|=bufi[(i<<2)];
bufo[i]=(float)ldexp(mantissa,exponent);
}*/
break;
}
}
// *********************************************************************************************
// Main functions
// *********************************************************************************************
void Cfaac::DisplayError(char *ProcName, char *str)
{
char buf[100]="";
if(str && *str)
{
if(ProcName && *ProcName)
sprintf(buf,"%s: ", ProcName);
strcat(buf,str);
MessageBox(0, buf, APP_NAME " plugin", MB_OK|MB_ICONSTOP);
}
MYOUTPUT *mo;
GLOBALLOCK(mo,hOutput,MYOUTPUT,return);
mo->bytes_into_buffer=-1;
GlobalUnlock(hOutput);
GlobalUnlock(hOutput);
}
// *********************************************************************************************
HANDLE Cfaac::Init(LPSTR InFileName, LPSTR OutFileName,long lSamprate,WORD wBitsPerSample,WORD wChannels,long FileSize)
{
MYOUTPUT *mo;
CMyEncCfg cfg(false);
DWORD samplesInput,
maxBytesOutput;
// if(wBitsPerSample!=8 && wBitsPerSample!=16) // 32 bit audio from cooledit is in unsupported format
// return 0;
if(wChannels>48) // FAAC supports max 48 tracks!
return NULL;
GLOBALLOCK(mo,hOutput,MYOUTPUT,return NULL);
// open the encoder library
if(!(mo->hEncoder=faacEncOpen(lSamprate, wChannels, &samplesInput, &maxBytesOutput)))
return ERROR_Init("Can't open library");
if(!(mo->bitbuf=(unsigned char *)malloc(maxBytesOutput*sizeof(unsigned char))))
return ERROR_Init("Memory allocation error: output buffer");
if(!(mo->bufIn=(BYTE *)malloc(samplesInput*sizeof(int32_t))))
return ERROR_Init("Memory allocation error: input buffer");
if(!(mo->buf32bit=(int32_t *)malloc(samplesInput*sizeof(int32_t))))
return ERROR_Init("Memory allocation error: 32 bit buffer");
if(cfg.SaveMP4)// || cfg.Tag.On)
{
int ExtPos=0, // append new ext
fnLen=lstrlen(OutFileName);
// if(OutFileName[lstrlen(OutFileName)-4]=='.')
if( fnLen>=4 &&
(!strcmpi(OutFileName+fnLen-4,".aac") ||
!strcmpi(OutFileName+fnLen-4,".mp4") ||
!strcmpi(OutFileName+fnLen-4,".m4a") ||
!strcmpi(OutFileName+fnLen-4,".m4b"))) // no aac/mp4 ext => append new ext
if( (cfg.SaveMP4==1 && strcmpi(OutFileName+fnLen-4,".mp4")) ||
(cfg.SaveMP4==2 && strcmpi(OutFileName+fnLen-4,".m4a")) ||
(cfg.SaveMP4==3 && strcmpi(OutFileName+fnLen-4,".m4b")))
ExtPos=4; // wrong ext => replace it
else
ExtPos=-1; // correct ext => no action
if(ExtPos!=-1)
{
switch(cfg.SaveMP4)
{
case 1: strcpy(OutFileName+fnLen-ExtPos,".mp4"); break;
case 2: strcpy(OutFileName+fnLen-ExtPos,".m4a"); break;
case 3: strcpy(OutFileName+fnLen-ExtPos,".m4b"); break;
}
FILE *f=fopen(OutFileName,"rb");
if(f)
{
char buf[MAX_PATH+20];
sprintf(buf,"Overwrite \"%s\" ?",OutFileName);
fclose(f);
if(MessageBox(NULL,buf,"File already exists!",MB_YESNO|MB_ICONQUESTION)==IDNO)
return ERROR_Init(0);//"User abort");
}
}
}
mo->WriteMP4= !strcmpi(OutFileName+lstrlen(OutFileName)-4,".mp4") ||
!strcmpi(OutFileName+lstrlen(OutFileName)-4,".m4a") ||
!strcmpi(OutFileName+lstrlen(OutFileName)-4,".m4b");
faacEncConfigurationPtr CurFormat=faacEncGetCurrentConfiguration(mo->hEncoder);
CurFormat->inputFormat=FAAC_INPUT_32BIT;
/* switch(wBitsPerSample)
{
case 16:
CurFormat->inputFormat=FAAC_INPUT_16BIT;
break;
case 24:
CurFormat->inputFormat=FAAC_INPUT_24BIT;
break;
case 32:
CurFormat->inputFormat=FAAC_INPUT_32BIT;
break;
default:
CurFormat->inputFormat=FAAC_INPUT_NULL;
break;
}*/
if(!cfg.AutoCfg)
{
faacEncConfigurationPtr myFormat=&cfg.EncCfg;
if(cfg.UseQuality)
{
CurFormat->quantqual=myFormat->quantqual;
CurFormat->bitRate=0;//myFormat->bitRate;
}
else
{
CurFormat->bitRate=(myFormat->bitRate*1000)/wChannels;
CurFormat->quantqual=100;
}
switch(CurFormat->bandWidth)
{
case 0: // Auto
break;
case 0xffffffff: // Full
CurFormat->bandWidth=lSamprate/2;
break;
default:
CurFormat->bandWidth=myFormat->bandWidth;
break;
}
CurFormat->mpegVersion=myFormat->mpegVersion;
CurFormat->outputFormat=myFormat->outputFormat;
CurFormat->mpegVersion=myFormat->mpegVersion;
CurFormat->aacObjectType=myFormat->aacObjectType;
CurFormat->allowMidside=myFormat->allowMidside;
// CurFormat->useTns=myFormat->useTns;
CurFormat->useTns=false;
}
else
{
CurFormat->mpegVersion=DEF_MPEGVER;
CurFormat->aacObjectType=DEF_PROFILE;
CurFormat->allowMidside=DEF_MIDSIDE;
// CurFormat->useTns=DEF_TNS;
CurFormat->useTns=false;
CurFormat->useLfe=DEF_LFE;
CurFormat->quantqual=DEF_QUALITY;
CurFormat->bitRate=DEF_BITRATE;
CurFormat->bandWidth=DEF_BANDWIDTH;
CurFormat->outputFormat=DEF_HEADER;
}
if(mo->WriteMP4)
CurFormat->outputFormat=RAW;
CurFormat->useLfe=wChannels>=6 ? 1 : 0;
if(!faacEncSetConfiguration(mo->hEncoder, CurFormat))
return ERROR_Init("Unsupported parameters!");
// mo->src_size=lSize;
// mi->dst_name=strdup(OutFileName);
mo->Samprate=lSamprate;
mo->BitsPerSample=wBitsPerSample;
mo->Channels=wChannels;
mo->samplesInput=samplesInput;
mo->samplesInputSize=samplesInput*(mo->BitsPerSample>>3);
mo->maxBytesOutput=maxBytesOutput;
if(mo->WriteMP4) // Create MP4 file --------------------------------------------------------------------------
{
BYTE *ASC=0;
DWORD ASCLength=0;
if((mo->MP4File=MP4Create(OutFileName, 0, 0))==MP4_INVALID_FILE_HANDLE)
return ERROR_Init("Can't create file");
MP4SetTimeScale(mo->MP4File, 90000);
mo->MP4track=MP4AddAudioTrack(mo->MP4File, lSamprate, MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE);
MP4SetAudioProfileLevel(mo->MP4File, 0x0F);
faacEncGetDecoderSpecificInfo(mo->hEncoder, &ASC, &ASCLength);
MP4SetTrackESConfiguration(mo->MP4File, mo->MP4track, (unsigned __int8 *)ASC, ASCLength);
mo->frameSize=samplesInput/wChannels;
mo->ofs=mo->frameSize;
if(cfg.TagOn)
{
int error=0;
#ifdef USE_IMPORT_TAG
if(cfg.TagImport && InFileName)
{
int l=strlen(InFileName);
if( !strcmpi(InFileName+l-4,".mp4") ||
!strcmpi(InFileName+l-4,".m4a") ||
!strcmpi(InFileName+l-4,".m4b"))
error=cfg.Tag.ReadMp4Tag(InFileName);
else
error=cfg.Tag.ReadAacTag(InFileName);
}
#endif
if(!error)
cfg.Tag.WriteMP4Tag(mo->MP4File);
}
}
else // Create AAC file -----------------------------------------------------------------------------
{
// open the aac output file
if(!(mo->aacFile=fopen(OutFileName, "wb")))
return ERROR_Init("Can't create file");
// use bufferized stream
setvbuf(mo->aacFile,NULL,_IOFBF,32767);
mo->InFilename=strdup(InFileName);
mo->OutFilename=strdup(OutFileName);
}
showInfo(mo);
GlobalUnlock(hOutput);
return hOutput;
}
// *********************************************************************************************
int Cfaac::processData(HANDLE hOutput, BYTE *bufIn, DWORD len)
{
if(!hOutput)
return -1;
int bytesWritten=0;
int bytesEncoded;
MYOUTPUT far *mo;
GLOBALLOCK(mo,hOutput,MYOUTPUT,return 0);
int32_t *buf=mo->buf32bit;
if((int)len<mo->samplesInputSize)
{
mo->samplesInput=(len<<3)/mo->BitsPerSample;
mo->samplesInputSize=mo->samplesInput*(mo->BitsPerSample>>3);
}
// if(mo->BitsPerSample==8 || mo->BitsPerSample==32)
To32bit(buf,bufIn,mo->samplesInput,mo->BitsPerSample>>3,false);
// call the actual encoding routine
if((bytesEncoded=faacEncEncode(mo->hEncoder, (int32_t *)buf, mo->samplesInput, mo->bitbuf, mo->maxBytesOutput))<0)
return ERROR_processData("faacEncEncode()");
// write bitstream to aac file
if(mo->aacFile)
{
if(bytesEncoded>0)
{
if((bytesWritten=fwrite(mo->bitbuf, 1, bytesEncoded, mo->aacFile))!=bytesEncoded)
return ERROR_processData("Write failed!");
mo->WrittenSamples=1; // needed into destructor
}
}
else
// write bitstream to mp4 file
{
MP4Duration dur,
SamplesLeft;
if(len>0)
{
mo->srcSize+=len;
dur=mo->frameSize;
}
else
{
mo->TotalSamples=(mo->srcSize<<3)/(mo->BitsPerSample*mo->Channels);
SamplesLeft=(mo->TotalSamples-mo->WrittenSamples)+mo->frameSize;
dur=SamplesLeft>mo->frameSize ? mo->frameSize : SamplesLeft;
}
if(bytesEncoded>0)
{
if(!(bytesWritten=MP4WriteSample(mo->MP4File, mo->MP4track, (unsigned __int8 *)mo->bitbuf, (DWORD)bytesEncoded, dur, mo->ofs, true) ? bytesEncoded : -1))
return ERROR_processData("MP4WriteSample()");
mo->ofs=0;
mo->WrittenSamples+=dur;
}
}
showProgress(mo);
GlobalUnlock(hOutput);
return bytesWritten;
}
// -----------------------------------------------------------------------------------------------
int Cfaac::processDataBufferized(HANDLE hOutput, BYTE *bufIn, long lBytes)
{
if(!hOutput)
return -1;
int bytesWritten=0, tot=0;
MYOUTPUT far *mo;
GLOBALLOCK(mo,hOutput,MYOUTPUT,return 0);
if(mo->bytes_into_buffer>=0)
do
{
if(mo->bytes_into_buffer+lBytes<mo->samplesInputSize)
{
memmove(mo->bufIn+mo->bytes_into_buffer, bufIn, lBytes);
mo->bytes_into_buffer+=lBytes;
lBytes=0;
}
else
{
int shift=mo->samplesInputSize-mo->bytes_into_buffer;
memmove(mo->bufIn+mo->bytes_into_buffer, bufIn, shift);
mo->bytes_into_buffer+=shift;
bufIn+=shift;
lBytes-=shift;
tot+=bytesWritten=processData(hOutput,mo->bufIn,mo->bytes_into_buffer);
if(bytesWritten<0)
return ERROR_processData(0);
mo->bytes_into_buffer=0;
}
}while(lBytes);
GlobalUnlock(hOutput);
return tot;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?