📄 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 + -