Recognizes if input is ogg or not.
[xiph/unicode.git] / speex / src / speexdec.c
blob24a62d4eea8b52e5fe0ce54ad13d00fe136243fe
1 /* Copyright (C) 2002-2006 Jean-Marc Valin
2 File: speexdec.c
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
15 - Neither the name of the Xiph.org Foundation nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #ifdef HAVE_CONFIG_H
33 # include "config.h"
34 #endif
36 #include <stdio.h>
37 #if !defined WIN32 && !defined _WIN32
38 #include <unistd.h>
39 #endif
40 #ifdef HAVE_GETOPT_H
41 #include <getopt.h>
42 #endif
43 #ifndef HAVE_GETOPT_LONG
44 #include "getopt_win.h"
45 #endif
46 #include <stdlib.h>
47 #include <string.h>
49 #include <speex/speex.h>
50 #include <ogg/ogg.h>
52 #if defined WIN32 || defined _WIN32
53 #include "wave_out.h"
54 /* We need the following two to set stdout to binary */
55 #include <io.h>
56 #include <fcntl.h>
57 #endif
58 #include <math.h>
60 #ifdef __MINGW32__
61 #include "wave_out.c"
62 #endif
64 #ifdef HAVE_SYS_SOUNDCARD_H
65 #include <sys/soundcard.h>
66 #include <sys/types.h>
67 #include <sys/stat.h>
68 #include <fcntl.h>
69 #include <sys/ioctl.h>
71 #elif defined HAVE_SYS_AUDIOIO_H
72 #include <sys/types.h>
73 #include <fcntl.h>
74 #include <sys/ioctl.h>
75 #include <sys/audioio.h>
76 #ifndef AUDIO_ENCODING_SLINEAR
77 #define AUDIO_ENCODING_SLINEAR AUDIO_ENCODING_LINEAR /* Solaris */
78 #endif
80 #endif
82 #include <string.h>
83 #include "wav_io.h"
84 #include <speex/speex_header.h>
85 #include <speex/speex_stereo.h>
86 #include <speex/speex_callbacks.h>
88 #define MAX_FRAME_SIZE 2000
90 #define readint(buf, base) (((buf[base+3]<<24)&0xff000000)| \
91 ((buf[base+2]<<16)&0xff0000)| \
92 ((buf[base+1]<<8)&0xff00)| \
93 (buf[base]&0xff))
95 static void print_comments(char *comments, int length)
97 char *c=comments;
98 int len, i, nb_fields;
99 char *end;
101 if (length<8)
103 fprintf (stderr, "Invalid/corrupted comments\n");
104 return;
106 end = c+length;
107 len=readint(c, 0);
108 c+=4;
109 if (len < 0 || c+len>end)
111 fprintf (stderr, "Invalid/corrupted comments\n");
112 return;
114 fwrite(c, 1, len, stderr);
115 c+=len;
116 fprintf (stderr, "\n");
117 if (c+4>end)
119 fprintf (stderr, "Invalid/corrupted comments\n");
120 return;
122 nb_fields=readint(c, 0);
123 c+=4;
124 for (i=0;i<nb_fields;i++)
126 if (c+4>end)
128 fprintf (stderr, "Invalid/corrupted comments\n");
129 return;
131 len=readint(c, 0);
132 c+=4;
133 if (len < 0 || c+len>end)
135 fprintf (stderr, "Invalid/corrupted comments\n");
136 return;
138 fwrite(c, 1, len, stderr);
139 c+=len;
140 fprintf (stderr, "\n");
144 FILE *out_file_open(char *outFile, int rate, int *channels)
146 FILE *fout=NULL;
147 /*Open output file*/
148 if (strlen(outFile)==0)
150 #if defined HAVE_SYS_SOUNDCARD_H
151 int audio_fd, format, stereo;
152 audio_fd=open("/dev/dsp", O_WRONLY);
153 if (audio_fd<0)
155 perror("Cannot open /dev/dsp");
156 exit(1);
159 format=AFMT_S16_NE;
160 if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format)==-1)
162 perror("SNDCTL_DSP_SETFMT");
163 close(audio_fd);
164 exit(1);
167 stereo=0;
168 if (*channels==2)
169 stereo=1;
170 if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo)==-1)
172 perror("SNDCTL_DSP_STEREO");
173 close(audio_fd);
174 exit(1);
176 if (stereo!=0)
178 if (*channels==1)
179 fprintf (stderr, "Cannot set mono mode, will decode in stereo\n");
180 *channels=2;
183 if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate)==-1)
185 perror("SNDCTL_DSP_SPEED");
186 close(audio_fd);
187 exit(1);
189 fout = fdopen(audio_fd, "w");
190 #elif defined HAVE_SYS_AUDIOIO_H
191 audio_info_t info;
192 int audio_fd;
194 audio_fd = open("/dev/audio", O_WRONLY);
195 if (audio_fd<0)
197 perror("Cannot open /dev/audio");
198 exit(1);
201 AUDIO_INITINFO(&info);
202 #ifdef AUMODE_PLAY /* NetBSD/OpenBSD */
203 info.mode = AUMODE_PLAY;
204 #endif
205 info.play.encoding = AUDIO_ENCODING_SLINEAR;
206 info.play.precision = 16;
207 info.play.sample_rate = rate;
208 info.play.channels = *channels;
210 if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0)
212 perror ("AUDIO_SETINFO");
213 exit(1);
215 fout = fdopen(audio_fd, "w");
216 #elif defined WIN32 || defined _WIN32
218 unsigned int speex_channels = *channels;
219 if (Set_WIN_Params (INVALID_FILEDESC, rate, SAMPLE_SIZE, speex_channels))
221 fprintf (stderr, "Can't access %s\n", "WAVE OUT");
222 exit(1);
225 #else
226 fprintf (stderr, "No soundcard support\n");
227 exit(1);
228 #endif
229 } else {
230 if (strcmp(outFile,"-")==0)
232 #if defined WIN32 || defined _WIN32
233 _setmode(_fileno(stdout), _O_BINARY);
234 #elif defined OS2
235 _fsetmode(stdout,"b");
236 #endif
237 fout=stdout;
239 else
241 fout = fopen(outFile, "wb");
242 if (!fout)
244 perror(outFile);
245 exit(1);
247 if (strcmp(outFile+strlen(outFile)-4,".wav")==0 || strcmp(outFile+strlen(outFile)-4,".WAV")==0)
248 write_wav_header(fout, rate, *channels, 0, 0);
251 return fout;
254 void usage()
256 printf ("Usage: speexdec [options] input_file.spx [output_file]\n");
257 printf ("\n");
258 printf ("Decodes a Speex file and produce a WAV file or raw file\n");
259 printf ("\n");
260 printf ("input_file can be:\n");
261 printf (" filename.spx regular Speex file\n");
262 printf (" - stdin\n");
263 printf ("\n");
264 printf ("output_file can be:\n");
265 printf (" filename.wav Wav file\n");
266 printf (" filename.* Raw PCM file (any extension other that .wav)\n");
267 printf (" - stdout\n");
268 printf (" (nothing) Will be played to soundcard\n");
269 printf ("\n");
270 printf ("Options:\n");
271 printf (" --enh Enable perceptual enhancement (default)\n");
272 printf (" --no-enh Disable perceptual enhancement\n");
273 printf (" --force-nb Force decoding in narrowband\n");
274 printf (" --force-wb Force decoding in wideband\n");
275 printf (" --force-uwb Force decoding in ultra-wideband\n");
276 printf (" --mono Force decoding in mono\n");
277 printf (" --stereo Force decoding in stereo\n");
278 printf (" --rate n Force decoding at sampling rate n Hz\n");
279 printf (" --packet-loss n Simulate n %% random packet loss\n");
280 printf (" -V Verbose mode (show bit-rate)\n");
281 printf (" -h, --help This help\n");
282 printf (" -v, --version Version information\n");
283 printf (" --pf Deprecated, use --enh instead\n");
284 printf (" --no-pf Deprecated, use --no-enh instead\n");
285 printf ("\n");
286 printf ("More information is available from the Speex site: http://www.speex.org\n");
287 printf ("\n");
288 printf ("Please report bugs to the mailing list `speex-dev@xiph.org'.\n");
291 void version()
293 const char* speex_version;
294 speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, (void*)&speex_version);
295 printf ("speexdec (Speex decoder) version %s (compiled " __DATE__ ")\n", speex_version);
296 printf ("Copyright (C) 2002-2006 Jean-Marc Valin\n");
299 void version_short()
301 const char* speex_version;
302 speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, (void*)&speex_version);
303 printf ("speexdec version %s\n", speex_version);
304 printf ("Copyright (C) 2002-2006 Jean-Marc Valin\n");
307 static void *process_header(ogg_packet *op, spx_int32_t enh_enabled, spx_int32_t *frame_size, int *granule_frame_size, spx_int32_t *rate, int *nframes, int forceMode, int *channels, SpeexStereoState *stereo, int *extra_headers, int quiet)
309 void *st;
310 const SpeexMode *mode;
311 SpeexHeader *header;
312 int modeID;
313 SpeexCallback callback;
315 header = speex_packet_to_header((char*)op->packet, op->bytes);
316 if (!header)
318 fprintf (stderr, "Cannot read header\n");
319 return NULL;
321 if (header->mode >= SPEEX_NB_MODES || header->mode<0)
323 fprintf (stderr, "Mode number %d does not (yet/any longer) exist in this version\n",
324 header->mode);
325 free(header);
326 return NULL;
329 modeID = header->mode;
330 if (forceMode!=-1)
331 modeID = forceMode;
333 mode = speex_lib_get_mode (modeID);
335 if (header->speex_version_id > 1)
337 fprintf (stderr, "This file was encoded with Speex bit-stream version %d, which I don't know how to decode\n", header->speex_version_id);
338 free(header);
339 return NULL;
342 if (mode->bitstream_version < header->mode_bitstream_version)
344 fprintf (stderr, "The file was encoded with a newer version of Speex. You need to upgrade in order to play it.\n");
345 free(header);
346 return NULL;
348 if (mode->bitstream_version > header->mode_bitstream_version)
350 fprintf (stderr, "The file was encoded with an older version of Speex. You would need to downgrade the version in order to play it.\n");
351 free(header);
352 return NULL;
355 st = speex_decoder_init(mode);
356 if (!st)
358 fprintf (stderr, "Decoder initialization failed.\n");
359 free(header);
360 return NULL;
362 speex_decoder_ctl(st, SPEEX_SET_ENH, &enh_enabled);
363 speex_decoder_ctl(st, SPEEX_GET_FRAME_SIZE, frame_size);
364 *granule_frame_size = *frame_size;
366 if (!*rate)
367 *rate = header->rate;
368 /* Adjust rate if --force-* options are used */
369 if (forceMode!=-1)
371 if (header->mode < forceMode)
373 *rate <<= (forceMode - header->mode);
374 *granule_frame_size >>= (forceMode - header->mode);
376 if (header->mode > forceMode)
378 *rate >>= (header->mode - forceMode);
379 *granule_frame_size <<= (header->mode - forceMode);
384 speex_decoder_ctl(st, SPEEX_SET_SAMPLING_RATE, rate);
386 *nframes = header->frames_per_packet;
388 if (*channels==-1)
389 *channels = header->nb_channels;
391 if (!(*channels==1))
393 *channels = 2;
394 callback.callback_id = SPEEX_INBAND_STEREO;
395 callback.func = speex_std_stereo_request_handler;
396 callback.data = stereo;
397 speex_decoder_ctl(st, SPEEX_SET_HANDLER, &callback);
400 if (!quiet)
402 fprintf (stderr, "Decoding %d Hz audio using %s mode",
403 *rate, mode->modeName);
405 if (*channels==1)
406 fprintf (stderr, " (mono");
407 else
408 fprintf (stderr, " (stereo");
410 if (header->vbr)
411 fprintf (stderr, ", VBR)\n");
412 else
413 fprintf(stderr, ")\n");
414 /*fprintf (stderr, "Decoding %d Hz audio at %d bps using %s mode\n",
415 *rate, mode->bitrate, mode->modeName);*/
418 *extra_headers = header->extra_headers;
420 free(header);
421 return st;
424 int main(int argc, char **argv)
426 int c;
427 int option_index = 0;
428 char *inFile, *outFile;
429 FILE *fin, *fout=NULL;
430 short out[MAX_FRAME_SIZE];
431 short output[MAX_FRAME_SIZE];
432 int frame_size=0, granule_frame_size=0;
433 void *st=NULL;
434 SpeexBits bits;
435 int packet_count=0;
436 int stream_init = 0;
437 int quiet = 0;
438 ogg_int64_t page_granule=0, last_granule=0;
439 int skip_samples=0, page_nb_packets;
440 struct option long_options[] =
442 {"help", no_argument, NULL, 0},
443 {"quiet", no_argument, NULL, 0},
444 {"version", no_argument, NULL, 0},
445 {"version-short", no_argument, NULL, 0},
446 {"enh", no_argument, NULL, 0},
447 {"no-enh", no_argument, NULL, 0},
448 {"pf", no_argument, NULL, 0},
449 {"no-pf", no_argument, NULL, 0},
450 {"force-nb", no_argument, NULL, 0},
451 {"force-wb", no_argument, NULL, 0},
452 {"force-uwb", no_argument, NULL, 0},
453 {"rate", required_argument, NULL, 0},
454 {"mono", no_argument, NULL, 0},
455 {"stereo", no_argument, NULL, 0},
456 {"packet-loss", required_argument, NULL, 0},
457 {0, 0, 0, 0}
459 ogg_sync_state oy;
460 ogg_page og;
461 ogg_packet op;
462 ogg_stream_state os;
463 int enh_enabled;
464 int nframes=2;
465 int print_bitrate=0;
466 int close_in=0;
467 int eos=0;
468 int forceMode=-1;
469 int audio_size=0;
470 float loss_percent=-1;
471 SpeexStereoState stereo = SPEEX_STEREO_STATE_INIT;
472 int channels=-1;
473 int rate=0;
474 int extra_headers=0;
475 int wav_format=0;
476 int lookahead;
477 int speex_serialno = -1;
479 enh_enabled = 1;
481 /*Process options*/
482 while(1)
484 c = getopt_long (argc, argv, "hvV",
485 long_options, &option_index);
486 if (c==-1)
487 break;
489 switch(c)
491 case 0:
492 if (strcmp(long_options[option_index].name,"help")==0)
494 usage();
495 exit(0);
496 } else if (strcmp(long_options[option_index].name,"quiet")==0)
498 quiet = 1;
499 } else if (strcmp(long_options[option_index].name,"version")==0)
501 version();
502 exit(0);
503 } else if (strcmp(long_options[option_index].name,"version-short")==0)
505 version_short();
506 exit(0);
507 } else if (strcmp(long_options[option_index].name,"enh")==0)
509 enh_enabled=1;
510 } else if (strcmp(long_options[option_index].name,"no-enh")==0)
512 enh_enabled=0;
513 } else if (strcmp(long_options[option_index].name,"pf")==0)
515 fprintf (stderr, "--pf is deprecated, use --enh instead\n");
516 enh_enabled=1;
517 } else if (strcmp(long_options[option_index].name,"no-pf")==0)
519 fprintf (stderr, "--no-pf is deprecated, use --no-enh instead\n");
520 enh_enabled=0;
521 } else if (strcmp(long_options[option_index].name,"force-nb")==0)
523 forceMode=0;
524 } else if (strcmp(long_options[option_index].name,"force-wb")==0)
526 forceMode=1;
527 } else if (strcmp(long_options[option_index].name,"force-uwb")==0)
529 forceMode=2;
530 } else if (strcmp(long_options[option_index].name,"mono")==0)
532 channels=1;
533 } else if (strcmp(long_options[option_index].name,"stereo")==0)
535 channels=2;
536 } else if (strcmp(long_options[option_index].name,"rate")==0)
538 rate=atoi (optarg);
539 } else if (strcmp(long_options[option_index].name,"packet-loss")==0)
541 loss_percent = atof(optarg);
543 break;
544 case 'h':
545 usage();
546 exit(0);
547 break;
548 case 'v':
549 version();
550 exit(0);
551 break;
552 case 'V':
553 print_bitrate=1;
554 break;
555 case '?':
556 usage();
557 exit(1);
558 break;
561 if (argc-optind!=2 && argc-optind!=1)
563 usage();
564 exit(1);
566 inFile=argv[optind];
568 if (argc-optind==2)
569 outFile=argv[optind+1];
570 else
571 outFile = "";
572 wav_format = strlen(outFile)>=4 && (
573 strcmp(outFile+strlen(outFile)-4,".wav")==0
574 || strcmp(outFile+strlen(outFile)-4,".WAV")==0);
575 /*Open input file*/
576 if (strcmp(inFile, "-")==0)
578 #if defined WIN32 || defined _WIN32
579 _setmode(_fileno(stdin), _O_BINARY);
580 #endif
581 fin=stdin;
583 else
585 fin = fopen(inFile, "rb");
586 if (!fin)
588 perror(inFile);
589 exit(1);
591 close_in=1;
595 /*Init Ogg data struct*/
596 ogg_sync_init(&oy);
598 speex_bits_init(&bits);
599 /*Main decoding loop*/
601 while (1)
603 char *data;
604 int i, j, nb_read;
605 /*Get the ogg buffer for writing*/
606 data = ogg_sync_buffer(&oy, 200);
607 /*Read bitstream from input file*/
608 nb_read = fread(data, sizeof(char), 200, fin);
609 ogg_sync_wrote(&oy, nb_read);
611 /*Loop for all complete pages we got (most likely only one)*/
612 while (ogg_sync_pageout(&oy, &og)==1)
614 int packet_no;
615 if (stream_init == 0) {
616 ogg_stream_init(&os, ogg_page_serialno(&og));
617 stream_init = 1;
619 if (ogg_page_serialno(&og) != os.serialno) {
620 /* so all streams are read. */
621 ogg_stream_reset_serialno(&os, ogg_page_serialno(&og));
623 /*Add page to the bitstream*/
624 ogg_stream_pagein(&os, &og);
625 page_granule = ogg_page_granulepos(&og);
626 page_nb_packets = ogg_page_packets(&og);
627 if (page_granule>0 && frame_size)
629 /* FIXME: shift the granule values if --force-* is specified */
630 skip_samples = frame_size*(page_nb_packets*granule_frame_size*nframes - (page_granule-last_granule))/granule_frame_size;
631 if (ogg_page_eos(&og))
632 skip_samples = -skip_samples;
633 /*else if (!ogg_page_bos(&og))
634 skip_samples = 0;*/
635 } else
637 skip_samples = 0;
639 /*printf ("page granulepos: %d %d %d\n", skip_samples, page_nb_packets, (int)page_granule);*/
640 last_granule = page_granule;
641 /*Extract all available packets*/
642 packet_no=0;
643 while (!eos && ogg_stream_packetout(&os, &op) == 1)
645 if (op.bytes>=5 && !memcmp(op.packet, "Speex", 5)) {
646 speex_serialno = os.serialno;
648 if (speex_serialno == -1 || os.serialno != speex_serialno)
649 break;
650 /*If first packet, process as Speex header*/
651 if (packet_count==0)
653 st = process_header(&op, enh_enabled, &frame_size, &granule_frame_size, &rate, &nframes, forceMode, &channels, &stereo, &extra_headers, quiet);
654 if (!st)
655 exit(1);
656 speex_decoder_ctl(st, SPEEX_GET_LOOKAHEAD, &lookahead);
657 if (!nframes)
658 nframes=1;
659 fout = out_file_open(outFile, rate, &channels);
661 } else if (packet_count==1)
663 if (!quiet)
664 print_comments((char*)op.packet, op.bytes);
665 } else if (packet_count<=1+extra_headers)
667 /* Ignore extra headers */
668 } else {
669 int lost=0;
670 packet_no++;
671 if (loss_percent>0 && 100*((float)rand())/RAND_MAX<loss_percent)
672 lost=1;
674 /*End of stream condition*/
675 if (op.e_o_s && os.serialno == speex_serialno) /* don't care for anything except speex eos */
676 eos=1;
678 /*Copy Ogg packet to Speex bitstream*/
679 speex_bits_read_from(&bits, (char*)op.packet, op.bytes);
680 for (j=0;j!=nframes;j++)
682 int ret;
683 /*Decode frame*/
684 if (!lost)
685 ret = speex_decode_int(st, &bits, output);
686 else
687 ret = speex_decode_int(st, NULL, output);
689 /*for (i=0;i<frame_size*channels;i++)
690 printf ("%d\n", (int)output[i]);*/
692 if (ret==-1)
693 break;
694 if (ret==-2)
696 fprintf (stderr, "Decoding error: corrupted stream?\n");
697 break;
699 if (speex_bits_remaining(&bits)<0)
701 fprintf (stderr, "Decoding overflow: corrupted stream?\n");
702 break;
704 if (channels==2)
705 speex_decode_stereo_int(output, frame_size, &stereo);
707 if (print_bitrate) {
708 spx_int32_t tmp;
709 char ch=13;
710 speex_decoder_ctl(st, SPEEX_GET_BITRATE, &tmp);
711 fputc (ch, stderr);
712 fprintf (stderr, "Bitrate is use: %d bps ", tmp);
714 /*Convert to short and save to output file*/
715 if (strlen(outFile)!=0)
717 for (i=0;i<frame_size*channels;i++)
718 out[i]=le_short(output[i]);
719 } else {
720 for (i=0;i<frame_size*channels;i++)
721 out[i]=output[i];
724 int frame_offset = 0;
725 int new_frame_size = frame_size;
726 /*printf ("packet %d %d\n", packet_no, skip_samples);*/
727 /*fprintf (stderr, "packet %d %d %d\n", packet_no, skip_samples, lookahead);*/
728 if (packet_no == 1 && j==0 && skip_samples > 0)
730 /*printf ("chopping first packet\n");*/
731 new_frame_size -= skip_samples+lookahead;
732 frame_offset = skip_samples+lookahead;
734 if (packet_no == page_nb_packets && skip_samples < 0)
736 int packet_length = nframes*frame_size+skip_samples+lookahead;
737 new_frame_size = packet_length - j*frame_size;
738 if (new_frame_size<0)
739 new_frame_size = 0;
740 if (new_frame_size>frame_size)
741 new_frame_size = frame_size;
742 /*printf ("chopping end: %d %d %d\n", new_frame_size, packet_length, packet_no);*/
744 if (new_frame_size>0)
746 #if defined WIN32 || defined _WIN32
747 if (strlen(outFile)==0)
748 WIN_Play_Samples (out+frame_offset*channels, sizeof(short) * new_frame_size*channels);
749 else
750 #endif
751 fwrite(out+frame_offset*channels, sizeof(short), new_frame_size*channels, fout);
753 audio_size+=sizeof(short)*new_frame_size*channels;
758 packet_count++;
761 if (feof(fin))
762 break;
766 if (fout && wav_format)
768 if (fseek(fout,4,SEEK_SET)==0)
770 int tmp;
771 tmp = le_int(audio_size+36);
772 fwrite(&tmp,4,1,fout);
773 if (fseek(fout,32,SEEK_CUR)==0)
775 tmp = le_int(audio_size);
776 fwrite(&tmp,4,1,fout);
777 } else
779 fprintf (stderr, "First seek worked, second didn't\n");
781 } else {
782 fprintf (stderr, "Cannot seek on wave file, size will be incorrect\n");
786 if (st)
787 speex_decoder_destroy(st);
788 else
790 fprintf (stderr, "This doesn't look like a Speex file\n");
792 speex_bits_destroy(&bits);
793 if (stream_init)
794 ogg_stream_clear(&os);
795 ogg_sync_clear(&oy);
797 #if defined WIN32 || defined _WIN32
798 if (strlen(outFile)==0)
799 WIN_Audio_close ();
800 #endif
802 if (close_in)
803 fclose(fin);
804 if (fout != NULL)
805 fclose(fout);
807 return 0;