int play_memmap(char *fn) { int tagsize = 0; infile = open_filestream(fn); if (infile == NULL) return 1; fileread = filelength_filestream(infile); memmap_buffer = (char*)LocalAlloc(LPTR, fileread); read_buffer_filestream(infile, memmap_buffer, fileread); /* skip id3v2 tag */ memmap_index = id3v2_tag(memmap_buffer); hDecoder = faacDecOpen(); /* Copy the configuration dialog setting and use it as the default */ /* initialize the decoder, and get samplerate and channel info */ if ((buffercount = faacDecInit(hDecoder, memmap_buffer + memmap_index, fileread - memmap_index - 1, &samplerate, &channels)) < 0) { MessageBox(mod.hMainWindow, "Error opening input file\n", "FAAD Error", MB_OK); return 1; } memmap_index += buffercount; PlayThread_memmap(); return 0; }
int play_file(char *fn) { int k; int tagsize; ZeroMemory(buffer, 768*2); infile = open_filestream(fn); if (infile == NULL) return 1; fileread = filelength_filestream(infile); buffercount = bytecount = 0; read_buffer_filestream(infile, buffer, 768*2); tagsize = id3v2_tag(buffer); /* If we find a tag, run right over it */ if(tagsize) { if(infile->http) { int i; /* Crude way of doing this, but I believe its fast enough to not make a big difference */ close_filestream(infile); infile = open_filestream(fn); for(i=0; i < tagsize; i++) read_byte_filestream(infile); } else { seek_filestream(infile, tagsize, FILE_BEGIN); } bytecount = tagsize; buffercount = 0; read_buffer_filestream(infile, buffer, 768*2); } hDecoder = faacDecOpen(); /* Copy the configuration dialog setting and use it as the default */ /* initialize the decoder, and get samplerate and channel info */ if((buffercount = faacDecInit(hDecoder, buffer, 768*2, &samplerate, &channels)) < 0) { MessageBox(mod.hMainWindow, "Error opening input file\n", "FAAD Error", MB_OK); return 1; } if(buffercount > 0) { bytecount += buffercount; for (k = 0; k < (768*2 - buffercount); k++) buffer[k] = buffer[k + buffercount]; read_buffer_filestream(infile, buffer + (768*2) - buffercount, buffercount); buffercount = 0; } PlayThread_file(); return 0; }
int decodeAACfile(char *sndfile, int def_srate, aac_dec_opt *opt) { int tagsize; unsigned long samplerate; unsigned char channels; void *sample_buffer; FILE *infile; audio_file *aufile; NeAACDecHandle hDecoder; NeAACDecFrameInfo frameInfo; NeAACDecConfigurationPtr config; int first_time = 1; /* declare variables for buffering */ DEC_BUFF_VARS infile = fopen(opt->filename, "rb"); if (infile == NULL) { /* unable to open file */ error_handler("Error opening file: %s\n", opt->filename); return 1; } INIT_BUFF(infile) tagsize = id3v2_tag(buffer); if (tagsize) { UPDATE_BUFF_SKIP(tagsize) } hDecoder = NeAACDecOpen(); /* Set the default object type and samplerate */ /* This is useful for RAW AAC files */ config = NeAACDecGetCurrentConfiguration(hDecoder); if (def_srate) config->defSampleRate = def_srate; config->defObjectType = opt->object_type; config->outputFormat = opt->output_format; NeAACDecSetConfiguration(hDecoder, config); if ((bytesconsumed = NeAACDecInit(hDecoder, buffer, bytes_in_buffer, &samplerate, &channels)) < 0) { /* If some error initializing occured, skip the file */ error_handler("Error initializing decoder library.\n"); END_BUFF NeAACDecClose(hDecoder); fclose(infile); return 1; } buffer_index += bytesconsumed; do { /* update buffer */ UPDATE_BUFF_READ sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, buffer, bytes_in_buffer); /* update buffer indices */ UPDATE_BUFF_IDX(frameInfo) if (frameInfo.error > 0) { error_handler("Error: %s\n", NeAACDecGetErrorMessage(frameInfo.error)); } opt->progress_update((long)fileread, buffer_index); /* open the sound file now that the number of channels are known */ if (first_time && !frameInfo.error) { if(opt->decode_mode == 0) { if (Set_WIN_Params (INVALID_FILEDESC, samplerate, SAMPLE_SIZE, frameInfo.channels) < 0) { error_handler("\nCan't access %s\n", "WAVE OUT"); END_BUFF NeAACDecClose(hDecoder); fclose(infile); return (0); } } else { aufile = open_audio_file(sndfile, samplerate, frameInfo.channels, opt->output_format, opt->file_type, aacChannelConfig2wavexChannelMask(&frameInfo)); if (aufile == NULL) { END_BUFF NeAACDecClose(hDecoder); fclose(infile); return 0; } } first_time = 0; } if ((frameInfo.error == 0) && (frameInfo.samples > 0)) { if(opt->decode_mode == 0) WIN_Play_Samples((short*)sample_buffer, frameInfo.channels*frameInfo.samples); else write_audio_file(aufile, sample_buffer, frameInfo.samples, 0); } if (buffer_index >= fileread) sample_buffer = NULL; /* to make sure it stops now */ if(stop_decoding) break; } while (sample_buffer != NULL); NeAACDecClose(hDecoder); fclose(infile); if(opt->decode_mode == 0) WIN_Audio_close(); else { if (!first_time) close_audio_file(aufile); } END_BUFF return frameInfo.error; }
int main(int argc, char *argv[]) { int k; short sample_buffer[1024*MAX_CHANNELS]; int writeToStdio = 0, out_dir_set = 0; int def_sr_set = 0, use_ltp = 0; int def_srate; int showHelp = 0; char *fnp; int result; int first_time = 1; char out_dir[255]; char aacFileName[255]; char audioFileName[255]; FILE *sndfile; FILE *infile; faacDecHandle hDecoder; faacDecConfigurationPtr config; char percent[200]; long buffercount; unsigned long bytesconsumed, samples, fileread, bytecount; unsigned char *buffer; unsigned long samplerate, channels, tagsize; /* System dependant types */ #ifdef _WIN32 long begin, end; #else clock_t begin; #endif fprintf(stderr, "FAAD (Freeware AAC Decoder) Compiled on: " __DATE__ "\n"); fprintf(stderr, "FAAD homepage: %s\n", "http://www.audiocoding.com"); /* begin process command line */ progName = argv[0]; while (1) { int c = -1; int option_index = 0; static struct option long_options[] = { { "outputdir", 0, 0, 'o' }, { "samplerate", 0, 0, 's' }, { "ltp", 0, 0, 'l' }, { "stdio", 0, 0, 'w' }, { "help", 0, 0, 'h' } }; c = getopt_long(argc, argv, "o:s:whl", long_options, &option_index); if (c == -1) break; switch (c) { case 'o': { if (optarg) { char dr[255]; if (sscanf(optarg, "%s", dr) < 1) { out_dir_set = 0; } else { out_dir_set = 1; strcpy(out_dir, dr); } } else { out_dir_set = 0; } break; } case 's': { if (optarg) { char dr[255]; if (sscanf(optarg, "%s", dr) < 1) { def_sr_set = 0; } else { def_sr_set = 1; def_srate = atoi(dr); } } else { out_dir_set = 0; } break; } case 'w': { writeToStdio = 1; break; } case 'l': { use_ltp = 1; break; } case 'h': { showHelp = 1; break; } default: break; } } /* check that we have at least two non-option arguments */ /* Print help if requested */ if (((argc - optind) < 1) || showHelp) { usage(); return 1; } /* point to the specified file name */ strcpy(aacFileName, argv[optind]); #ifdef _WIN32 begin = GetTickCount(); #else begin = clock(); #endif buffer = (unsigned char*)malloc(768*MAX_CHANNELS); memset(buffer, 0, 768*MAX_CHANNELS); infile = fopen(aacFileName, "rb"); if (infile == NULL) { /* unable to open file */ fprintf(stderr, "Error opening file: %s\n", aacFileName); return 1; } fseek(infile, 0, SEEK_END); fileread = ftell(infile); fseek(infile, 0, SEEK_SET); buffercount = bytecount = 0; fread(buffer, 1, 768*MAX_CHANNELS, infile); tagsize = id3v2_tag(buffer); if (tagsize) { fseek(infile, tagsize, SEEK_SET); bytecount = tagsize; buffercount = 0; fread(buffer, 1, 768*MAX_CHANNELS, infile); } hDecoder = faacDecOpen(); /* Set the default object type and samplerate */ /* This is useful for RAW AAC files */ config = faacDecGetCurrentConfiguration(hDecoder); if (def_sr_set) config->defSampleRate = def_srate; if (use_ltp) config->defObjectType = LTP; faacDecSetConfiguration(hDecoder, config); if((buffercount = faacDecInit(hDecoder, buffer, &samplerate, &channels)) < 0) { /* If some error initializing occured, skip the file */ fprintf(stderr, "Error initializing decoder library.\n"); return 1; } if (buffercount > 0) { bytecount += buffercount; for (k = 0; k < (768*MAX_CHANNELS - buffercount); k++) buffer[k] = buffer[k + buffercount]; fread(buffer + (768*MAX_CHANNELS) - buffercount, 1, buffercount, infile); buffercount = 0; } fprintf(stderr, "Busy decoding %s", aacFileName); if (tagsize) fprintf(stderr, " (has ID3v2)\n"); else fprintf(stderr, "\n"); /* Only calculate the path and open the file for writing if we are not writing to stdout. */ if(!writeToStdio) { if (out_dir_set) combine_path(audioFileName, out_dir, aacFileName); else strcpy(audioFileName, aacFileName); fnp = (char *)strrchr(audioFileName,'.'); if (fnp) fnp[0] = '\0'; strcat(audioFileName, ".wav"); } first_time = 1; do { if (buffercount > 0) { for (k = 0; k < (768*MAX_CHANNELS - buffercount); k++) buffer[k] = buffer[k + buffercount]; fread(buffer + (768*MAX_CHANNELS) - buffercount, 1, buffercount, infile); buffercount = 0; } result = faacDecDecode(hDecoder, buffer, &bytesconsumed, sample_buffer, &samples); if (result == FAAD_FATAL_ERROR) fprintf(stderr, "Fatal error decoding file\n"); if (result == FAAD_ERROR) fprintf(stderr, "Error decoding frame\n"); buffercount += bytesconsumed; bytecount += bytesconsumed; if (bytecount >= fileread) result = 9999; /* to make sure it stops now */ sprintf(percent, "%.2f decoding %s.", min((double)(bytecount*100)/fileread,100), aacFileName); fprintf(stderr, "%s\r", percent); #ifdef _WIN32 SetConsoleTitle(percent); #endif if ((result == FAAD_OK) && (samples > 0)) { if(first_time) { first_time = 0; if(!writeToStdio) { sndfile = fopen(audioFileName, "w+b"); if (sndfile==NULL) { fprintf(stderr, "Unable to create the file << %s >>.\n", audioFileName); continue; } CreateWavHeader(sndfile, channels, samplerate, 16); } else { sndfile = stdout; } } fwrite(sample_buffer, sizeof(short), 1024*channels, sndfile); } } while (result <= FAAD_OK_CHUPDATE); faacDecClose(hDecoder); fclose(infile); if(!writeToStdio) UpdateWavHeader(sndfile); /* Only close if we are not writing to stdout */ if(!writeToStdio) if(sndfile) fclose(sndfile); #ifdef _WIN32 end = GetTickCount(); fprintf(stderr, "Decoding %s took: %d sec.\n", aacFileName, (end-begin)/1000); SetConsoleTitle("FAAD"); #else /* clock() grabs time since the start of the app but when we decode multiple files, each file has its own starttime (begin). */ fprintf(stderr, "Decoding %s took: %5.2f sec.\n", aacFileName, (float)(clock() - begin)/(float)CLOCKS_PER_SEC); #endif if (buffer) free(buffer); 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; }
int fdpl_decode_AAC(int def_srate, const char *file_path, size_t &c, size_t &sr, size_t &samples, std::vector<float> * ch1, std::vector<float> *ch2) { int tagsize; uint32_t samplerate; unsigned char channels; void *sample_buffer; FILE *infile; faacDecHandle hDecoder; faacDecFrameInfo frameInfo; faacDecConfigurationPtr config; /* declare variables for buffering */ DEC_BUFF_VARS infile = fopen(file_path, "rb"); if (infile == NULL) { /* unable to open file */ std::cerr<<"Error opening file"<<std::endl; return 1; } INIT_BUFF(infile) tagsize = id3v2_tag(buffer);//avoids ID3 tag (useful for mp3 as well) if (tagsize) { UPDATE_BUFF_SKIP(tagsize) } hDecoder = faacDecOpen(); /* Set the default object type and samplerate */ /* This is useful for RAW AAC files */ config = faacDecGetCurrentConfiguration(hDecoder); if (def_srate) config->defSampleRate = def_srate; config->defObjectType = LC;//default config->outputFormat = FAAD_FMT_FLOAT; config -> downMatrix = 0; //set to 1 faacDecSetConfiguration(hDecoder, config); if ((bytesconsumed = faacDecInit(hDecoder, buffer, bytes_in_buffer, &samplerate, &channels)) < 0) { /* If some error initializing occured, skip the file */ std::cerr<<"Error initializing decoder library."<<std::endl; END_BUFF faacDecClose(hDecoder); fclose(infile); return 1; } buffer_index += bytesconsumed; do { /* update buffer */ UPDATE_BUFF_READ sample_buffer = faacDecDecode(hDecoder, &frameInfo, buffer, bytes_in_buffer); /* update buffer indices */ UPDATE_BUFF_IDX(frameInfo) if (frameInfo.error > 0) { std::cerr<<"Error: %s\n"<<faacDecGetErrorMessage(frameInfo.error)<<std::endl; } if ((frameInfo.error == 0) && (frameInfo.samples > 0) && (frameInfo.channels < 3)) { size_t samples_channel = (size_t)frameInfo.samples/(size_t)frameInfo.channels; samples += samples_channel; float *pcm; pcm = (float *)sample_buffer; for(size_t i=0; i<samples_channel; i++){ //writing the samples of each channel in separate float vectors for(size_t j=0; j<frameInfo.channels; j++){ if(j==0){ ch1 -> push_back(pcm[i*frameInfo.channels+j]); }else if(j==1){ ch2 -> push_back(pcm[i*frameInfo.channels+j]); }else{ std::cerr<<"Unexpected number of channels: "<<j<<std::endl; return -1; } } } } if (buffer_index >= fileread) sample_buffer = NULL; /* to make sure it stops now */ } while (sample_buffer != NULL); c = frameInfo.channels; sr = frameInfo.samplerate; faacDecClose(hDecoder); fclose(infile); END_BUFF return frameInfo.error; }