int getsonglength(char *fn) { faadAACInfo tmp; get_AAC_format(fn, &tmp, NULL, NULL, 1); return tmp.length; }
// return handle that will be passed in to close, and write routines HANDLE FAR PASCAL OpenFilterInput(LPSTR lpstrFilename, long far *lSamprate, WORD far *wBitsPerSample, WORD far *wChannels, HWND hWnd, long far *lChunkSize) { HANDLE hInput=NULL; Cfaad tmp; CMyDecCfg cfg(false); if(!*lSamprate && !tmp.IsMP4(lpstrFilename)) { /* aac_buffer b; float fLength; int bitrate; DWORD headertype; tmp.GetAACInfos(lpstrFilename,&b,&headertype,&fLength,&bitrate); if(headertype==RAW) tmp.ShowDlg4RawAAC=ShowDlg4RawAAC;*/ DWORD *seek_table; int seek_table_length; faadAACInfo file_info; if(!get_AAC_format(lpstrFilename, &file_info, &seek_table, &seek_table_length, 0)) if(file_info.headertype==RAW) tmp.ShowDlg4RawAAC=ShowDlg4RawAAC; } if(hInput=tmp.getInfos(lpstrFilename)) { MYINPUT *mi; GLOBALLOCK(mi,hInput,MYINPUT,return NULL); *wChannels=(WORD)mi->Channels; *lSamprate=mi->Samprate; *wBitsPerSample=mi->BitsPerSample; *lChunkSize=(*wBitsPerSample/8)*1024**wChannels*2; GlobalUnlock(hInput); tmp.hInput=NULL; }
BOOL CALLBACK info_dialog_proc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) { faadAACInfo format; char *tmp_string; char info[1024]; LV_COLUMN lvc; BOOL bResult; switch (message) { case WM_INITDIALOG: /* Set up the list control for the ID3 tag */ /* Initialize the LV_COLUMN structure. */ lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvc.fmt = LVCFMT_LEFT; /* Add the columns. */ lvc.iSubItem = 0; lvc.cx = 100; lvc.pszText = "Frame"; ListView_InsertColumn(GetDlgItem(hwndDlg, IDC_ID3LIST), 0, &lvc); lvc.iSubItem = 1; lvc.cx = 250; lvc.pszText = "Data"; ListView_InsertColumn(GetDlgItem(hwndDlg, IDC_ID3LIST), 1, &lvc); /* get AAC info */ get_AAC_format(info_fn, &format, NULL, NULL, 1); switch(format.headertype) { case 0: /* Headerless */ tmp_string = "RAW"; break; case 1: /* ADIF */ tmp_string = "ADIF"; break; case 2: /* ADTS */ tmp_string = "ADTS"; break; } SetDlgItemText(hwndDlg, IDC_HEADER, tmp_string); if (format.object_type == 0 /* Main */) tmp_string = "Main"; else if (format.object_type == 1 /* Low Complexity */) tmp_string = "Low Complexity"; else if (format.object_type == 2 /* SSR */) tmp_string = "SSR (unsupported)"; else if (format.object_type == 3 /* LTP */) tmp_string = "Main LTP"; SetDlgItemText(hwndDlg, IDC_PROFILE, tmp_string); if (format.version == 2) tmp_string = "MPEG2"; else tmp_string = "MPEG4"; SetDlgItemText(hwndDlg, IDC_VERSION, tmp_string); wsprintf(info, "%d bps", format.bitrate); SetDlgItemText(hwndDlg, IDC_BITRATE, info); wsprintf(info, "%d Hz", format.sampling_rate); SetDlgItemText(hwndDlg, IDC_SAMPLERATE, info); wsprintf(info, "%d ch", format.channels); SetDlgItemText(hwndDlg, IDC_CHANNELS, info); FillID3List(hwndDlg, GetDlgItem(hwndDlg, IDC_ID3LIST), info_fn); if (ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_ID3LIST)) == 0) EnableWindow(GetDlgItem(hwndDlg, IDC_ID3V2TAG), FALSE); else EnableCheckbox(GetDlgItem(hwndDlg, IDC_ID3V2TAG), TRUE, TRUE); bFileChanged = FALSE; return TRUE; case WM_NOTIFY: /* Branch depending on the specific notification message. */ switch (((LPNMHDR) lParam)->code) { /* Process LVN_GETDISPINFO to supply information about */ /* callback items. */ case LVN_GETDISPINFO: List_OnGetDispInfo((LV_DISPINFO *)lParam); break; case NM_DBLCLK: bResult = List_EditData(hwndDlg, GetDlgItem(hwndDlg, IDC_ID3LIST)); if (bResult) EnableCheckbox(GetDlgItem(hwndDlg, IDC_ID3V2TAG), TRUE, TRUE); bFileChanged = bFileChanged ? bFileChanged : bResult; break; } return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_ADDSTFRAMES: bResult = List_AddStandardFrames(hwndDlg, GetDlgItem(hwndDlg, IDC_ID3LIST)); if (bResult) EnableCheckbox(GetDlgItem(hwndDlg, IDC_ID3V2TAG), TRUE, TRUE); bFileChanged = bFileChanged ? bFileChanged : bResult; return TRUE; case IDC_ADDFRAME: bResult = List_AddFrame(hwndDlg, GetDlgItem(hwndDlg, IDC_ID3LIST)); if (bResult) EnableCheckbox(GetDlgItem(hwndDlg, IDC_ID3V2TAG), TRUE, TRUE); bFileChanged = bFileChanged ? bFileChanged : bResult; return TRUE; case IDC_DELFRAME: bResult = List_DeleteSelected(hwndDlg, GetDlgItem(hwndDlg, IDC_ID3LIST)); if (ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_ID3LIST)) == 0) EnableCheckbox(GetDlgItem(hwndDlg, IDC_ID3V2TAG), FALSE, FALSE); bFileChanged = bFileChanged ? bFileChanged : bResult; return TRUE; case IDC_EDITFRAME: bResult = List_EditData(hwndDlg, GetDlgItem(hwndDlg, IDC_ID3LIST)); if (bResult) EnableCheckbox(GetDlgItem(hwndDlg, IDC_ID3V2TAG), TRUE, TRUE); bFileChanged = bFileChanged ? bFileChanged : bResult; return TRUE; case IDC_ID3V2TAG: bFileChanged = TRUE; return TRUE; case IDC_CLOSE: case IDCANCEL: if (bFileChanged == TRUE) { if (MessageBox(hwndDlg, "Save changes?", "Save changes", MB_YESNO) == IDYES) List_SaveID3(hwndDlg, GetDlgItem(hwndDlg, IDC_ID3LIST), info_fn); } EndDialog(hwndDlg, wParam); return TRUE; } } return FALSE; }
int play(char *fn) { int maxlatency; int thread_id; current_file_mode = m_memmap_file; if (current_file_mode) { if (play_memmap(fn)) return -1; } else { if (play_file(fn)) return -1; } if(seek_table) { free(seek_table); seek_table = NULL; seek_table_length = 0; } get_AAC_format(fn, &file_info, &seek_table, &seek_table_length, 0); if(infile->http) { /* No seeking in http streams */ mod.is_seekable = 0; } else { if (file_info.headertype == 2) /* ADTS header - seekable */ mod.is_seekable = 1; else mod.is_seekable = 0; /* ADIF or Headerless - not seekable */ } strcpy(lastfn,fn); paused=0; decode_pos_ms=0; seek_needed=-1; /* To RageAmp: This is really needed, because aacinfo isn't very accurate on ADIF files yet. Can be fixed though :-) */ file_info.sampling_rate = samplerate; file_info.channels = frameInfo.channels; maxlatency = mod.outMod->Open(file_info.sampling_rate, file_info.channels, 16, -1,-1); if (maxlatency < 0) // error opening device { return -1; } // initialize vis stuff mod.SAVSAInit(maxlatency, file_info.sampling_rate); mod.VSASetInfo(file_info.sampling_rate, file_info.channels); mod.SetInfo(file_info.bitrate/1000, file_info.sampling_rate/1000, file_info.channels,1); mod.outMod->SetVolume(-666); // set the output plug-ins default volume killPlayThread = 0; if((play_thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) PlayThread, (void *) &killPlayThread, 0, &thread_id)) == NULL) { MessageBox(mod.hMainWindow, "Fatal error: Cannot create playback thread\n", "FAAD Error", MB_OK); return -1; } // Note: This line seriously slows down start up time if(m_priority != 3) // if the priority in config window is set to normal, there is nothing to reset! SetThreadPriority(play_thread_handle, priority_table[m_priority]); return 0; }
int AacPcm::getInfos(MediaInfo *infos) { if(!infos) return 1; if(hDecoder) { SHOW_INFO() return 0; } IsAAC=strcmpi(infos->getFilename()+lstrlen(infos->getFilename())-4,".aac")==0; if(!IsAAC) // MP4 file --------------------------------------------------------------------- { MP4Duration length; unsigned __int32 buffer_size; mp4AudioSpecificConfig mp4ASC; if(!(mp4File=MP4Read(infos->getFilename(), 0))) ERROR_getInfos("Error opening file"); if((track=GetAACTrack(mp4File))<0) ERROR_getInfos(0); //"Unable to find correct AAC sound track"); if(!(hDecoder=faacDecOpen())) ERROR_getInfos("Error initializing decoder library"); MP4GetTrackESConfiguration(mp4File, track, (unsigned __int8 **)&buffer, &buffer_size); if(!buffer) ERROR_getInfos("MP4GetTrackESConfiguration"); AudioSpecificConfig(buffer, buffer_size, &mp4ASC); Channels=mp4ASC.channelsConfiguration; if(faacDecInit2(hDecoder, buffer, buffer_size, &Samplerate, &Channels) < 0) ERROR_getInfos("Error initializing decoder library"); FREE_ARRAY(buffer); length=MP4GetTrackDuration(mp4File, track); len_ms=(DWORD)MP4ConvertFromTrackDuration(mp4File, track, length, MP4_MSECS_TIME_SCALE); file_info.bitrate=MP4GetTrackBitRate(mp4File, track); file_info.version=MP4GetTrackAudioType(mp4File, track)==MP4_MPEG4_AUDIO_TYPE ? 4 : 2; numSamples=MP4GetTrackNumberOfSamples(mp4File, track); sampleId=1; } else // AAC file ------------------------------------------------------------------------------ { DWORD read, tmp; BYTE Channels4Raw=0; if(!(aacFile=fopen(infos->getFilename(),"rb"))) ERROR_getInfos("Error opening file"); // use bufferized stream setvbuf(aacFile,NULL,_IOFBF,32767); // get size of file fseek(aacFile, 0, SEEK_END); src_size=ftell(aacFile); fseek(aacFile, 0, SEEK_SET); if(!(buffer=(BYTE *)malloc(FAAD_STREAMSIZE))) ERROR_getInfos("Memory allocation error: buffer") tmp=src_size<FAAD_STREAMSIZE ? src_size : FAAD_STREAMSIZE; read=fread(buffer, 1, tmp, aacFile); if(read==tmp) { bytes_read=read; bytes_into_buffer=read; } else ERROR_getInfos("Read failed!") if(tagsize=id3v2_tag(buffer)) { if(tagsize>(long)src_size) ERROR_getInfos("Corrupt stream!"); if(tagsize<bytes_into_buffer) { bytes_into_buffer-=tagsize; memcpy(buffer,buffer+tagsize,bytes_into_buffer); } else { bytes_read=tagsize; bytes_into_buffer=0; if(tagsize>bytes_into_buffer) fseek(aacFile, tagsize, SEEK_SET); } if(src_size<bytes_read+FAAD_STREAMSIZE-bytes_into_buffer) tmp=src_size-bytes_read; else tmp=FAAD_STREAMSIZE-bytes_into_buffer; read=fread(buffer+bytes_into_buffer, 1, tmp, aacFile); if(read==tmp) { bytes_read+=read; bytes_into_buffer+=read; } else ERROR_getInfos("Read failed!"); } if(get_AAC_format((char *)infos->getFilename(), &file_info, &seek_table, &seek_table_length, 0)) ERROR_getInfos("get_AAC_format"); IsSeekable=file_info.headertype==ADTS && seek_table && seek_table_length>0; BlockSeeking=!IsSeekable; if(!(hDecoder=faacDecOpen())) ERROR_getInfos("Can't open library"); if(file_info.headertype==RAW) { faacDecConfiguration config; config.defSampleRate=atoi(cfg_samplerate); switch(cfg_profile[1]) { case 'a': config.defObjectType=MAIN; break; case 'o': config.defObjectType=LOW; break; case 'S': config.defObjectType=SSR; break; case 'T': config.defObjectType=LTP; break; } switch(cfg_bps[0]) { case '1': config.outputFormat=FAAD_FMT_16BIT; break; case '2': config.outputFormat=FAAD_FMT_24BIT; break; case '3': config.outputFormat=FAAD_FMT_32BIT; break; case 'F': config.outputFormat=FAAD_FMT_24BIT; break; } faacDecSetConfiguration(hDecoder, &config); if(!FindBitrate) { AacPcm *NewInst; if(!(NewInst=new AacPcm())) ERROR_getInfos("Memory allocation error: NewInst"); NewInst->FindBitrate=TRUE; if(NewInst->getInfos(infos)) ERROR_getInfos(0); Channels4Raw=NewInst->frameInfo.channels; file_info.bitrate=NewInst->file_info.bitrate*Channels4Raw; delete NewInst; } else { DWORD Samples, BytesConsumed; if((bytes_consumed=faacDecInit(hDecoder,buffer,bytes_into_buffer,&Samplerate,&Channels))<0) ERROR_getInfos("Can't init library"); bytes_into_buffer-=bytes_consumed; if(!processData(infos,0,0)) ERROR_getInfos(0); Samples=frameInfo.samples/sizeof(short); BytesConsumed=frameInfo.bytesconsumed; processData(infos,0,0); if(BytesConsumed<frameInfo.bytesconsumed) BytesConsumed=frameInfo.bytesconsumed; file_info.bitrate=(BytesConsumed*8*Samplerate)/Samples; if(!file_info.bitrate) file_info.bitrate=1000; // try to continue decoding return 0; } } if((bytes_consumed=faacDecInit(hDecoder, buffer, bytes_into_buffer, &Samplerate, &Channels))<0) ERROR_getInfos("faacDecInit failed!") bytes_into_buffer-=bytes_consumed; if(Channels4Raw) Channels=Channels4Raw; len_ms=(DWORD)((1000*((float)src_size*8))/file_info.bitrate); } SHOW_INFO(); return 0; }