int decodeMP4file(char *sndfile, aac_dec_opt *opt) { int track; unsigned long samplerate; unsigned char channels; void *sample_buffer; mp4ff_t *infile; FILE *mp4File; int sampleId, numSamples; audio_file *aufile; NeAACDecHandle hDecoder; NeAACDecFrameInfo frameInfo; unsigned char *buffer; int buffer_size; int first_time = 1; /* initialise the callback structure */ mp4ff_callback_t *mp4cb = malloc(sizeof(mp4ff_callback_t)); mp4File = fopen(opt->filename, "rb"); mp4cb->read = read_callback; mp4cb->seek = seek_callback; mp4cb->user_data = mp4File; infile = mp4ff_open_read(mp4cb); 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"); mp4ff_close(infile); free(mp4cb); fclose(mp4File); return 1; } buffer = NULL; buffer_size = 0; mp4ff_get_decoder_config(infile, track, &buffer, &buffer_size); hDecoder = NeAACDecOpen(); if(NeAACDecInit2(hDecoder, buffer, buffer_size, &samplerate, &channels) < 0) { /* If some error initializing occured, skip the file */ error_handler("Error initializing decoder library.\n"); NeAACDecClose(hDecoder); mp4ff_close(infile); free(mp4cb); fclose(mp4File); return 1; } if (buffer) free(buffer); numSamples = mp4ff_num_samples(infile, track); 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) { error_handler("Reading from MP4 file failed.\n"); NeAACDecClose(hDecoder); mp4ff_close(infile); free(mp4cb); fclose(mp4File); return 1; } sample_buffer = NeAACDecDecode(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"); NeAACDecClose(hDecoder); mp4ff_close(infile); free(mp4cb); fclose(mp4File); return (0); } } else { aufile = open_audio_file(sndfile, samplerate, frameInfo.channels, opt->output_format, opt->file_type, aacChannelConfig2wavexChannelMask(&frameInfo)); if (aufile == NULL) { NeAACDecClose(hDecoder); mp4ff_close(infile); free(mp4cb); fclose(mp4File); 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", NeAACDecGetErrorMessage(frameInfo.error)); break; } if(stop_decoding) break; } NeAACDecClose(hDecoder); mp4ff_close(infile); free(mp4cb); fclose(mp4File); if(opt->decode_mode == 0) WIN_Audio_close(); else { if (!first_time) close_audio_file(aufile); } return frameInfo.error; }
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 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; }
int main(int argc, char **argv) { int c; int option_index = 0; char *inFile, *outFile; FILE *fin, *fout=NULL; short out[MAX_FRAME_SIZE]; short output[MAX_FRAME_SIZE]; int frame_size=0, granule_frame_size=0; void *st=NULL; CELTMode *mode=NULL; int packet_count=0; int stream_init = 0; int quiet = 0; ogg_int64_t page_granule=0, last_granule=0; int skip_samples=0, page_nb_packets; struct option long_options[] = { {"help", no_argument, NULL, 0}, {"quiet", no_argument, NULL, 0}, {"version", no_argument, NULL, 0}, {"version-short", no_argument, NULL, 0}, {"rate", required_argument, NULL, 0}, {"mono", no_argument, NULL, 0}, {"stereo", no_argument, NULL, 0}, {"packet-loss", required_argument, NULL, 0}, {0, 0, 0, 0} }; ogg_sync_state oy; ogg_page og; ogg_packet op; ogg_stream_state os; int enh_enabled; int nframes=2; int print_bitrate=0; int close_in=0; int eos=0; int forceMode=-1; int audio_size=0; float loss_percent=-1; int channels=-1; int rate=0; int extra_headers=0; int wav_format=0; int lookahead=0; int celt_serialno = -1; int firstpacket = 1; enh_enabled = 1; /*Process options*/ while(1) { c = getopt_long (argc, argv, "hvV", long_options, &option_index); if (c==-1) break; switch(c) { case 0: if (strcmp(long_options[option_index].name,"help")==0) { usage(); exit(0); } else if (strcmp(long_options[option_index].name,"quiet")==0) { quiet = 1; } else if (strcmp(long_options[option_index].name,"version")==0) { version(); exit(0); } else if (strcmp(long_options[option_index].name,"version-short")==0) { version_short(); exit(0); } else if (strcmp(long_options[option_index].name,"mono")==0) { channels=1; } else if (strcmp(long_options[option_index].name,"stereo")==0) { channels=2; } else if (strcmp(long_options[option_index].name,"rate")==0) { rate=atoi (optarg); } else if (strcmp(long_options[option_index].name,"packet-loss")==0) { loss_percent = atof(optarg); } break; case 'h': usage(); exit(0); break; case 'v': version(); exit(0); break; case 'V': print_bitrate=1; break; case '?': usage(); exit(1); break; } } if (argc-optind!=2 && argc-optind!=1) { usage(); exit(1); } inFile=argv[optind]; if (argc-optind==2) outFile=argv[optind+1]; else outFile = ""; wav_format = strlen(outFile)>=4 && ( strcmp(outFile+strlen(outFile)-4,".wav")==0 || strcmp(outFile+strlen(outFile)-4,".WAV")==0); /*Open input file*/ if (strcmp(inFile, "-")==0) { #if defined WIN32 || defined _WIN32 _setmode(_fileno(stdin), _O_BINARY); #endif fin=stdin; } else { fin = fopen(inFile, "rb"); if (!fin) { perror(inFile); exit(1); } close_in=1; } /*Init Ogg data struct*/ ogg_sync_init(&oy); /*Main decoding loop*/ while (1) { char *data; int i, nb_read; /*Get the ogg buffer for writing*/ data = ogg_sync_buffer(&oy, 200); /*Read bitstream from input file*/ nb_read = fread(data, sizeof(char), 200, fin); ogg_sync_wrote(&oy, nb_read); /*Loop for all complete pages we got (most likely only one)*/ while (ogg_sync_pageout(&oy, &og)==1) { if (stream_init == 0) { ogg_stream_init(&os, ogg_page_serialno(&og)); stream_init = 1; } if (ogg_page_serialno(&og) != os.serialno) { /* so all streams are read. */ ogg_stream_reset_serialno(&os, ogg_page_serialno(&og)); } /*Add page to the bitstream*/ ogg_stream_pagein(&os, &og); page_granule = ogg_page_granulepos(&og); page_nb_packets = ogg_page_packets(&og); if (page_granule>0 && frame_size) { /* FIXME: shift the granule values if --force-* is specified */ skip_samples = frame_size*(page_nb_packets*granule_frame_size*nframes - (page_granule-last_granule))/granule_frame_size; if (ogg_page_eos(&og)) skip_samples = -skip_samples; /*else if (!ogg_page_bos(&og)) skip_samples = 0;*/ } else { skip_samples = 0; } /*printf ("page granulepos: %d %d %d\n", skip_samples, page_nb_packets, (int)page_granule);*/ last_granule = page_granule; /*Extract all available packets*/ while (!eos && ogg_stream_packetout(&os, &op) == 1 && op.bytes>=8) { if (!memcmp(op.packet, "CELT ", 8)) { celt_serialno = os.serialno; } if (celt_serialno == -1 || os.serialno != celt_serialno) break; /*If first packet, process as CELT header*/ if (packet_count==0) { st = process_header(&op, enh_enabled, &frame_size, &granule_frame_size, &rate, &nframes, forceMode, &channels, &lookahead, &extra_headers, quiet, &mode); if (!st) exit(1); if (!nframes) nframes=1; fout = out_file_open(outFile, rate, &channels); } else if (packet_count==1) { if (!quiet) print_comments((char*)op.packet, op.bytes); } else if (packet_count<=1+extra_headers) { /* Ignore extra headers */ } else { int lost=0; if (loss_percent>0 && 100*((float)rand())/RAND_MAX<loss_percent) lost=1; /*End of stream condition*/ if (op.e_o_s && os.serialno == celt_serialno) /* don't care for anything except celt eos */ eos=1; { int ret; /*Decode frame*/ if (!lost) ret = celt_decode(st, (unsigned char*)op.packet, op.bytes, output); else ret = celt_decode(st, NULL, 0, output); /*for (i=0;i<frame_size*channels;i++) printf ("%d\n", (int)output[i]);*/ if (ret!=0) { fprintf (stderr, "Decoding error: corrupted stream?\n"); break; } if (print_bitrate) { celt_int32 tmp=op.bytes; char ch=13; fputc (ch, stderr); fprintf (stderr, "Bitrate in use: %d bytes/packet ", tmp); } /*Convert to short and save to output file*/ if (strlen(outFile)!=0) { for (i=0;i<frame_size*channels;i++) out[i]=le_short(output[i]); } else { for (i=0;i<frame_size*channels;i++) out[i]=output[i]; } { int frame_offset = 0; int new_frame_size = frame_size; /*printf ("packet %d %d\n", packet_no, skip_samples);*/ /*fprintf (stderr, "packet %d %d %d\n", packet_no, skip_samples, lookahead);*/ if (firstpacket == 1) { /*printf ("chopping first packet\n");*/ new_frame_size -= lookahead; frame_offset = lookahead; firstpacket = 0; } if (new_frame_size>0) { #if defined WIN32 || defined _WIN32 if (strlen(outFile)==0) WIN_Play_Samples (out+frame_offset*channels, sizeof(short) * new_frame_size*channels); else #endif fwrite(out+frame_offset*channels, sizeof(short), new_frame_size*channels, fout); audio_size+=sizeof(short)*new_frame_size*channels; } } } } packet_count++; } } if (feof(fin)) break; } if (fout && wav_format) { if (fseek(fout,4,SEEK_SET)==0) { int tmp; tmp = le_int(audio_size+36); fwrite(&tmp,4,1,fout); if (fseek(fout,32,SEEK_CUR)==0) { tmp = le_int(audio_size); fwrite(&tmp,4,1,fout); } else { fprintf (stderr, "First seek worked, second didn't\n"); } } else { fprintf (stderr, "Cannot seek on wave file, size will be incorrect\n"); } } if (st) { celt_decoder_destroy(st); celt_mode_destroy(mode); } else { fprintf (stderr, "This doesn't look like a CELT file\n"); } if (stream_init) ogg_stream_clear(&os); ogg_sync_clear(&oy); #if defined WIN32 || defined _WIN32 if (strlen(outFile)==0) WIN_Audio_close (); #endif if (close_in) fclose(fin); if (fout != NULL) fclose(fout); return 0; }
opus_int64 audio_write(float *pcm, int channels, int frame_size, FILE *fout, SpeexResamplerState *resampler, int *skip, shapestate *shapemem, int file, opus_int64 maxout) { opus_int64 sampout=0; int i,ret,tmp_skip; unsigned out_len; short *out; float *buf; float *output; out=alloca(sizeof(short)*MAX_FRAME_SIZE*channels); buf=alloca(sizeof(float)*MAX_FRAME_SIZE*channels); maxout=maxout<0?0:maxout; do { if (skip){ tmp_skip = (*skip>frame_size) ? (int)frame_size : *skip; *skip -= tmp_skip; } else { tmp_skip = 0; } if (resampler){ unsigned in_len; output=buf; in_len = frame_size-tmp_skip; out_len = 1024<maxout?1024:maxout; speex_resampler_process_interleaved_float(resampler, pcm+channels*tmp_skip, &in_len, buf, &out_len); pcm += channels*(in_len+tmp_skip); frame_size -= in_len+tmp_skip; } else { output=pcm+channels*tmp_skip; out_len=frame_size-tmp_skip; frame_size=0; } /*Convert to short and save to output file*/ if (shapemem){ shape_dither_toshort(shapemem,out,output,out_len,channels); }else{ for (i=0;i<(int)out_len*channels;i++) out[i]=(short)float2int(fmaxf(-32768,fminf(output[i]*32768.f,32767))); } if ((le_short(1)!=1)&&file){ for (i=0;i<(int)out_len*channels;i++) out[i]=le_short(out[i]); } if(maxout>0) { #if defined WIN32 || defined _WIN32 if(!file){ ret=WIN_Play_Samples (out, sizeof(short) * channels * (out_len<maxout?out_len:maxout)); if(ret>0)ret/=sizeof(short)*channels; else fprintf(stderr, "Error playing audio.\n"); }else #elif defined HAVE_LIBSNDIO if(!file){ ret=sio_write (hdl, out, sizeof(short) * channels * (out_len<maxout?out_len:maxout)); if(ret>0)ret/=sizeof(short)*channels; else fprintf(stderr, "Error playing audio.\n"); }else #endif ret=fwrite(out, 2*channels, out_len<maxout?out_len:maxout, fout); sampout+=ret; maxout-=ret; } } while (frame_size>0 && maxout>0); return sampout; }