📄 speexdec.c
字号:
fprintf (stderr, " (stereo"); if (header->vbr) fprintf (stderr, ", VBR)\n"); else fprintf(stderr, ")\n"); /*fprintf (stderr, "Decoding %d Hz audio at %d bps using %s mode\n", *rate, mode->bitrate, mode->modeName);*/ } *extra_headers = header->extra_headers; free(header); return st;}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; void *st=NULL; SpeexBits bits; 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}, {"enh", no_argument, NULL, 0}, {"no-enh", no_argument, NULL, 0}, {"pf", no_argument, NULL, 0}, {"no-pf", no_argument, NULL, 0}, {"force-nb", no_argument, NULL, 0}, {"force-wb", no_argument, NULL, 0}, {"force-uwb", 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; SpeexStereoState stereo = SPEEX_STEREO_STATE_INIT; int channels=-1; int rate=0; int extra_headers; int wav_format=0; 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,"enh")==0) { enh_enabled=1; } else if (strcmp(long_options[option_index].name,"no-enh")==0) { enh_enabled=0; } else if (strcmp(long_options[option_index].name,"pf")==0) { fprintf (stderr, "--pf is deprecated, use --enh instead\n"); enh_enabled=1; } else if (strcmp(long_options[option_index].name,"no-pf")==0) { fprintf (stderr, "--no-pf is deprecated, use --no-enh instead\n"); enh_enabled=0; } else if (strcmp(long_options[option_index].name,"force-nb")==0) { forceMode=0; } else if (strcmp(long_options[option_index].name,"force-wb")==0) { forceMode=1; } else if (strcmp(long_options[option_index].name,"force-uwb")==0) { forceMode=2; } 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); speex_bits_init(&bits); /*Main decoding loop*/ while (1) { char *data; int i, j, 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) { int packet_no; if (stream_init == 0) { ogg_stream_init(&os, ogg_page_serialno(&og)); stream_init = 1; } /*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) { skip_samples = page_nb_packets*frame_size*nframes - (page_granule-last_granule); 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*/ packet_no=0; while (!eos && ogg_stream_packetout(&os, &op)==1) { /*If first packet, process as Speex header*/ if (packet_count==0) { st = process_header(&op, enh_enabled, &frame_size, &rate, &nframes, forceMode, &channels, &stereo, &extra_headers, quiet); if (!nframes) nframes=1; if (!st) exit(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; packet_no++; if (loss_percent>0 && 100*((float)rand())/RAND_MAX<loss_percent) lost=1; /*End of stream condition*/ if (op.e_o_s) eos=1; /*Copy Ogg packet to Speex bitstream*/ speex_bits_read_from(&bits, (char*)op.packet, op.bytes); for (j=0;j!=nframes;j++) { int ret; /*Decode frame*/ if (!lost) ret = speex_decode_int(st, &bits, output); else ret = speex_decode_int(st, NULL, output); /*for (i=0;i<frame_size*channels;i++) printf ("%d\n", (int)output[i]);*/ if (ret==-1) break; if (ret==-2) { fprintf (stderr, "Decoding error: corrupted stream?\n"); break; } if (speex_bits_remaining(&bits)<0) { fprintf (stderr, "Decoding overflow: corrupted stream?\n"); break; } if (channels==2) speex_decode_stereo_int(output, frame_size, &stereo); if (print_bitrate) { int tmp; char ch=13; speex_decoder_ctl(st, SPEEX_GET_BITRATE, &tmp); fputc (ch, stderr); fprintf (stderr, "Bitrate is use: %d bps ", 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);*/ if (packet_no == 1 && j==0 && skip_samples > 0) { /*printf ("chopping first packet\n");*/ new_frame_size -= skip_samples; frame_offset = skip_samples; } if (packet_no == page_nb_packets && skip_samples < 0) { int packet_length = nframes*frame_size+skip_samples; new_frame_size = packet_length - j*frame_size; if (new_frame_size<0) new_frame_size = 0; if (new_frame_size>frame_size) new_frame_size = frame_size; /*printf ("chopping end: %d %d %d\n", new_frame_size, packet_length, packet_no);*/ } if (new_frame_size) { #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 (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) speex_decoder_destroy(st); else { fprintf (stderr, "This doesn't look like a Speex file\n"); } speex_bits_destroy(&bits); 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -