int PlayThread_file() { int k; if (buffercount > 0) { for (k = 0; k < (768*2 - buffercount); k++) buffer[k] = buffer[k + buffercount]; read_buffer_filestream(infile, buffer + (768*2) - buffercount, buffercount); buffercount = 0; } sample_buffer = (char*)faacDecDecode(hDecoder, &frameInfo, buffer, 768*2); if (frameInfo.error) { MessageBox(NULL, faacDecGetErrorMessage(frameInfo.error), "FAAD Error", MB_OK); last_frame = 1; } buffercount += frameInfo.bytesconsumed; bytecount += frameInfo.bytesconsumed; if (bytecount >= fileread) last_frame = 1; return frameInfo.bytesconsumed; }
void* NEAACDECAPI mtv_faacDecDecode(NeAACDecFrameInfo *hInfo, uint8_t *buffer, uint32_t buffer_size) { unsigned char *pcm_o; pcm_o = faacDecDecode(faac_hdec, &faac_finfo, buffer, buffer_size); //decode a audio packet *hInfo = faac_finfo; return (void *)pcm_o; }
int AacPcm::processData(MediaInfo *infos, ChunkList *chunk_list, bool *killswitch) { DWORD BytesDecoded=0; char *bufout=0; ChunkInfosI *ci=0; svc_fileReader *reader=0; if(!FindBitrate && !chunk_list) ERROR_processData("chunk_list==NULL"); // is this case possible? if(!(reader=infos->getReader())) ERROR_processData("File doesn\'t exists"); if(chunk_list) { if(!(ci=new ChunkInfosI())) ERROR_processData("Memory allocation error: ci"); ci->addInfo("srate", Samplerate); ci->addInfo("bps", bps); ci->addInfo("nch", Channels); } if(!IsAAC) // MP4 file -------------------------------------------------------------------------- { unsigned __int32 buffer_size=0; int rc; if(newpos_ms>-1) { MP4Duration duration=MP4ConvertToTrackDuration(mp4File,track,newpos_ms,MP4_MSECS_TIME_SCALE); sampleId=MP4GetSampleIdFromTime(mp4File,track,duration,0); bytes_read=(DWORD)(((float)newpos_ms*file_info.bitrate)/(8*1000)); reader->seek(bytes_read); // updates slider newpos_ms=-1; } do { buffer=NULL; if(sampleId>=numSamples) ERROR_processData(0); rc=MP4ReadSample(mp4File, track, sampleId++, (unsigned __int8 **)&buffer, &buffer_size, NULL, NULL, NULL, NULL); if(rc==0 || buffer==NULL) { FREE_ARRAY(buffer); ERROR_processData("MP4ReadSample") } bufout=(char *)faacDecDecode(hDecoder,&frameInfo,buffer,buffer_size); BytesDecoded=frameInfo.samples*sizeof(short); FREE_ARRAY(buffer); // to update the slider bytes_read+=buffer_size; reader->seek(bytes_read); }while(!BytesDecoded && !frameInfo.error);
unsigned int faad_decoder::update(void *dest, unsigned int const num_samples_to_write) { if (!is_initialized()) return 0; unsigned int multiplier = playback_properties_.num_channels * get_sample_size(playback_properties_.sample_type_); faacDecFrameInfo info; while (out_buffer.size() < (num_samples_to_write * multiplier)) { size_t actual_in_size = in_buffer.size(); if (actual_in_size < 32768) { size_t old_in_size = actual_in_size; in_buffer.resize(old_in_size + 32768); long num_read_bytes = source_->read(&in_buffer[old_in_size], 32768); if (num_read_bytes <= 0) break; actual_in_size = old_in_size + num_read_bytes; } void *output_samples = faacDecDecode(*faad_handle, &info, reinterpret_cast < unsigned char* > (&in_buffer[0]), actual_in_size); unsigned int num_remaining_bytes = actual_in_size; num_remaining_bytes -= info.bytesconsumed; std::memmove(&in_buffer[0], &in_buffer[info.bytesconsumed], num_remaining_bytes); in_buffer.resize(num_remaining_bytes); if ((output_samples == 0) || (info.error != 0) || (info.channels == 0)) { initialized = false; break; } if (info.samples > 0) { size_t old_out_size = out_buffer.size(); out_buffer.resize(old_out_size + info.samples * playback_properties_.num_channels); std::memcpy(&out_buffer[old_out_size], output_samples, info.samples * playback_properties_.num_channels); } } size_t num_bytes_to_copy = std::min(size_t(num_samples_to_write * multiplier), out_buffer.size()); std::memcpy(dest, &out_buffer[0], num_bytes_to_copy); if (out_buffer.size() > num_bytes_to_copy) std::memmove(&out_buffer[0], &out_buffer[num_bytes_to_copy], out_buffer.size() - num_bytes_to_copy); out_buffer.resize(out_buffer.size() - num_bytes_to_copy); current_position += num_bytes_to_copy / multiplier; return num_bytes_to_copy / multiplier; }
bool CCoreAACDecoder::Decode(BYTE *pSrc, DWORD SrcLength, BYTE *pDst, DWORD DstLength, DWORD *ActualDstLength) { faacDecFrameInfo frameInfo; short *outsamples = (short *)faacDecDecode(m_decHandle, &frameInfo, pSrc, DstLength); if (frameInfo.error) { NOTE2("CCoreAACDecoder::Decode Error %d [%s]\n", frameInfo.error, faacDecGetErrorMessage(frameInfo.error)); return false; } m_brCalcFrames++; m_DecodedFrames++; m_brBytesConsumed += SrcLength; if(m_brCalcFrames == 43) { m_Bitrate = (int)((m_brBytesConsumed * 8) / (m_DecodedFrames / 43.07)); m_brCalcFrames = 0; } if (!frameInfo.error && outsamples) { int channelidx = frameInfo.channels-1; if(chmap[channelidx][0]) { // dshow remapping short *dstBuffer = (short*)pDst; for(unsigned int i = 0; i < frameInfo.samples; i += frameInfo.channels, outsamples += frameInfo.channels) { for(unsigned int j=1; j <= frameInfo.channels; j++) { *dstBuffer++ = outsamples[chmap[channelidx][j]]; } } } else { memcpy(pDst, outsamples, frameInfo.samples * sizeof(short)); } } else return false; *ActualDstLength = frameInfo.samples * sizeof(short); return true; }
int PlayThread_memmap() { sample_buffer = (char*)faacDecDecode(hDecoder, &frameInfo, memmap_buffer + memmap_index, fileread - memmap_index - 1); if (frameInfo.error) { MessageBox(NULL, faacDecGetErrorMessage(frameInfo.error), "FAAD Error", MB_OK); last_frame = 1; } memmap_index += frameInfo.bytesconsumed; if (memmap_index >= fileread) last_frame = 1; return frameInfo.bytesconsumed; }
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; }
static GF_Err FAAD_ProcessData(GF_MediaDecoder *ifcg, char *inBuffer, u32 inBufferLength, u16 ES_ID, u32 *CTS, char *outBuffer, u32 *outBufferLength, u8 PaddingBits, u32 mmlevel) { void *buffer; unsigned short *conv_in, *conv_out; u32 i, j; FAADCTX(); /*check not using scalabilty*/ if (ctx->ES_ID != ES_ID) return GF_BAD_PARAM; /*if late or seeking don't decode*/ switch (mmlevel) { case GF_CODEC_LEVEL_SEEK: // case GF_CODEC_LEVEL_DROP: *outBufferLength = 0; return GF_OK; default: break; } if (ctx->out_size > *outBufferLength) { *outBufferLength = ctx->out_size; return GF_BUFFER_TOO_SMALL; } GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[FAAD] Decoding AU\n")); buffer = faacDecDecode(ctx->codec, &ctx->info, (unsigned char *) inBuffer, inBufferLength); if (ctx->info.error>0) { GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[FAAD] Error decoding AU %s\n", faacDecGetErrorMessage(ctx->info.error) )); *outBufferLength = 0; //reinit if error FAAD_AttachStream((GF_BaseDecoder *)ifcg, ctx->esd); return GF_NON_COMPLIANT_BITSTREAM; } if (!ctx->info.samples || !buffer || !ctx->info.bytesconsumed) { GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[FAAD] empty/non complete AU\n")); *outBufferLength = 0; return GF_OK; } GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[FAAD] AU decoded\n")); /*FAAD froces us to decode a frame to get channel cfg*/ if (ctx->signal_mc) { s32 ch, idx; ctx->signal_mc = GF_FALSE; idx = 0; /*NOW WATCH OUT!! FAAD may very well decide to output more channels than indicated!!!*/ ctx->num_channels = ctx->info.channels; /*get cfg*/ ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_FRONT_LEFT); if (ch>=0) { ctx->ch_reorder[idx] = ch; idx++; } ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_FRONT_RIGHT); if (ch>=0) { ctx->ch_reorder[idx] = ch; idx++; } ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_FRONT_CENTER); if (ch>=0) { ctx->ch_reorder[idx] = ch; idx++; } ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_LFE); if (ch>=0) { ctx->ch_reorder[idx] = ch; idx++; } ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_BACK_LEFT); if (ch>=0) { ctx->ch_reorder[idx] = ch; idx++; } ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_BACK_RIGHT); if (ch>=0) { ctx->ch_reorder[idx] = ch; idx++; } ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_BACK_CENTER); if (ch>=0) { ctx->ch_reorder[idx] = ch; idx++; } ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_SIDE_LEFT); if (ch>=0) { ctx->ch_reorder[idx] = ch; idx++; } ch = FAAD_GetChannelPos(ctx, GF_AUDIO_CH_SIDE_RIGHT); if (ch>=0) { ctx->ch_reorder[idx] = ch; idx++; } *outBufferLength = ctx->out_size; if (sizeof(short) * ctx->info.samples > *outBufferLength) { *outBufferLength = ctx->out_size = (u32) (sizeof(short)*ctx->info.samples); } return GF_BUFFER_TOO_SMALL; } if (sizeof(short) * ctx->info.samples > *outBufferLength) { *outBufferLength = (u32) (sizeof(short)*ctx->info.samples); return GF_BUFFER_TOO_SMALL; } /*we assume left/right order*/ if (ctx->num_channels<=2) { memcpy(outBuffer, buffer, sizeof(short)* ctx->info.samples); *outBufferLength = (u32) (sizeof(short)*ctx->info.samples); return GF_OK; } conv_in = (unsigned short *) buffer; conv_out = (unsigned short *) outBuffer; for (i=0; i<ctx->info.samples; i+=ctx->info.channels) { for (j=0; j<ctx->info.channels; j++) { conv_out[i + j] = conv_in[i + ctx->ch_reorder[j]]; } } *outBufferLength = (u32) (sizeof(short)*ctx->info.samples); return GF_OK; }
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; }
static gint xmms_faad_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len, xmms_error_t *err) { xmms_faad_data_t *data; xmms_error_t error; faacDecFrameInfo frameInfo; gpointer sample_buffer; guint size, bytes_read = 0; data = xmms_xform_private_data_get (xform); g_return_val_if_fail (data, -1); size = MIN (data->outbuf->len, len); while (size == 0) { gboolean need_read; /* MP4 demuxer always gives full packets so we need different handling */ if (data->filetype == FAAD_TYPE_MP4) need_read = (data->buffer_length == 0); else need_read = (data->buffer_length < data->buffer_size); if (need_read) { bytes_read = xmms_xform_read (xform, (gchar *) data->buffer + data->buffer_length, data->buffer_size - data->buffer_length, &error); if (bytes_read <= 0 && data->buffer_length == 0) { XMMS_DBG ("EOF"); return 0; } data->buffer_length += bytes_read; } sample_buffer = faacDecDecode (data->decoder, &frameInfo, data->buffer, data->buffer_length); g_memmove (data->buffer, data->buffer + frameInfo.bytesconsumed, data->buffer_length - frameInfo.bytesconsumed); data->buffer_length -= frameInfo.bytesconsumed; bytes_read = frameInfo.samples * xmms_sample_size_get (data->sampleformat); if (bytes_read > 0 && frameInfo.error == 0) { gint32 temp, toskip = 0; if (data->samplerate != frameInfo.samplerate || data->channels != frameInfo.channels) { /* We should inform output to change parameters somehow */ XMMS_DBG ("Output format changed in the middle of a read!"); data->samplerate = frameInfo.samplerate; data->channels = frameInfo.channels; } if (xmms_xform_auxdata_get_int (xform, "frame_offset", &temp)) { toskip = (temp * frameInfo.channels * xmms_sample_size_get (data->sampleformat)); } if (xmms_xform_auxdata_get_int (xform, "frame_duration", &temp)) { bytes_read = (temp * frameInfo.channels * xmms_sample_size_get (data->sampleformat)); } g_string_append_len (data->outbuf, sample_buffer + toskip, bytes_read - toskip); } else if (frameInfo.error > 0) { XMMS_DBG ("ERROR %d in faad decoding: %s", frameInfo.error, faacDecGetErrorMessage (frameInfo.error)); return -1; } size = MIN (data->outbuf->len, len); } memcpy (buf, data->outbuf->str, size); g_string_erase (data->outbuf, 0, size); return size; }
uint8_t ADM_faad::run(uint8_t *inptr, uint32_t nbIn, float *outptr, uint32_t *nbOut) { uint32_t xin; long int res; void *outbuf; faacDecFrameInfo info; int max=0; #ifdef OLD_FAAD_PROTO unsigned long int srate; #else uint32_t srate; #endif unsigned char chan=0; uint8_t first=0; ADM_assert(_instance); *nbOut=0; if(!_inited) // we still have'nt initialized the codec { // Try printf("Trying with %d bytes\n",nbIn); res=faacDecInit(_instance,inptr,nbIn,&srate,&chan); if(res>=0) { printf("Faad Inited : rate:%d chan:%d off:%ld\n",srate,chan,res); _inited=1; first=1; _inbuffer=0; inptr+=res; nbIn-=res; } } if(!_inited) { printf("No dice...\n"); return 1; } // The codec is initialized, feed him do { max=FAAD_BUFFER-_inbuffer; if(nbIn<max) max=nbIn; memcpy(_buffer+_inbuffer,inptr,max); inptr+=max; nbIn-=max; _inbuffer+=max; /* if(_inbuffer<FAAD_MIN_STREAMSIZE*2) { return 1; }*/ memset(&info,0,sizeof(info)); //printf("%x %x\n",_buffer[0],_buffer[1]); outbuf = faacDecDecode(_instance, &info, _buffer, _inbuffer); if(info.error) { printf("Faad: Error %d :%s\n",info.error, faacDecGetErrorMessage(info.error)); printf("Bye consumed %u, bytes dropped %u \n",info.bytesconsumed,_inbuffer); _inbuffer=0; // Purge buffer return 1; } if(first) { printf("Channels : %d\n",info.channels); printf("Frequency: %d\n",info.samplerate); printf("SBR : %d\n",info.sbr); } xin=info.bytesconsumed ; if(xin>_inbuffer) xin=0; memmove(_buffer,_buffer+xin,_inbuffer-xin); _inbuffer-=xin; if(info.samples) { *nbOut+= info.samples; int16_t *in = (int16_t *) outbuf; for (int i = 0; i < info.samples; i++) { *(outptr++) = (float)*in / 32768; in++; } } }while(nbIn); return 1; }
int fdpl_decode_MP4(const char *file_path, size_t &ch, size_t &sr, size_t &samples, std::vector<float> *ch1, std::vector<float> *ch2) { unsigned int track; uint32_t samplerate;//these for init, we prefer to take the ones at frameInfo unsigned char channels; void *sample_buffer; mp4ff_t *infile; FILE *mp4File; int sampleId, numSamples; faacDecHandle hDecoder; faacDecFrameInfo frameInfo; unsigned char *buffer; unsigned int buffer_size; /* initialise the callback structure */ mp4ff_callback_t *mp4cb; mp4cb = (mp4ff_callback_t *)malloc(sizeof(mp4ff_callback_t)); mp4File = fopen(file_path, "rb"); mp4cb->read = read_callback; mp4cb->seek = seek_callback; mp4cb->user_data = mp4File; infile = mp4ff_open_read(mp4cb); if (!infile) { /* unable to open file */ std::cerr<<"Error opening file "<< file_path <<std::endl; return 1; } if ((track = GetAACTrack(infile)) < 0) { std::cerr<<"Unable to find correct AAC sound track in the MP4 file"<<std::endl; mp4ff_close(infile); free(mp4cb); fclose(mp4File); return 1; } buffer = NULL; buffer_size = 0; mp4ff_get_decoder_config(infile, track, &buffer, &buffer_size); hDecoder = faacDecOpen(); if(faacDecInit2(hDecoder, buffer, buffer_size, &samplerate, &channels) < 0) { /* If some error initializing occured, skip the file */ std::cerr<<"Error initializing decoder library"<<std::endl; faacDecClose(hDecoder); mp4ff_close(infile); free(mp4cb); fclose(mp4File); return 1; } if (buffer) free(buffer); numSamples = mp4ff_num_samples(infile, track); samples = 0; //firstTime = 1; for (sampleId = 0; sampleId < numSamples; sampleId++) { int rc; /* get access unit from MP4 file */ buffer = NULL; buffer_size = 0; rc = mp4ff_read_sample(infile, track, sampleId, &buffer, &buffer_size); if (rc == 0) { std::cerr<<"error while decoding"<<std::endl; faacDecClose(hDecoder); mp4ff_close(infile); free(mp4cb); fclose(mp4File); return 1; } sample_buffer = faacDecDecode(hDecoder, &frameInfo, buffer, buffer_size); if (buffer) free(buffer); 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 (frameInfo.error > 0) { std::cerr<<"error: "<<faacDecGetErrorMessage(frameInfo.error)<<std::endl; break; } } ch = frameInfo.channels; sr = frameInfo.samplerate; faacDecClose(hDecoder); mp4ff_close(infile); free(mp4cb); fclose(mp4File); return frameInfo.error; }
/* * Decode task call for FAAC */ static int aac_decode (codec_data_t *ptr, uint64_t ts, int from_rtp, int *sync_frame, uint8_t *buffer, uint32_t buflen, void *userdata) { aac_codec_t *aac = (aac_codec_t *)ptr; unsigned long bytes_consummed; int bits = -1; // struct timezone tz; if (aac->m_record_sync_time) { aac->m_current_frame = 0; aac->m_record_sync_time = 0; aac->m_current_time = ts; aac->m_last_rtp_ts = ts; } else { if (aac->m_last_rtp_ts == ts) { aac->m_current_time += aac->m_msec_per_frame; aac->m_current_frame++; } else { aac->m_last_rtp_ts = ts; aac->m_current_time = ts; aac->m_current_frame = 0; } // Note - here m_current_time should pretty much always be >= rtpts. // If we're not, we most likely want to stop and resync. We don't // need to keep decoding - just decode this frame and indicate we // need a resync... That should handle fast forwards... We need // someway to handle reverses - perhaps if we're more than .5 seconds // later... } if (aac->m_faad_inited == 0) { /* * If not initialized, do so. */ abort(); unsigned long freq; unsigned char chans; faacDecInit(aac->m_info, (unsigned char *)buffer, buflen, &freq, &chans); aac->m_freq = freq; aac->m_chans = chans; aac->m_faad_inited = 1; } uint8_t *buff; unsigned long samples; bytes_consummed = buflen; //aa_message(LOG_DEBUG, aaclib, "decoding %d bits", buflen * 8); faacDecFrameInfo frame_info; buff = (uint8_t *)faacDecDecode(aac->m_info, &frame_info, buffer, buflen); if (buff != NULL) { bytes_consummed = frame_info.bytesconsumed; #if 0 aa_message(LOG_DEBUG, aaclib, LLU" bytes %d samples %d", ts, bytes_consummed, frame_info.samples); #endif if (aac->m_audio_inited != 0) { int tempchans = frame_info.channels; if (tempchans != aac->m_chans) { aa_message(LOG_NOTICE, aaclib, "chupdate - chans from data is %d", tempchans); } } else { int tempchans = frame_info.channels; if (tempchans == 0) { aa_message(LOG_ERR, aaclib, "initializing aac, returned channels are 0"); aac->m_resync_with_header = 1; aac->m_record_sync_time = 1; return bytes_consummed; } aac->m_chans = tempchans; aac->m_freq = frame_info.samplerate; aac->m_vft->audio_configure(aac->m_ifptr, aac->m_freq, aac->m_chans, AUDIO_S16SYS, aac->m_output_frame_size); uint8_t *now = aac->m_vft->audio_get_buffer(aac->m_ifptr); aac->m_audio_inited = 1; } /* * good result - give it to audio sync class */ #if DUMP_OUTPUT_TO_FILE fwrite(buff, aac->m_output_frame_size * 4, 1, aac->m_outfile); #endif if (frame_info.samples != 0) { aac->m_vft->audio_load_buffer(aac->m_ifptr, buff, frame_info.samples * 2, aac->m_last_ts, aac->m_resync_with_header); if (aac->m_resync_with_header == 1) { aac->m_resync_with_header = 0; #ifdef DEBUG_SYNC aa_message(LOG_DEBUG, aaclib, "Back to good at "LLU, aac->m_current_time); #endif } } } else { aa_message(LOG_ERR, aaclib, "error return is %d", frame_info.error); aac->m_resync_with_header = 1; #ifdef DEBUG_SYNC aa_message(LOG_ERR, aaclib, "Audio decode problem - at "LLU, aac->m_current_time); #endif } aac->m_last_ts = aac->m_current_time; return (bytes_consummed); }
/***************************************************************************** * DecodeBlock: *****************************************************************************/ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) { decoder_sys_t *p_sys = p_dec->p_sys; block_t *p_block; if( !pp_block || !*pp_block ) return NULL; p_block = *pp_block; if( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) { block_Release( p_block ); return NULL; } /* Remove ADTS header if we have decoder specific config */ if( p_dec->fmt_in.i_extra && p_block->i_buffer > 7 ) { if( p_block->p_buffer[0] == 0xff && ( p_block->p_buffer[1] & 0xf0 ) == 0xf0 ) /* syncword */ { /* ADTS header present */ size_t i_header_size; /* 7 bytes (+ 2 bytes for crc) */ i_header_size = 7 + ( ( p_block->p_buffer[1] & 0x01 ) ? 0 : 2 ); /* FIXME: multiple blocks per frame */ if( p_block->i_buffer > i_header_size ) { vlc_memcpy( p_block->p_buffer, p_block->p_buffer + i_header_size, p_block->i_buffer - i_header_size ); p_block->i_buffer -= i_header_size; } } } /* Append the block to the temporary buffer */ if( p_sys->i_buffer_size < p_sys->i_buffer + p_block->i_buffer ) { p_sys->i_buffer_size = p_sys->i_buffer + p_block->i_buffer; p_sys->p_buffer = realloc( p_sys->p_buffer, p_sys->i_buffer_size ); } if( p_block->i_buffer > 0 ) { vlc_memcpy( &p_sys->p_buffer[p_sys->i_buffer], p_block->p_buffer, p_block->i_buffer ); p_sys->i_buffer += p_block->i_buffer; p_block->i_buffer = 0; } if( p_dec->fmt_out.audio.i_rate == 0 && p_dec->fmt_in.i_extra > 0 ) { /* We have a decoder config so init the handle */ unsigned long i_rate; unsigned char i_channels; if( faacDecInit2( p_sys->hfaad, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra, &i_rate, &i_channels ) >= 0 ) { p_dec->fmt_out.audio.i_rate = i_rate; p_dec->fmt_out.audio.i_channels = i_channels; p_dec->fmt_out.audio.i_physical_channels = p_dec->fmt_out.audio.i_original_channels = pi_channels_guessed[i_channels]; aout_DateInit( &p_sys->date, i_rate ); } } if( p_dec->fmt_out.audio.i_rate == 0 && p_sys->i_buffer ) { unsigned long i_rate; unsigned char i_channels; /* Init faad with the first frame */ if( faacDecInit( p_sys->hfaad, p_sys->p_buffer, p_sys->i_buffer, &i_rate, &i_channels ) < 0 ) { block_Release( p_block ); return NULL; } p_dec->fmt_out.audio.i_rate = i_rate; p_dec->fmt_out.audio.i_channels = i_channels; p_dec->fmt_out.audio.i_physical_channels = p_dec->fmt_out.audio.i_original_channels = pi_channels_guessed[i_channels]; aout_DateInit( &p_sys->date, i_rate ); } if( p_block->i_pts != 0 && p_block->i_pts != aout_DateGet( &p_sys->date ) ) { aout_DateSet( &p_sys->date, p_block->i_pts ); } else if( !aout_DateGet( &p_sys->date ) ) { /* We've just started the stream, wait for the first PTS. */ block_Release( p_block ); p_sys->i_buffer = 0; return NULL; } /* Decode all data */ if( p_sys->i_buffer ) { void *samples; faacDecFrameInfo frame; aout_buffer_t *p_out; int i, j; samples = faacDecDecode( p_sys->hfaad, &frame, p_sys->p_buffer, p_sys->i_buffer ); if( frame.error > 0 ) { msg_Warn( p_dec, "%s", faacDecGetErrorMessage( frame.error ) ); /* Flush the buffer */ p_sys->i_buffer = 0; block_Release( p_block ); return NULL; } if( frame.channels <= 0 || frame.channels > 8 || frame.channels == 7 ) { msg_Warn( p_dec, "invalid channels count: %i", frame.channels ); /* Flush the buffer */ p_sys->i_buffer -= frame.bytesconsumed; if( p_sys->i_buffer > 0 ) { memmove( p_sys->p_buffer,&p_sys->p_buffer[frame.bytesconsumed], p_sys->i_buffer ); } block_Release( p_block ); return NULL; } if( frame.samples <= 0 ) { msg_Warn( p_dec, "decoded zero sample" ); /* Flush the buffer */ p_sys->i_buffer -= frame.bytesconsumed; if( p_sys->i_buffer > 0 ) { memmove( p_sys->p_buffer,&p_sys->p_buffer[frame.bytesconsumed], p_sys->i_buffer ); } block_Release( p_block ); return NULL; } /* We decoded a valid frame */ if( p_dec->fmt_out.audio.i_rate != frame.samplerate ) { aout_DateInit( &p_sys->date, frame.samplerate ); aout_DateSet( &p_sys->date, p_block->i_pts ); } p_block->i_pts = 0; /* PTS is valid only once */ p_dec->fmt_out.audio.i_rate = frame.samplerate; p_dec->fmt_out.audio.i_channels = frame.channels; p_dec->fmt_out.audio.i_physical_channels = p_dec->fmt_out.audio.i_original_channels = pi_channels_guessed[frame.channels]; /* Adjust stream info when dealing with SBR/PS */ if( p_sys->b_sbr != frame.sbr || p_sys->b_ps != frame.ps ) { const char *psz_ext = (frame.sbr && frame.ps) ? "SBR+PS" : frame.sbr ? "SBR" : "PS"; msg_Dbg( p_dec, "AAC %s (channels: %u, samplerate: %lu)", psz_ext, frame.channels, frame.samplerate ); if( !p_dec->p_description ) p_dec->p_description = vlc_meta_New(); if( p_dec->p_description ) vlc_meta_AddExtra( p_dec->p_description, _("AAC extension"), psz_ext ); p_sys->b_sbr = frame.sbr; p_sys->b_ps = frame.ps; } /* Convert frame.channel_position to our own channel values */ p_dec->fmt_out.audio.i_physical_channels = 0; for( i = 0; i < frame.channels; i++ ) { /* Find the channel code */ for( j = 0; j < MAX_CHANNEL_POSITIONS; j++ ) { if( frame.channel_position[i] == pi_channels_in[j] ) break; } if( j >= MAX_CHANNEL_POSITIONS ) { msg_Warn( p_dec, "unknown channel ordering" ); /* Invent something */ j = i; } /* */ p_sys->pi_channel_positions[i] = pi_channels_out[j]; if( p_dec->fmt_out.audio.i_physical_channels & pi_channels_out[j] ) frame.channels--; /* We loose a duplicated channel */ else p_dec->fmt_out.audio.i_physical_channels |= pi_channels_out[j]; } p_dec->fmt_out.audio.i_original_channels = p_dec->fmt_out.audio.i_physical_channels; p_out = decoder_NewAudioBuffer(p_dec, frame.samples/frame.channels); if( p_out == NULL ) { p_sys->i_buffer = 0; block_Release( p_block ); return NULL; } p_out->start_date = aout_DateGet( &p_sys->date ); p_out->end_date = aout_DateIncrement( &p_sys->date, frame.samples / frame.channels ); DoReordering( (uint32_t *)p_out->p_buffer, samples, frame.samples / frame.channels, frame.channels, p_sys->pi_channel_positions ); p_sys->i_buffer -= frame.bytesconsumed; if( p_sys->i_buffer > 0 ) { memmove( p_sys->p_buffer, &p_sys->p_buffer[frame.bytesconsumed], p_sys->i_buffer ); } return p_out; } block_Release( p_block ); return NULL; }
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; faacDecHandle hDecoder; faacDecFrameInfo frameInfo; faacDecConfigurationPtr 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 = 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 = opt->object_type; config->outputFormat = opt->output_format; faacDecSetConfiguration(hDecoder, config); if ((bytesconsumed = faacDecInit(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 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) { error_handler("Error: %s\n", faacDecGetErrorMessage(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 faacDecClose(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 faacDecClose(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); faacDecClose(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 AacPcm::processData(MediaInfo *infos, ChunkList *chunk_list, bool *killswitch) { DWORD read, tmp, shorts_decoded=0; long result=0; ChunkInfosI *ci = new ChunkInfosI(); ci->addInfo("srate", dwSamprate); ci->addInfo("bps", 16); ci->addInfo("nch", dwChannels); if(bytes_into_buffer<0) ERROR_processData(0); svc_fileReader *reader = infos->getReader(); if(!reader) ERROR_processData("File doesn\'t exists"); do { if(bytes_consumed>0 && bytes_into_buffer>=0) { if(bytes_into_buffer) memcpy(buffer,buffer+bytes_consumed,bytes_into_buffer); if(bytes_read<lSize) { if(bytes_read+bytes_consumed<lSize) tmp=bytes_consumed; else tmp=lSize-bytes_read; read=reader->read((char *)buffer+bytes_into_buffer, tmp); if(read==tmp) { bytes_read+=read; bytes_into_buffer+=read; } else infos->status("Read failed!"); // continue until bytes_into_buffer<1 } else if(bytes_into_buffer) memset(buffer+bytes_into_buffer, 0, bytes_consumed); } if(bytes_into_buffer<1) if(bytes_read<lSize) ERROR_processData("Buffer empty!") else return 0; result=faacDecDecode(hDecoder, buffer, &bytes_consumed, (short*)bufout, &shorts_decoded); bytes_into_buffer-=bytes_consumed; }while(!shorts_decoded || result==FAAD_OK_CHUPDATE); if(result==FAAD_FATAL_ERROR || result==FAAD_ERROR) ERROR_processData("FAAD_FATAL_ERROR or FAAD_ERROR"); shorts_decoded*=sizeof(short); chunk_list->setChunk("PCM", bufout, shorts_decoded, ci); // fwrite(bufout,1,bytesDec,fil); if(!shorts_decoded) ERROR_processData(0); return 1; }
/* * Decode task call for FAAC */ static int aac_decode (codec_data_t *ptr, frame_timestamp_t *ts, int from_rtp, int *sync_frame, uint8_t *buffer, uint32_t buflen, void *userdata) { aac_codec_t *aac = (aac_codec_t *)ptr; unsigned long bytes_consummed; int bits = -1; // struct timezone tz; uint32_t freq_timestamp; freq_timestamp = ts->audio_freq_timestamp; if (ts->audio_freq != aac->m_freq) { freq_timestamp = convert_timescale(freq_timestamp, ts->audio_freq, aac->m_freq); } if (aac->m_record_sync_time) { aac->m_current_frame = 0; aac->m_record_sync_time = 0; aac->m_current_time = ts->msec_timestamp; aac->m_last_rtp_ts = ts->msec_timestamp; } else { if (aac->m_last_rtp_ts == ts->msec_timestamp) { aac->m_current_frame++; aac->m_current_time = aac->m_last_rtp_ts; aac->m_current_time += aac->m_output_frame_size * aac->m_current_frame * TO_U64(1000) / aac->m_freq; freq_timestamp += aac->m_output_frame_size * aac->m_current_frame; } else { aac->m_last_rtp_ts = ts->msec_timestamp; aac->m_current_time = ts->msec_timestamp; aac->m_current_frame = 0; } // Note - here m_current_time should pretty much always be >= rtpts. // If we're not, we most likely want to stop and resync. We don't // need to keep decoding - just decode this frame and indicate we // need a resync... That should handle fast forwards... We need // someway to handle reverses - perhaps if we're more than .5 seconds // later... } if (aac->m_faad_inited == 0) { /* * If not initialized, do so. */ unsigned long freq, chans; faacDecInit(aac->m_info, (unsigned char *)buffer, &freq, &chans); aac->m_freq = freq; aac->m_chans = chans; aac->m_faad_inited = 1; } uint8_t *buff; /* * Get an audio buffer */ if (aac->m_audio_inited == 0) { buff = aac->m_temp_buff; } else { buff = aac->m_vft->audio_get_buffer(aac->m_ifptr, freq_timestamp, aac->m_current_time); } if (buff == NULL) { //player_debug_message("Can't get buffer in aa"); return (0); } unsigned long samples; bytes_consummed = buflen; //aa_message(LOG_DEBUG, aaclib, "decoding %d bits", buflen * 8); bits = faacDecDecode(aac->m_info, (unsigned char *)buffer, &bytes_consummed, (short *)buff, &samples); switch (bits) { case FAAD_OK_CHUPDATE: if (aac->m_audio_inited != 0) { int tempchans = faacDecGetProgConfig(aac->m_info, NULL); if (tempchans != aac->m_chans) { aa_message(LOG_NOTICE, aaclib, "chupdate - chans from data is %d", tempchans); } } // fall through... case FAAD_OK: if (aac->m_audio_inited == 0) { int tempchans = faacDecGetProgConfig(aac->m_info, NULL); if (tempchans == 0) { aac->m_resync_with_header = 1; aac->m_record_sync_time = 1; return bytes_consummed; } if (tempchans != aac->m_chans) { aa_message(LOG_NOTICE, aaclib, "chans from data is %d conf %d", tempchans, aac->m_chans); aac->m_chans = tempchans; } aac->m_vft->audio_configure(aac->m_ifptr, aac->m_freq, aac->m_chans, AUDIO_FMT_S16, aac->m_output_frame_size); uint8_t *now = aac->m_vft->audio_get_buffer(aac->m_ifptr, freq_timestamp, aac->m_current_time); if (now != NULL) { memcpy(now, buff, tempchans * aac->m_output_frame_size * sizeof(int16_t)); } aac->m_audio_inited = 1; } /* * good result - give it to audio sync class */ #if DUMP_OUTPUT_TO_FILE fwrite(buff, aac->m_output_frame_size * 4, 1, aac->m_outfile); #endif aac->m_vft->audio_filled_buffer(aac->m_ifptr); if (aac->m_resync_with_header == 1) { aac->m_resync_with_header = 0; #ifdef DEBUG_SYNC aa_message(LOG_DEBUG, aaclib, "Back to good at "U64, aac->m_current_time); #endif } break; default: aa_message(LOG_ERR, aaclib, "Bits return is %d", bits); aac->m_resync_with_header = 1; #ifdef DEBUG_SYNC aa_message(LOG_ERR, aaclib, "Audio decode problem - at "U64, aac->m_current_time); #endif break; } return (bytes_consummed); }
static void *mp4Decode(void *args) { MP4FileHandle mp4file; pthread_mutex_lock(&mutex); seekPosition = -1; bPlaying = TRUE; if(!(mp4file = MP4Read(args, 0))){ mp4cfg.file_type = FILE_AAC; MP4Close(mp4file); }else{ mp4cfg.file_type = FILE_MP4; } if(mp4cfg.file_type == FILE_MP4){ // We are reading a MP4 file gint mp4track; if((mp4track = getAACTrack(mp4file)) < 0){ //TODO: check here for others Audio format..... g_print("Unsupported Audio track type\n"); g_free(args); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); }else{ faacDecHandle decoder; unsigned char *buffer = NULL; guint bufferSize = 0; gulong samplerate; guchar channels; guint avgBitrate; MP4Duration duration; gulong msDuration; MP4SampleId numSamples; MP4SampleId sampleID = 1; decoder = faacDecOpen(); MP4GetTrackESConfiguration(mp4file, mp4track, &buffer, &bufferSize); if(!buffer){ g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } if(faacDecInit2(decoder, buffer, bufferSize, &samplerate, &channels)<0){ g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } g_free(buffer); if(channels == 0){ g_print("Number of Channels not supported\n"); g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } duration = MP4GetTrackDuration(mp4file, mp4track); msDuration = MP4ConvertFromTrackDuration(mp4file, mp4track, duration, MP4_MSECS_TIME_SCALE); numSamples = MP4GetTrackNumberOfSamples(mp4file, mp4track); mp4_ip.output->open_audio(FMT_S16_NE, samplerate, channels); mp4_ip.output->flush(0); mp4_ip.set_info(args, msDuration, -1, samplerate/1000, channels); g_print("MP4 - %d channels @ %d Hz\n", channels, samplerate); while(bPlaying){ void* sampleBuffer; faacDecFrameInfo frameInfo; gint rc; if(seekPosition!=-1){ duration = MP4ConvertToTrackDuration(mp4file, mp4track, seekPosition*1000, MP4_MSECS_TIME_SCALE); sampleID = MP4GetSampleIdFromTime(mp4file, mp4track, duration, 0); mp4_ip.output->flush(seekPosition*1000); seekPosition = -1; } buffer=NULL; bufferSize=0; if(sampleID > numSamples){ mp4_ip.output->close_audio(); g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } rc = MP4ReadSample(mp4file, mp4track, sampleID++, &buffer, &bufferSize, NULL, NULL, NULL, NULL); //g_print("%d/%d\n", sampleID-1, numSamples); if((rc==0) || (buffer== NULL)){ g_print("MP4: read error\n"); sampleBuffer = NULL; sampleID=0; mp4_ip.output->buffer_free(); mp4_ip.output->close_audio(); g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); }else{ sampleBuffer = faacDecDecode(decoder, &frameInfo, buffer, bufferSize); if(frameInfo.error > 0){ g_print("MP4: %s\n", faacDecGetErrorMessage(frameInfo.error)); mp4_ip.output->close_audio(); g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } if(buffer){ g_free(buffer); buffer=NULL; bufferSize=0; } while(bPlaying && mp4_ip.output->buffer_free()<frameInfo.samples<<1) xmms_usleep(30000); } mp4_ip.add_vis_pcm(mp4_ip.output->written_time(), FMT_S16_NE, channels, frameInfo.samples<<1, sampleBuffer); mp4_ip.output->write_audio(sampleBuffer, frameInfo.samples<<1); } while(bPlaying && mp4_ip.output->buffer_free()){ xmms_usleep(10000); } mp4_ip.output->close_audio(); g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } } else{ // WE ARE READING AN AAC FILE FILE *file = NULL; faacDecHandle decoder = 0; guchar *buffer = 0; gulong bufferconsumed = 0; gulong samplerate = 0; guchar channels; gulong buffervalid = 0; TitleInput* input; gchar *temp = g_strdup(args); gchar *ext = strrchr(temp, '.'); gchar *xmmstitle = NULL; faacDecConfigurationPtr config; if((file = fopen(args, "rb")) == 0){ g_print("AAC: can't find file %s\n", args); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } if((decoder = faacDecOpen()) == NULL){ g_print("AAC: Open Decoder Error\n"); fclose(file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } config = faacDecGetCurrentConfiguration(decoder); config->useOldADTSFormat = 0; faacDecSetConfiguration(decoder, config); if((buffer = g_malloc(BUFFER_SIZE)) == NULL){ g_print("AAC: error g_malloc\n"); fclose(file); bPlaying = FALSE; faacDecClose(decoder); pthread_mutex_unlock(&mutex); pthread_exit(NULL); } if((buffervalid = fread(buffer, 1, BUFFER_SIZE, file))==0){ g_print("AAC: Error reading file\n"); g_free(buffer); fclose(file); bPlaying = FALSE; faacDecClose(decoder); pthread_mutex_unlock(&mutex); pthread_exit(NULL); } XMMS_NEW_TITLEINPUT(input); input->file_name = g_basename(temp); input->file_ext = ext ? ext+1 : NULL; input->file_path = temp; if(!strncmp(buffer, "ID3", 3)){ gint size = 0; fseek(file, 0, SEEK_SET); size = (buffer[6]<<21) | (buffer[7]<<14) | (buffer[8]<<7) | buffer[9]; size+=10; fread(buffer, 1, size, file); buffervalid = fread(buffer, 1, BUFFER_SIZE, file); } xmmstitle = xmms_get_titlestring(xmms_get_gentitle_format(), input); if(xmmstitle == NULL) xmmstitle = g_strdup(input->file_name); if(temp) g_free(temp); if(input->performer) g_free(input->performer); if(input->album_name) g_free(input->album_name); if(input->track_name) g_free(input->track_name); if(input->genre) g_free(input->genre); g_free(input); bufferconsumed = faacDecInit(decoder, buffer, buffervalid, &samplerate, &channels); if(mp4_ip.output->open_audio(FMT_S16_NE,samplerate,channels) == FALSE){ g_print("AAC: Output Error\n"); g_free(buffer); buffer=0; faacDecClose(decoder); fclose(file); mp4_ip.output->close_audio(); /* if(positionTable){ g_free(positionTable); positionTable=0; } */ g_free(xmmstitle); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } //if(bSeek){ //mp4_ip.set_info(xmmstitle, lenght*1000, -1, samplerate, channels); //}else{ mp4_ip.set_info(xmmstitle, -1, -1, samplerate, channels); //} mp4_ip.output->flush(0); while(bPlaying && buffervalid > 0){ faacDecFrameInfo finfo; unsigned long samplesdecoded; char* sample_buffer = NULL; /* if(bSeek && seekPosition!=-1){ fseek(file, positionTable[seekPosition], SEEK_SET); bufferconsumed=0; buffervalid = fread(buffer, 1, BUFFER_SIZE, file); aac_ip.output->flush(seekPosition*1000); seekPosition=-1; } */ if(bufferconsumed > 0){ memmove(buffer, &buffer[bufferconsumed], buffervalid-bufferconsumed); buffervalid -= bufferconsumed; buffervalid += fread(&buffer[buffervalid], 1, BUFFER_SIZE-buffervalid, file); bufferconsumed = 0; } sample_buffer = faacDecDecode(decoder, &finfo, buffer, buffervalid); if(finfo.error){ config = faacDecGetCurrentConfiguration(decoder); if(config->useOldADTSFormat != 1){ faacDecClose(decoder); decoder = faacDecOpen(); config = faacDecGetCurrentConfiguration(decoder); config->useOldADTSFormat = 1; faacDecSetConfiguration(decoder, config); finfo.bytesconsumed=0; finfo.samples = 0; faacDecInit(decoder, buffer, buffervalid, &samplerate, &channels); }else{ g_print("FAAD2 Warning %s\n", faacDecGetErrorMessage(finfo.error)); buffervalid = 0; } } bufferconsumed += finfo.bytesconsumed; samplesdecoded = finfo.samples; if((samplesdecoded<=0) && !sample_buffer){ g_print("AAC: error sample decoding\n"); continue; } while(bPlaying && mp4_ip.output->buffer_free() < (samplesdecoded<<1)){ xmms_usleep(10000); } mp4_ip.add_vis_pcm(mp4_ip.output->written_time(), FMT_S16_LE, channels, samplesdecoded<<1, sample_buffer); mp4_ip.output->write_audio(sample_buffer, samplesdecoded<<1); } while(bPlaying && mp4_ip.output->buffer_playing()){ xmms_usleep(10000); } mp4_ip.output->buffer_free(); mp4_ip.output->close_audio(); bPlaying = FALSE; g_free(buffer); faacDecClose(decoder); g_free(xmmstitle); fclose(file); seekPosition = -1; /* if(positionTable){ g_free(positionTable); positionTable=0; } */ bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } }
static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen) { int j = 0, len = 0, last_dec_len = 1, errors = 0; void *faac_sample_buffer; while(len < minlen && last_dec_len > 0 && errors < MAX_FAAD_ERRORS) { /* update buffer for raw aac streams: */ if(!sh->codecdata_len) if(sh->a_in_buffer_len < sh->a_in_buffer_size){ sh->a_in_buffer_len += demux_read_data(sh->ds,&sh->a_in_buffer[sh->a_in_buffer_len], sh->a_in_buffer_size - sh->a_in_buffer_len); } #ifdef DUMP_AAC_COMPRESSED {int i; for (i = 0; i < 16; i++) printf ("%02X ", sh->a_in_buffer[i]); printf ("\n");} #endif if(!sh->codecdata_len){ // raw aac stream: do { faac_sample_buffer = faacDecDecode(faac_hdec, &faac_finfo, sh->a_in_buffer, sh->a_in_buffer_len); /* update buffer index after faacDecDecode */ if(faac_finfo.bytesconsumed >= sh->a_in_buffer_len) { sh->a_in_buffer_len=0; } else { sh->a_in_buffer_len-=faac_finfo.bytesconsumed; memmove(sh->a_in_buffer,&sh->a_in_buffer[faac_finfo.bytesconsumed],sh->a_in_buffer_len); } if(faac_finfo.error > 0) { mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: error: %s, trying to resync!\n", faacDecGetErrorMessage(faac_finfo.error)); if (sh->a_in_buffer_len <= 0) { errors = MAX_FAAD_ERRORS; break; } sh->a_in_buffer_len--; memmove(sh->a_in_buffer,&sh->a_in_buffer[1],sh->a_in_buffer_len); aac_sync(sh); errors++; } else break; } while(errors < MAX_FAAD_ERRORS); } else { // packetized (.mp4) aac stream: unsigned char* bufptr=NULL; double pts; int buflen=ds_get_packet_pts(sh->ds, &bufptr, &pts); if(buflen<=0) break; if (pts != MP_NOPTS_VALUE) { sh->pts = pts; sh->pts_bytes = 0; } faac_sample_buffer = faacDecDecode(faac_hdec, &faac_finfo, bufptr, buflen); } //for (j=0;j<faac_finfo.channels;j++) printf("%d:%d\n", j, faac_finfo.channel_position[j]); if(faac_finfo.error > 0) { mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: Failed to decode frame: %s \n", faacDecGetErrorMessage(faac_finfo.error)); } else if (faac_finfo.samples == 0) { mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"FAAD: Decoded zero samples!\n"); } else { /* XXX: samples already multiplied by channels! */ mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"FAAD: Successfully decoded frame (%ld Bytes)!\n", sh->samplesize*faac_finfo.samples); memcpy(buf+len,faac_sample_buffer, sh->samplesize*faac_finfo.samples); last_dec_len = sh->samplesize*faac_finfo.samples; len += last_dec_len; sh->pts_bytes += last_dec_len; //printf("FAAD: buffer: %d bytes consumed: %d \n", k, faac_finfo.bytesconsumed); } } return len; }
/***************************************************************************** * DecodeBlock: *****************************************************************************/ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) { decoder_sys_t *p_sys = p_dec->p_sys; block_t *p_block; if( !pp_block || !*pp_block ) return NULL; p_block = *pp_block; if( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) { block_Release( p_block ); return NULL; } /* Remove ADTS header if we have decoder specific config */ if( p_dec->fmt_in.i_extra && p_block->i_buffer > 7 ) { if( p_block->p_buffer[0] == 0xff && ( p_block->p_buffer[1] & 0xf0 ) == 0xf0 ) /* syncword */ { /* ADTS header present */ size_t i_header_size; /* 7 bytes (+ 2 bytes for crc) */ i_header_size = 7 + ( ( p_block->p_buffer[1] & 0x01 ) ? 0 : 2 ); /* FIXME: multiple blocks per frame */ if( p_block->i_buffer > i_header_size ) { p_block->p_buffer += i_header_size; p_block->i_buffer -= i_header_size; } } } /* Append the block to the temporary buffer */ if( p_sys->i_buffer_size < p_sys->i_buffer + p_block->i_buffer ) { size_t i_buffer_size = p_sys->i_buffer + p_block->i_buffer; uint8_t *p_buffer = realloc( p_sys->p_buffer, i_buffer_size ); if( p_buffer ) { p_sys->i_buffer_size = i_buffer_size; p_sys->p_buffer = p_buffer; } else { p_block->i_buffer = 0; } } if( p_block->i_buffer > 0 ) { memcpy( &p_sys->p_buffer[p_sys->i_buffer], p_block->p_buffer, p_block->i_buffer ); p_sys->i_buffer += p_block->i_buffer; p_block->i_buffer = 0; } if( p_dec->fmt_out.audio.i_rate == 0 && p_dec->fmt_in.i_extra > 0 ) { /* We have a decoder config so init the handle */ unsigned long i_rate; unsigned char i_channels; if( faacDecInit2( p_sys->hfaad, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra, &i_rate, &i_channels ) >= 0 ) { p_dec->fmt_out.audio.i_rate = i_rate; p_dec->fmt_out.audio.i_channels = i_channels; p_dec->fmt_out.audio.i_physical_channels = p_dec->fmt_out.audio.i_original_channels = pi_channels_guessed[i_channels]; date_Init( &p_sys->date, i_rate, 1 ); } } if( p_dec->fmt_out.audio.i_rate == 0 && p_sys->i_buffer ) { unsigned long i_rate; unsigned char i_channels; /* Init faad with the first frame */ if( faacDecInit( p_sys->hfaad, p_sys->p_buffer, p_sys->i_buffer, &i_rate, &i_channels ) < 0 ) { block_Release( p_block ); return NULL; } p_dec->fmt_out.audio.i_rate = i_rate; p_dec->fmt_out.audio.i_channels = i_channels; p_dec->fmt_out.audio.i_physical_channels = p_dec->fmt_out.audio.i_original_channels = pi_channels_guessed[i_channels]; date_Init( &p_sys->date, i_rate, 1 ); } if( p_block->i_pts > VLC_TS_INVALID && p_block->i_pts != date_Get( &p_sys->date ) ) { date_Set( &p_sys->date, p_block->i_pts ); } else if( !date_Get( &p_sys->date ) ) { /* We've just started the stream, wait for the first PTS. */ block_Release( p_block ); p_sys->i_buffer = 0; return NULL; } /* Decode all data */ if( p_sys->i_buffer ) { void *samples; faacDecFrameInfo frame; block_t *p_out; samples = faacDecDecode( p_sys->hfaad, &frame, p_sys->p_buffer, p_sys->i_buffer ); if( frame.error > 0 ) { msg_Warn( p_dec, "%s", faacDecGetErrorMessage( frame.error ) ); if( frame.error == 21 || frame.error == 12 ) { /* * Once an "Unexpected channel configuration change" * or a "Invalid number of channels" error * occurs, it will occurs afterwards, and we got no sound. * Reinitialization of the decoder is required. */ unsigned long i_rate; unsigned char i_channels; faacDecHandle *hfaad; faacDecConfiguration *cfg,*oldcfg; oldcfg = faacDecGetCurrentConfiguration( p_sys->hfaad ); hfaad = faacDecOpen(); cfg = faacDecGetCurrentConfiguration( hfaad ); if( oldcfg->defSampleRate ) cfg->defSampleRate = oldcfg->defSampleRate; cfg->defObjectType = oldcfg->defObjectType; cfg->outputFormat = oldcfg->outputFormat; faacDecSetConfiguration( hfaad, cfg ); if( faacDecInit( hfaad, p_sys->p_buffer, p_sys->i_buffer, &i_rate,&i_channels ) < 0 ) { /* reinitialization failed */ faacDecClose( hfaad ); faacDecSetConfiguration( p_sys->hfaad, oldcfg ); } else { faacDecClose( p_sys->hfaad ); p_sys->hfaad = hfaad; p_dec->fmt_out.audio.i_rate = i_rate; p_dec->fmt_out.audio.i_channels = i_channels; p_dec->fmt_out.audio.i_physical_channels = p_dec->fmt_out.audio.i_original_channels = pi_channels_guessed[i_channels]; date_Init( &p_sys->date, i_rate, 1 ); } } /* Flush the buffer */ p_sys->i_buffer = 0; block_Release( p_block ); return NULL; } if( frame.channels <= 0 || frame.channels > 8 || frame.channels == 7 ) { msg_Warn( p_dec, "invalid channels count: %i", frame.channels ); /* Flush the buffer */ p_sys->i_buffer -= frame.bytesconsumed; if( p_sys->i_buffer > 0 ) { memmove( p_sys->p_buffer,&p_sys->p_buffer[frame.bytesconsumed], p_sys->i_buffer ); } block_Release( p_block ); return NULL; } if( frame.samples <= 0 ) { msg_Warn( p_dec, "decoded zero sample" ); /* Flush the buffer */ p_sys->i_buffer -= frame.bytesconsumed; if( p_sys->i_buffer > 0 ) { memmove( p_sys->p_buffer,&p_sys->p_buffer[frame.bytesconsumed], p_sys->i_buffer ); } block_Release( p_block ); return NULL; } /* We decoded a valid frame */ if( p_dec->fmt_out.audio.i_rate != frame.samplerate ) { date_Init( &p_sys->date, frame.samplerate, 1 ); date_Set( &p_sys->date, p_block->i_pts ); } p_block->i_pts = VLC_TS_INVALID; /* PTS is valid only once */ p_dec->fmt_out.audio.i_rate = frame.samplerate; p_dec->fmt_out.audio.i_channels = frame.channels; /* Adjust stream info when dealing with SBR/PS */ bool b_sbr = (frame.sbr == 1) || (frame.sbr == 2); if( p_sys->b_sbr != b_sbr || p_sys->b_ps != frame.ps ) { const char *psz_ext = (b_sbr && frame.ps) ? "SBR+PS" : b_sbr ? "SBR" : "PS"; msg_Dbg( p_dec, "AAC %s (channels: %u, samplerate: %lu)", psz_ext, frame.channels, frame.samplerate ); if( !p_dec->p_description ) p_dec->p_description = vlc_meta_New(); if( p_dec->p_description ) vlc_meta_AddExtra( p_dec->p_description, _("AAC extension"), psz_ext ); p_sys->b_sbr = b_sbr; p_sys->b_ps = frame.ps; } /* Convert frame.channel_position to our own channel values */ p_dec->fmt_out.audio.i_physical_channels = 0; const uint32_t nbChannels = frame.channels; unsigned j; for( unsigned i = 0; i < nbChannels; i++ ) { /* Find the channel code */ for( j = 0; j < MAX_CHANNEL_POSITIONS; j++ ) { if( frame.channel_position[i] == pi_channels_in[j] ) break; } if( j >= MAX_CHANNEL_POSITIONS ) { msg_Warn( p_dec, "unknown channel ordering" ); /* Invent something */ j = i; } /* */ p_sys->pi_channel_positions[i] = pi_channels_out[j]; if( p_dec->fmt_out.audio.i_physical_channels & pi_channels_out[j] ) frame.channels--; /* We loose a duplicated channel */ else p_dec->fmt_out.audio.i_physical_channels |= pi_channels_out[j]; } if ( nbChannels != frame.channels ) { p_dec->fmt_out.audio.i_physical_channels = p_dec->fmt_out.audio.i_original_channels = pi_channels_guessed[nbChannels]; } else { p_dec->fmt_out.audio.i_original_channels = p_dec->fmt_out.audio.i_physical_channels; } p_dec->fmt_out.audio.i_channels = nbChannels; p_out = decoder_NewAudioBuffer( p_dec, frame.samples / nbChannels ); if( p_out == NULL ) { p_sys->i_buffer = 0; block_Release( p_block ); return NULL; } p_out->i_pts = date_Get( &p_sys->date ); p_out->i_length = date_Increment( &p_sys->date, frame.samples / nbChannels ) - p_out->i_pts; DoReordering( (uint32_t *)p_out->p_buffer, samples, frame.samples / nbChannels, nbChannels, p_sys->pi_channel_positions ); p_sys->i_buffer -= frame.bytesconsumed; if( p_sys->i_buffer > 0 ) { memmove( p_sys->p_buffer, &p_sys->p_buffer[frame.bytesconsumed], p_sys->i_buffer ); } return p_out; } block_Release( p_block ); return NULL; }
int decodeMP4file(char *sndfile, aac_dec_opt *opt) { int track; unsigned long samplerate; unsigned char channels; void *sample_buffer; MP4FileHandle infile; MP4SampleId sampleId, numSamples; audio_file *aufile; faacDecHandle hDecoder; faacDecFrameInfo frameInfo; unsigned char *buffer; int buffer_size; int first_time = 1; hDecoder = faacDecOpen(); infile = MP4Read(opt->filename, 0); if (!infile) { /* unable to open file */ error_handler("Error opening file: %s\n", opt->filename); return 1; } if ((track = GetAACTrack(infile)) < 0) { error_handler("Unable to find correct AAC sound track in the MP4 file.\n"); MP4Close(infile); return 1; } buffer = NULL; buffer_size = 0; MP4GetTrackESConfiguration(infile, track, &buffer, &buffer_size); if(faacDecInit2(hDecoder, buffer, buffer_size, &samplerate, &channels) < 0) { /* If some error initializing occured, skip the file */ error_handler("Error initializing decoder library.\n"); faacDecClose(hDecoder); MP4Close(infile); return 1; } if (buffer) free(buffer); numSamples = MP4GetTrackNumberOfSamples(infile, track); for (sampleId = 1; sampleId <= numSamples; sampleId++) { int rc; /* get access unit from MP4 file */ buffer = NULL; buffer_size = 0; rc = MP4ReadSample(infile, track, sampleId, &buffer, &buffer_size, NULL, NULL, NULL, NULL); if (rc == 0) { error_handler("Reading from MP4 file failed.\n"); faacDecClose(hDecoder); MP4Close(infile); return 1; } sample_buffer = faacDecDecode(hDecoder, &frameInfo, buffer, buffer_size); if (buffer) free(buffer); opt->progress_update((long)numSamples, sampleId); /* 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"); faacDecClose(hDecoder); MP4Close(infile); return (0); } } else { aufile = open_audio_file(sndfile, samplerate, frameInfo.channels, opt->output_format, opt->file_type, aacChannelConfig2wavexChannelMask(&frameInfo)); if (aufile == NULL) { faacDecClose(hDecoder); MP4Close(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 (frameInfo.error > 0) { error_handler("Error: %s\n", faacDecGetErrorMessage(frameInfo.error)); break; } if(stop_decoding) break; } faacDecClose(hDecoder); MP4Close(infile); if(opt->decode_mode == 0) WIN_Audio_close(); else { if (!first_time) close_audio_file(aufile); } return frameInfo.error; }
uint8_t ADM_faad::run( uint8_t * ptr, uint32_t nbIn, uint8_t * outptr, uint32_t * nbOut,ADM_ChannelMatrix *matrix) { long int res; void *outbuf; faacDecFrameInfo info; int max=0; #ifdef OLD_FAAD_PROTO unsigned long int srate; #else uint32_t srate; #endif unsigned char chan=0; uint8_t first=0; ADM_assert(_instance); *nbOut=0; if(!_inited) // we still have'nt initialized the codec { // Try printf("Trying with %d bytes\n",nbIn); res=faacDecInit(_instance,ptr,nbIn,&srate,&chan); if(res>=0) { printf("Faad Inited : rate:%d chan:%d off:%ld\n",srate,chan,res); _inited=1; first=1; _inbuffer=0; ptr+=res; nbIn-=res; } } if(!_inited) { printf("No dice...\n"); return 1; } // The codec is initialized, feed him do { max=FAAD_BUFFER-_inbuffer; if(nbIn<max) max=nbIn; memcpy(_buffer+_inbuffer,ptr,max); ptr+=max; nbIn-=max; _inbuffer+=max; /* if(_inbuffer<FAAD_MIN_STREAMSIZE*2) { return 1; }*/ memset(&info,0,sizeof(info)); //printf("%x %x\n",_buffer[0],_buffer[1]); outbuf = faacDecDecode(_instance, &info, _buffer, _inbuffer); if(info.error) { printf("Faad: Error %d :%s\n",info.error, faacDecGetErrorMessage(info.error)); /* xin=info.bytesconsumed ; if(!xin) xin=1; memmove(_buffer,_buffer+xin,_inbuffer-xin); _inbuffer-=xin; return 1;*/ return 0; } if(first) { printf("Channels : %d\n",info.channels); printf("Frequency: %d\n",info.samplerate); printf("SBR : %d\n",info.sbr); } xin=info.bytesconsumed ; if(xin>_inbuffer) xin=0; xout=info.samples*2; //printf("in:%d out:%d\n",xin,xout); memmove(_buffer,_buffer+xin,_inbuffer-xin); _inbuffer-=xin; if(xout) { memcpy(outptr,outbuf,xout); *nbOut+=xout; outptr+=xout; } }while(nbIn); return 1; }