📄 cfaad.cpp
字号:
void Cfaad::setFaadCfg(faacDecHandle hDecoder, CMyDecCfg Cfg){faacDecConfigurationPtr config=faacDecGetCurrentConfiguration(hDecoder); if(!Cfg.DefaultCfg) { config->defObjectType=Cfg.DecCfg.defObjectType; config->outputFormat=Cfg.DecCfg.outputFormat; config->defSampleRate=Cfg.DecCfg.defSampleRate; config->downMatrix=Cfg.DecCfg.downMatrix; config->useOldADTSFormat=Cfg.DecCfg.useOldADTSFormat; config->dontUpSampleImplicitSBR=1; } else { config->defObjectType=LC; config->outputFormat=FAAD_FMT_16BIT; config->defSampleRate=44100; config->downMatrix=0; config->useOldADTSFormat=0; config->dontUpSampleImplicitSBR=1; } faacDecSetConfiguration(hDecoder, config);}// -----------------------------------------------------------------------------------------------void Cfaad::setDefaultFaadCfg(faacDecHandle hDecoder, BOOL showDlg){ if(showDlg && ShowDlg4RawAAC) ShowDlg4RawAAC();CMyDecCfg Cfg(false); setFaadCfg(hDecoder,Cfg);}// -----------------------------------------------------------------------------------------------void Cfaad::DisplayError(char *ProcName, char *str){MYINPUT *mi;char buf[100]=""; GlobalUnlock(hInput); // it wasn't done in getInfos() GLOBALLOCK(mi,hInput,MYINPUT,return); if(ProcName && *ProcName) sprintf(buf,"%s: ", ProcName); if(str && *str) strcat(buf,str); if(*buf && str) MessageBox(0, buf, APP_NAME " plugin", MB_OK|MB_ICONSTOP); mi->bytes_into_buffer=-1; GlobalUnlock(hInput);}// *********************************************************************************************HANDLE Cfaad::getInfos(LPSTR lpstrFilename){MYINPUT *mi;// test tags//CMyDecCfg cfg; cfg.Tag.ReadMp4Tag(lpstrFilename);//CMyDecCfg cfg; cfg.Tag.ReadAacTag(lpstrFilename); GLOBALLOCK(mi,hInput,MYINPUT,return NULL);// mi->IsAAC=strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".aac")==0; if((mi->IsMP4=IsMP4(lpstrFilename))==-1) return ERROR_getInfos("Error opening file"); if(mi->IsMP4) // MP4 file --------------------------------------------------------------------- { MP4Duration length; unsigned __int32 buffer_size; DWORD timeScale; BYTE sf; mp4AudioSpecificConfig mp4ASC; if(!(mi->mp4File=MP4Read(lpstrFilename, 0))) return ERROR_getInfos("Error opening file"); if((mi->track=GetAACTrack(mi->mp4File))<0) return ERROR_getInfos(0); //"Unable to find correct AAC sound track"); if(!(mi->hDecoder=faacDecOpen())) return ERROR_getInfos("Error initializing decoder library"); MP4GetTrackESConfiguration(mi->mp4File, mi->track, (unsigned __int8 **)&mi->buffer, &buffer_size); if(!mi->buffer) return ERROR_getInfos("MP4GetTrackESConfiguration()"); AudioSpecificConfig(mi->buffer, buffer_size, &mp4ASC); timeScale = mp4ASC.samplingFrequency; mi->Channels=mp4ASC.channelsConfiguration; sf = mp4ASC.samplingFrequencyIndex; mi->type = mp4ASC.objectTypeIndex;// mi->SBR=mp4ASC.sbr_present_flag; if(faacDecInit2(mi->hDecoder, mi->buffer, buffer_size, &mi->Samprate, &mi->Channels) < 0) return ERROR_getInfos("Error initializing decoder library"); FREE_ARRAY(mi->buffer); length=MP4GetTrackDuration(mi->mp4File, mi->track); mi->len_ms=(DWORD)MP4ConvertFromTrackDuration(mi->mp4File, mi->track, length, MP4_MSECS_TIME_SCALE); mi->file_info.bitrate=MP4GetTrackBitRate(mi->mp4File, mi->track); mi->file_info.version=MP4GetTrackAudioType(mi->mp4File, mi->track)==MP4_MPEG4_AUDIO_TYPE ? 4 : 2; mi->numSamples=MP4GetTrackNumberOfSamples(mi->mp4File, mi->track); mi->sampleId=1; mi->IsSeekable=true; mi->LockSeeking=!mi->IsSeekable; } else // AAC file ------------------------------------------------------------------------------ { DWORD read, tmp; BYTE Channels4Raw=0; if(!(mi->aacFile=fopen(lpstrFilename,"rb"))) return ERROR_getInfos("Error opening file"); // use bufferized stream setvbuf(mi->aacFile,NULL,_IOFBF,32767); // get size of file fseek(mi->aacFile, 0, SEEK_END); mi->src_size=ftell(mi->aacFile); fseek(mi->aacFile, 0, SEEK_SET); if(!(mi->buffer=(BYTE *)malloc(FAAD_STREAMSIZE))) return ERROR_getInfos("Memory allocation error: mi->buffer"); tmp=mi->src_size<FAAD_STREAMSIZE ? mi->src_size : FAAD_STREAMSIZE; read=fread(mi->buffer, 1, tmp, mi->aacFile); if(read==tmp) { mi->bytes_read=read; mi->bytes_into_buffer=read; } else return ERROR_getInfos("Read failed!"); // skip Tag long tagsize; if(tagsize=id3v2_TagSize(mi->buffer)) { if(tagsize>(long)mi->src_size) ERROR_getInfos("Corrupt stream!"); if(tagsize<mi->bytes_into_buffer) { mi->bytes_into_buffer-=tagsize; memcpy(mi->buffer,mi->buffer+tagsize,mi->bytes_into_buffer); } else { mi->bytes_read=tagsize; mi->bytes_into_buffer=0; if(tagsize>mi->bytes_into_buffer) fseek(mi->aacFile, tagsize, SEEK_SET); } if(mi->src_size<mi->bytes_read+FAAD_STREAMSIZE-mi->bytes_into_buffer) tmp=mi->src_size-mi->bytes_read; else tmp=FAAD_STREAMSIZE-mi->bytes_into_buffer; read=fread(mi->buffer+mi->bytes_into_buffer, 1, tmp, mi->aacFile); if(read==tmp) { mi->bytes_read+=read; mi->bytes_into_buffer+=read; } else ERROR_getInfos("Read failed!"); } if(get_AAC_format(lpstrFilename, &mi->file_info, &mi->seek_table, &mi->seek_table_length, 0)) ERROR_getInfos("get_AAC_format()"); mi->IsSeekable=mi->file_info.headertype==ADTS && mi->seek_table && mi->seek_table_length>0; mi->LockSeeking=!mi->IsSeekable;/* aac_buffer b; float fLength; DWORD headertype; b.infile=mi->aacFile; b.buffer=mi->buffer; b.bytes_into_buffer=read; b.bytes_consumed=mi->bytes_consumed; b.file_offset=0; b.at_eof=(read!=tmp) ? 1 : 0; GetAACInfos(&b,&headertype,&fLength,&mi->file_info.bitrate,mi->src_size); mi->file_info.bitrate*=1024; mi->file_info.headertype=headertype; mi->bytes_into_buffer=b.bytes_into_buffer; mi->bytes_consumed=b.bytes_consumed; IsSeekable=false; // only mp4 can be seeked*/ if(!mi->FindBitrate) // open a new instance to get info from decoder { MYINPUT *miTmp; Cfaad *NewInst; if(!(NewInst=new Cfaad())) return ERROR_getInfos("Memory allocation error: NewInst"); GLOBALLOCK(miTmp,NewInst->hInput,MYINPUT,return 0); miTmp->FindBitrate=TRUE; NewInst->ShowDlg4RawAAC=ShowDlg4RawAAC; NewInst->pCfg=pCfg; if(!NewInst->getInfos(lpstrFilename)) return ERROR_getInfos(0); mi->Channels=miTmp->frameInfo.channels; if(mi->file_info.headertype==RAW) mi->file_info.bitrate=miTmp->file_info.bitrate;//*mi->Channels; mi->Samprate=miTmp->Samprate; mi->file_info.headertype=miTmp->file_info.headertype; mi->file_info.object_type=miTmp->file_info.object_type; mi->file_info.version=miTmp->file_info.version; GlobalUnlock(NewInst->hInput); delete NewInst; } if(!(mi->hDecoder=faacDecOpen())) return ERROR_getInfos("Can't open library"); if(mi->file_info.headertype==RAW) if(pCfg) setFaadCfg(mi->hDecoder,*pCfg); else setDefaultFaadCfg(mi->hDecoder,mi->FindBitrate); BYTE Channels; // faacDecInit doesn't report correctly the number of channels in raw aac files if((mi->bytes_consumed=faacDecInit(mi->hDecoder, mi->buffer, mi->bytes_into_buffer, &mi->Samprate, &Channels))<0) return ERROR_getInfos("faacDecInit()"); mi->bytes_into_buffer-=mi->bytes_consumed; if(mi->FindBitrate) // get info from decoder { DWORD Samples, BytesConsumed; if(!processData(hInput,0,0)) return ERROR_getInfos(0); Samples=mi->frameInfo.samples/sizeof(short); BytesConsumed=mi->frameInfo.bytesconsumed; if(mi->file_info.headertype==RAW || !mi->file_info.bitrate) mi->file_info.bitrate=(BytesConsumed*8*mi->Samprate)/(Samples*2); if(!mi->file_info.bitrate) return ERROR_getInfos("Can't determine the bitrate"); } mi->len_ms=(DWORD)((mi->src_size<<3)/(mi->file_info.bitrate>>10));// mi->len_ms=(DWORD)((1000*((float)mi->src_size*8))/mi->file_info.bitrate); } if(mi->len_ms) mi->dst_size=(DWORD)(mi->len_ms*((float)mi->Samprate/1000)*mi->Channels*(mi->BitsPerSample/8)); else return ERROR_getInfos("Can't determine the length"); showInfo(mi); GlobalUnlock(hInput); return hInput;}// *********************************************************************************************int Cfaad::processData(HANDLE hInput, unsigned char far *bufout, long lBytes){BYTE *buffer;DWORD BytesDecoded=0;char *sample_buffer=0;int read;MYINPUT *mi; GLOBALLOCK(mi,hInput,MYINPUT,return 0); if(mi->LockSeeking) { NoSeek(); mi->LockSeeking=false; } if(mi->IsMP4) // MP4 file -------------------------------------------------------------------------- { unsigned __int32 buffer_size=0; int rc; if(newpos_ms>-1) { MP4Duration duration=MP4ConvertToTrackDuration(mi->mp4File,mi->track,newpos_ms,MP4_MSECS_TIME_SCALE); MP4SampleId sampleId=MP4GetSampleIdFromTime(mi->mp4File,mi->track,duration,0); mi->bytes_read=(DWORD)(((float)newpos_ms*mi->file_info.bitrate)/(8*1000)); if(seek(mi->bytes_read)) // update the slider return ERROR_processData(0); newpos_ms=-1; } do { buffer=NULL; if(mi->sampleId>=mi->numSamples) return ERROR_processData(0); rc=MP4ReadSample(mi->mp4File, mi->track, mi->sampleId++, (unsigned __int8 **)&buffer, &buffer_size, NULL, NULL, NULL, NULL); if(rc==0 || buffer==NULL) { FREE_ARRAY(buffer); return ERROR_processData("MP4ReadSample()"); } sample_buffer=(char *)faacDecDecode(mi->hDecoder,&mi->frameInfo,buffer,buffer_size); BytesDecoded=mi->frameInfo.samples*sizeof(short); if(BytesDecoded>(DWORD)lBytes) BytesDecoded=lBytes; memmove(bufout,sample_buffer,BytesDecoded); FREE_ARRAY(buffer); // to update the slider mi->bytes_read+=buffer_size; if(seek(mi->bytes_read)) return ERROR_processData(0); }while(!BytesDecoded && !mi->frameInfo.error); } else // AAC file -------------------------------------------------------------------------- { if(newpos_ms>-1) { if(mi->IsSeekable) { DWORD normalized=mi->len_ms/(mi->seek_table_length-1); if(normalized<1000) normalized=1000; mi->bytes_read=mi->seek_table[newpos_ms/normalized]; fseek(mi->aacFile, mi->bytes_read, SEEK_SET); if(seek(mi->bytes_read)) // update the slider return ERROR_processData(0); mi->bytes_into_buffer=0; mi->bytes_consumed=FAAD_STREAMSIZE; } newpos_ms=-1; } buffer=mi->buffer; do { if(mi->bytes_consumed>0) { if(mi->bytes_into_buffer) memmove(buffer,buffer+mi->bytes_consumed,mi->bytes_into_buffer); if(mi->bytes_read<mi->src_size) { int tmp; if(mi->bytes_read+mi->bytes_consumed<mi->src_size) tmp=mi->bytes_consumed; else tmp=mi->src_size-mi->bytes_read; read=fread(buffer+mi->bytes_into_buffer, 1, tmp, mi->aacFile); if(read==tmp) { mi->bytes_read+=read; mi->bytes_into_buffer+=read; } } else if(mi->bytes_into_buffer) memset(buffer+mi->bytes_into_buffer, 0, mi->bytes_consumed); mi->bytes_consumed=0; if( (mi->bytes_into_buffer>3 && !memcmp(mi->buffer, "TAG", 3)) || (mi->bytes_into_buffer>11 && !memcmp(mi->buffer, "LYRICSBEGIN", 11)) || (mi->bytes_into_buffer>8 && !memcmp(mi->buffer, "APETAGEX", 8))) return ERROR_processData(0); } if(mi->bytes_into_buffer<1) if(mi->bytes_read<mi->src_size) return ERROR_processData("Buffer empty!"); else return ERROR_processData(0); sample_buffer=(char *)faacDecDecode(mi->hDecoder,&mi->frameInfo,buffer,mi->bytes_into_buffer); BytesDecoded=mi->frameInfo.samples*sizeof(short); if(bufout) { if(BytesDecoded>(DWORD)lBytes) BytesDecoded=lBytes; if(sample_buffer && BytesDecoded && !mi->frameInfo.error) memmove(bufout,sample_buffer,BytesDecoded); } else // Data needed to decode Raw files { mi->Channels=mi->frameInfo.channels; mi->file_info.object_type=mi->frameInfo.object_type; } mi->bytes_consumed+=mi->frameInfo.bytesconsumed; mi->bytes_into_buffer-=mi->bytes_consumed; }while(!BytesDecoded && !mi->frameInfo.error); } // END AAC file -------------------------------------------------------------------------- if(mi->frameInfo.error) return ERROR_processData((char *)faacDecGetErrorMessage(mi->frameInfo.error)); showProgress(mi); GlobalUnlock(hInput); return BytesDecoded;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -