Blame tools/celtdec.c

Packit 664db3
/* Copyright (C) 2008 Jean-Marc Valin, CSIRO
Packit 664db3
   File: celtdec.c
Packit 664db3
Packit 664db3
   Redistribution and use in source and binary forms, with or without
Packit 664db3
   modification, are permitted provided that the following conditions
Packit 664db3
   are met:
Packit 664db3
   
Packit 664db3
   - Redistributions of source code must retain the above copyright
Packit 664db3
   notice, this list of conditions and the following disclaimer.
Packit 664db3
   
Packit 664db3
   - Redistributions in binary form must reproduce the above copyright
Packit 664db3
   notice, this list of conditions and the following disclaimer in the
Packit 664db3
   documentation and/or other materials provided with the distribution.
Packit 664db3
   
Packit 664db3
   - Neither the name of the Xiph.org Foundation nor the names of its
Packit 664db3
   contributors may be used to endorse or promote products derived from
Packit 664db3
   this software without specific prior written permission.
Packit 664db3
   
Packit 664db3
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit 664db3
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit 664db3
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit 664db3
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
Packit 664db3
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Packit 664db3
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
Packit 664db3
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
Packit 664db3
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
Packit 664db3
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
Packit 664db3
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Packit 664db3
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 664db3
*/
Packit 664db3
Packit 664db3
#ifdef HAVE_CONFIG_H
Packit 664db3
# include "config.h"
Packit 664db3
#endif
Packit 664db3
Packit 664db3
#include <stdio.h>
Packit 664db3
#if !defined WIN32 && !defined _WIN32
Packit 664db3
#include <unistd.h>
Packit 664db3
#endif
Packit 664db3
#ifdef HAVE_GETOPT_H
Packit 664db3
#include <getopt.h>
Packit 664db3
#endif
Packit 664db3
#ifndef HAVE_GETOPT_LONG
Packit 664db3
#include "getopt_win.h"
Packit 664db3
#endif
Packit 664db3
#include <stdlib.h>
Packit 664db3
#include <string.h>
Packit 664db3
Packit 664db3
#include "celt.h"
Packit 664db3
#include <ogg/ogg.h>
Packit 664db3
Packit 664db3
#if defined WIN32 || defined _WIN32
Packit 664db3
#include "wave_out.h"
Packit 664db3
/* We need the following two to set stdout to binary */
Packit 664db3
#include <io.h>
Packit 664db3
#include <fcntl.h>
Packit 664db3
#endif
Packit 664db3
#include <math.h>
Packit 664db3
Packit 664db3
#ifdef __MINGW32__
Packit 664db3
#include "wave_out.c"
Packit 664db3
#endif
Packit 664db3
Packit 664db3
#ifdef HAVE_SYS_SOUNDCARD_H
Packit 664db3
#include <sys/soundcard.h>
Packit 664db3
#include <sys/types.h>
Packit 664db3
#include <sys/stat.h>
Packit 664db3
#include <fcntl.h>
Packit 664db3
#include <sys/ioctl.h>
Packit 664db3
Packit 664db3
#elif defined HAVE_SYS_AUDIOIO_H
Packit 664db3
#include <sys/types.h>
Packit 664db3
#include <fcntl.h>
Packit 664db3
#include <sys/ioctl.h>
Packit 664db3
#include <sys/audioio.h>
Packit 664db3
#ifndef AUDIO_ENCODING_SLINEAR
Packit 664db3
#define AUDIO_ENCODING_SLINEAR AUDIO_ENCODING_LINEAR /* Solaris */
Packit 664db3
#endif
Packit 664db3
Packit 664db3
#endif
Packit 664db3
Packit 664db3
#include <string.h>
Packit 664db3
#include "wav_io.h"
Packit 664db3
#include "celt_header.h"
Packit 664db3
Packit 664db3
#define MAX_FRAME_SIZE 2000
Packit 664db3
Packit 664db3
#define readint(buf, base) (((buf[base+3]<<24)&0xff000000)| \
Packit 664db3
                           ((buf[base+2]<<16)&0xff0000)| \
Packit 664db3
                           ((buf[base+1]<<8)&0xff00)| \
Packit 664db3
  	           	    (buf[base]&0xff))
Packit 664db3
Packit 664db3
static void print_comments(char *comments, int length)
Packit 664db3
{
Packit 664db3
   char *c=comments;
Packit 664db3
   int len, i, nb_fields;
Packit 664db3
   char *end;
Packit 664db3
   
Packit 664db3
   if (length<8)
Packit 664db3
   {
Packit 664db3
      fprintf (stderr, "Invalid/corrupted comments\n");
Packit 664db3
      return;
Packit 664db3
   }
Packit 664db3
   end = c+length;
Packit 664db3
   len=readint(c, 0);
Packit 664db3
   c+=4;
Packit 664db3
   if (len < 0 || c+len>end)
Packit 664db3
   {
Packit 664db3
      fprintf (stderr, "Invalid/corrupted comments\n");
Packit 664db3
      return;
Packit 664db3
   }
Packit 664db3
   fwrite(c, 1, len, stderr);
Packit 664db3
   c+=len;
Packit 664db3
   fprintf (stderr, "\n");
Packit 664db3
   if (c+4>end)
Packit 664db3
   {
Packit 664db3
      fprintf (stderr, "Invalid/corrupted comments\n");
Packit 664db3
      return;
Packit 664db3
   }
Packit 664db3
   nb_fields=readint(c, 0);
Packit 664db3
   c+=4;
Packit 664db3
   for (i=0;i
Packit 664db3
   {
Packit 664db3
      if (c+4>end)
Packit 664db3
      {
Packit 664db3
         fprintf (stderr, "Invalid/corrupted comments\n");
Packit 664db3
         return;
Packit 664db3
      }
Packit 664db3
      len=readint(c, 0);
Packit 664db3
      c+=4;
Packit 664db3
      if (len < 0 || c+len>end)
Packit 664db3
      {
Packit 664db3
         fprintf (stderr, "Invalid/corrupted comments\n");
Packit 664db3
         return;
Packit 664db3
      }
Packit 664db3
      fwrite(c, 1, len, stderr);
Packit 664db3
      c+=len;
Packit 664db3
      fprintf (stderr, "\n");
Packit 664db3
   }
Packit 664db3
}
Packit 664db3
Packit 664db3
FILE *out_file_open(char *outFile, int rate, int *channels)
Packit 664db3
{
Packit 664db3
   FILE *fout=NULL;
Packit 664db3
   /*Open output file*/
Packit 664db3
   if (strlen(outFile)==0)
Packit 664db3
   {
Packit 664db3
#if defined HAVE_SYS_SOUNDCARD_H
Packit 664db3
      int audio_fd, format, stereo;
Packit 664db3
      audio_fd=open("/dev/dsp", O_WRONLY);
Packit 664db3
      if (audio_fd<0)
Packit 664db3
      {
Packit 664db3
         perror("Cannot open /dev/dsp");
Packit 664db3
         exit(1);         
Packit 664db3
      }
Packit 664db3
Packit 664db3
      format=AFMT_S16_NE;
Packit 664db3
      if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format)==-1)
Packit 664db3
      {
Packit 664db3
         perror("SNDCTL_DSP_SETFMT");
Packit 664db3
         close(audio_fd);
Packit 664db3
         exit(1);
Packit 664db3
      }
Packit 664db3
Packit 664db3
      stereo=0;
Packit 664db3
      if (*channels==2)
Packit 664db3
         stereo=1;
Packit 664db3
      if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo)==-1)
Packit 664db3
      {
Packit 664db3
         perror("SNDCTL_DSP_STEREO");
Packit 664db3
         close(audio_fd);
Packit 664db3
         exit(1);
Packit 664db3
      }
Packit 664db3
      if (stereo!=0)
Packit 664db3
      {
Packit 664db3
         if (*channels==1)
Packit 664db3
            fprintf (stderr, "Cannot set mono mode, will decode in stereo\n");
Packit 664db3
         *channels=2;
Packit 664db3
      }
Packit 664db3
Packit 664db3
      if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate)==-1)
Packit 664db3
      {
Packit 664db3
         perror("SNDCTL_DSP_SPEED");
Packit 664db3
         close(audio_fd);
Packit 664db3
         exit(1);
Packit 664db3
      }
Packit 664db3
      fout = fdopen(audio_fd, "w");
Packit 664db3
#elif defined HAVE_SYS_AUDIOIO_H
Packit 664db3
      audio_info_t info;
Packit 664db3
      int audio_fd;
Packit 664db3
      
Packit 664db3
      audio_fd = open("/dev/audio", O_WRONLY);
Packit 664db3
      if (audio_fd<0)
Packit 664db3
      {
Packit 664db3
         perror("Cannot open /dev/audio");
Packit 664db3
         exit(1);
Packit 664db3
      }
Packit 664db3
Packit 664db3
      AUDIO_INITINFO(&info;;
Packit 664db3
#ifdef AUMODE_PLAY    /* NetBSD/OpenBSD */
Packit 664db3
      info.mode = AUMODE_PLAY;
Packit 664db3
#endif
Packit 664db3
      info.play.encoding = AUDIO_ENCODING_SLINEAR;
Packit 664db3
      info.play.precision = 16;
Packit 664db3
      info.play.sample_rate = rate;
Packit 664db3
      info.play.channels = *channels;
Packit 664db3
      
Packit 664db3
      if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0)
Packit 664db3
      {
Packit 664db3
         perror ("AUDIO_SETINFO");
Packit 664db3
         exit(1);
Packit 664db3
      }
Packit 664db3
      fout = fdopen(audio_fd, "w");
Packit 664db3
#elif defined WIN32 || defined _WIN32
Packit 664db3
      {
Packit 664db3
         unsigned int celt_channels = *channels;
Packit 664db3
         if (Set_WIN_Params (INVALID_FILEDESC, rate, SAMPLE_SIZE, celt_channels))
Packit 664db3
         {
Packit 664db3
            fprintf (stderr, "Can't access %s\n", "WAVE OUT");
Packit 664db3
            exit(1);
Packit 664db3
         }
Packit 664db3
      }
Packit 664db3
#else
Packit 664db3
      fprintf (stderr, "No soundcard support\n");
Packit 664db3
      exit(1);
Packit 664db3
#endif
Packit 664db3
   } else {
Packit 664db3
      if (strcmp(outFile,"-")==0)
Packit 664db3
      {
Packit 664db3
#if defined WIN32 || defined _WIN32
Packit 664db3
         _setmode(_fileno(stdout), _O_BINARY);
Packit 664db3
#endif
Packit 664db3
         fout=stdout;
Packit 664db3
      }
Packit 664db3
      else 
Packit 664db3
      {
Packit 664db3
         fout = fopen(outFile, "wb");
Packit 664db3
         if (!fout)
Packit 664db3
         {
Packit 664db3
            perror(outFile);
Packit 664db3
            exit(1);
Packit 664db3
         }
Packit 664db3
         if (strcmp(outFile+strlen(outFile)-4,".wav")==0 || strcmp(outFile+strlen(outFile)-4,".WAV")==0)
Packit 664db3
            write_wav_header(fout, rate, *channels, 0, 0);
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
   return fout;
Packit 664db3
}
Packit 664db3
Packit 664db3
void usage(void)
Packit 664db3
{
Packit 664db3
   printf ("Usage: celtdec [options] input_file.oga [output_file]\n");
Packit 664db3
   printf ("\n");
Packit 664db3
   printf ("Decodes a CELT file and produce a WAV file or raw file\n");
Packit 664db3
   printf ("\n");
Packit 664db3
   printf ("input_file can be:\n");
Packit 664db3
   printf ("  filename.oga         regular CELT file\n");
Packit 664db3
   printf ("  -                    stdin\n");
Packit 664db3
   printf ("\n");  
Packit 664db3
   printf ("output_file can be:\n");
Packit 664db3
   printf ("  filename.wav         Wav file\n");
Packit 664db3
   printf ("  filename.*           Raw PCM file (any extension other that .wav)\n");
Packit 664db3
   printf ("  -                    stdout\n");
Packit 664db3
   printf ("  (nothing)            Will be played to soundcard\n");
Packit 664db3
   printf ("\n");  
Packit 664db3
   printf ("Options:\n");
Packit 664db3
   printf (" --mono                Force decoding in mono\n");
Packit 664db3
   printf (" --stereo              Force decoding in stereo\n");
Packit 664db3
   printf (" --rate n              Force decoding at sampling rate n Hz\n");
Packit 664db3
   printf (" --packet-loss n       Simulate n %% random packet loss\n");
Packit 664db3
   printf (" -V                    Verbose mode (show bit-rate)\n"); 
Packit 664db3
   printf (" -h, --help            This help\n");
Packit 664db3
   printf (" -v, --version         Version information\n");
Packit 664db3
   printf ("\n");
Packit 664db3
}
Packit 664db3
Packit 664db3
void version(void)
Packit 664db3
{
Packit 664db3
   printf ("celtenc (CELT encoder)\n");
Packit 664db3
   printf ("Copyright (C) 2008 Jean-Marc Valin\n");
Packit 664db3
}
Packit 664db3
Packit 664db3
void version_short(void)
Packit 664db3
{
Packit 664db3
   printf ("celtenc (CELT encoder)\n");
Packit 664db3
   printf ("Copyright (C) 2008 Jean-Marc Valin\n");
Packit 664db3
}
Packit 664db3
Packit 664db3
static CELTDecoder *process_header(ogg_packet *op, celt_int32_t enh_enabled, celt_int32_t *frame_size, int *granule_frame_size, celt_int32_t *rate, int *nframes, int forceMode, int *channels, int *overlap, int *extra_headers, int quiet, CELTMode **mode)
Packit 664db3
{
Packit 664db3
   CELTDecoder *st;
Packit 664db3
   CELT051Header header;
Packit 664db3
      
Packit 664db3
   celt051_header_from_packet(op->packet, op->bytes, &header);
Packit 664db3
Packit 664db3
   if (header.nb_channels>2 || header.nb_channels<1)
Packit 664db3
   {
Packit 664db3
      fprintf (stderr, "Unsupported number of channels: %d\n", header.nb_channels);
Packit 664db3
      return NULL;
Packit 664db3
   }
Packit 664db3
   *mode = celt051_mode_create(header.sample_rate, header.nb_channels, header.frame_size, NULL);
Packit 664db3
   if (*mode == NULL)
Packit 664db3
   {
Packit 664db3
      fprintf (stderr, "Mode initialization failed.\n");
Packit 664db3
      return NULL;
Packit 664db3
   }
Packit 664db3
   *channels = header.nb_channels;
Packit 664db3
   *overlap=header.overlap;
Packit 664db3
   st = celt051_decoder_create(*mode);
Packit 664db3
   if (!st)
Packit 664db3
   {
Packit 664db3
      fprintf (stderr, "Decoder initialization failed.\n");
Packit 664db3
      return NULL;
Packit 664db3
   }
Packit 664db3
   
Packit 664db3
   celt051_mode_info(*mode, CELT_GET_FRAME_SIZE, frame_size);
Packit 664db3
   *granule_frame_size = *frame_size;
Packit 664db3
Packit 664db3
   if (!*rate)
Packit 664db3
      *rate = header.sample_rate;
Packit 664db3
Packit 664db3
   *nframes = 1;
Packit 664db3
Packit 664db3
   if (!quiet)
Packit 664db3
   {
Packit 664db3
      fprintf (stderr, "Decoding %d Hz audio in", *rate);
Packit 664db3
Packit 664db3
      if (*channels==1)
Packit 664db3
         fprintf (stderr, " (mono");
Packit 664db3
      else
Packit 664db3
         fprintf (stderr, " (stereo");
Packit 664db3
      fprintf(stderr, ")\n");
Packit 664db3
   }
Packit 664db3
Packit 664db3
   *extra_headers = header.extra_headers;
Packit 664db3
Packit 664db3
   return st;
Packit 664db3
}
Packit 664db3
Packit 664db3
int main(int argc, char **argv)
Packit 664db3
{
Packit 664db3
   int c;
Packit 664db3
   int option_index = 0;
Packit 664db3
   char *inFile, *outFile;
Packit 664db3
   FILE *fin, *fout=NULL;
Packit 664db3
   short out[MAX_FRAME_SIZE];
Packit 664db3
   short output[MAX_FRAME_SIZE];
Packit 664db3
   int frame_size=0, granule_frame_size=0;
Packit 664db3
   void *st=NULL;
Packit 664db3
   CELTMode *mode=NULL;
Packit 664db3
   int packet_count=0;
Packit 664db3
   int stream_init = 0;
Packit 664db3
   int quiet = 0;
Packit 664db3
   ogg_int64_t page_granule=0, last_granule=0;
Packit 664db3
   int skip_samples=0, page_nb_packets;
Packit 664db3
   struct option long_options[] =
Packit 664db3
   {
Packit 664db3
      {"help", no_argument, NULL, 0},
Packit 664db3
      {"quiet", no_argument, NULL, 0},
Packit 664db3
      {"version", no_argument, NULL, 0},
Packit 664db3
      {"version-short", no_argument, NULL, 0},
Packit 664db3
      {"rate", required_argument, NULL, 0},
Packit 664db3
      {"mono", no_argument, NULL, 0},
Packit 664db3
      {"stereo", no_argument, NULL, 0},
Packit 664db3
      {"packet-loss", required_argument, NULL, 0},
Packit 664db3
      {0, 0, 0, 0}
Packit 664db3
   };
Packit 664db3
   ogg_sync_state oy;
Packit 664db3
   ogg_page       og;
Packit 664db3
   ogg_packet     op;
Packit 664db3
   ogg_stream_state os;
Packit 664db3
   int enh_enabled;
Packit 664db3
   int nframes=2;
Packit 664db3
   int print_bitrate=0;
Packit 664db3
   int close_in=0;
Packit 664db3
   int eos=0;
Packit 664db3
   int forceMode=-1;
Packit 664db3
   int audio_size=0;
Packit 664db3
   float loss_percent=-1;
Packit 664db3
   int channels=-1;
Packit 664db3
   int rate=0;
Packit 664db3
   int extra_headers=0;
Packit 664db3
   int wav_format=0;
Packit 664db3
   int lookahead=0;
Packit 664db3
   int celt_serialno = -1;
Packit 664db3
   int firstpacket = 1;
Packit 664db3
Packit 664db3
   enh_enabled = 1;
Packit 664db3
Packit 664db3
   /*Process options*/
Packit 664db3
   while(1)
Packit 664db3
   {
Packit 664db3
      c = getopt_long (argc, argv, "hvV",
Packit 664db3
                       long_options, &option_index);
Packit 664db3
      if (c==-1)
Packit 664db3
         break;
Packit 664db3
      
Packit 664db3
      switch(c)
Packit 664db3
      {
Packit 664db3
      case 0:
Packit 664db3
         if (strcmp(long_options[option_index].name,"help")==0)
Packit 664db3
         {
Packit 664db3
            usage();
Packit 664db3
            exit(0);
Packit 664db3
         } else if (strcmp(long_options[option_index].name,"quiet")==0)
Packit 664db3
         {
Packit 664db3
            quiet = 1;
Packit 664db3
         } else if (strcmp(long_options[option_index].name,"version")==0)
Packit 664db3
         {
Packit 664db3
            version();
Packit 664db3
            exit(0);
Packit 664db3
         } else if (strcmp(long_options[option_index].name,"version-short")==0)
Packit 664db3
         {
Packit 664db3
            version_short();
Packit 664db3
            exit(0);
Packit 664db3
         } else if (strcmp(long_options[option_index].name,"mono")==0)
Packit 664db3
         {
Packit 664db3
            channels=1;
Packit 664db3
         } else if (strcmp(long_options[option_index].name,"stereo")==0)
Packit 664db3
         {
Packit 664db3
            channels=2;
Packit 664db3
         } else if (strcmp(long_options[option_index].name,"rate")==0)
Packit 664db3
         {
Packit 664db3
            rate=atoi (optarg);
Packit 664db3
         } else if (strcmp(long_options[option_index].name,"packet-loss")==0)
Packit 664db3
         {
Packit 664db3
            loss_percent = atof(optarg);
Packit 664db3
         }
Packit 664db3
         break;
Packit 664db3
      case 'h':
Packit 664db3
         usage();
Packit 664db3
         exit(0);
Packit 664db3
         break;
Packit 664db3
      case 'v':
Packit 664db3
         version();
Packit 664db3
         exit(0);
Packit 664db3
         break;
Packit 664db3
      case 'V':
Packit 664db3
         print_bitrate=1;
Packit 664db3
         break;
Packit 664db3
      case '?':
Packit 664db3
         usage();
Packit 664db3
         exit(1);
Packit 664db3
         break;
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
   if (argc-optind!=2 && argc-optind!=1)
Packit 664db3
   {
Packit 664db3
      usage();
Packit 664db3
      exit(1);
Packit 664db3
   }
Packit 664db3
   inFile=argv[optind];
Packit 664db3
Packit 664db3
   if (argc-optind==2)
Packit 664db3
      outFile=argv[optind+1];
Packit 664db3
   else
Packit 664db3
      outFile = "";
Packit 664db3
   wav_format = strlen(outFile)>=4 && (
Packit 664db3
                                       strcmp(outFile+strlen(outFile)-4,".wav")==0
Packit 664db3
                                       || strcmp(outFile+strlen(outFile)-4,".WAV")==0);
Packit 664db3
   /*Open input file*/
Packit 664db3
   if (strcmp(inFile, "-")==0)
Packit 664db3
   {
Packit 664db3
#if defined WIN32 || defined _WIN32
Packit 664db3
      _setmode(_fileno(stdin), _O_BINARY);
Packit 664db3
#endif
Packit 664db3
      fin=stdin;
Packit 664db3
   }
Packit 664db3
   else 
Packit 664db3
   {
Packit 664db3
      fin = fopen(inFile, "rb");
Packit 664db3
      if (!fin)
Packit 664db3
      {
Packit 664db3
         perror(inFile);
Packit 664db3
         exit(1);
Packit 664db3
      }
Packit 664db3
      close_in=1;
Packit 664db3
   }
Packit 664db3
Packit 664db3
Packit 664db3
   /*Init Ogg data struct*/
Packit 664db3
   ogg_sync_init(&oy;;
Packit 664db3
   
Packit 664db3
   /*Main decoding loop*/
Packit 664db3
   
Packit 664db3
   while (1)
Packit 664db3
   {
Packit 664db3
      char *data;
Packit 664db3
      int i, nb_read;
Packit 664db3
      /*Get the ogg buffer for writing*/
Packit 664db3
      data = ogg_sync_buffer(&oy, 200);
Packit 664db3
      /*Read bitstream from input file*/
Packit 664db3
      nb_read = fread(data, sizeof(char), 200, fin);      
Packit 664db3
      ogg_sync_wrote(&oy, nb_read);
Packit 664db3
Packit 664db3
      /*Loop for all complete pages we got (most likely only one)*/
Packit 664db3
      while (ogg_sync_pageout(&oy, &og)==1)
Packit 664db3
      {
Packit 664db3
         if (stream_init == 0) {
Packit 664db3
            ogg_stream_init(&os, ogg_page_serialno(&og);;
Packit 664db3
            stream_init = 1;
Packit 664db3
         }
Packit 664db3
	 if (ogg_page_serialno(&og) != os.serialno) {
Packit 664db3
	    /* so all streams are read. */
Packit 664db3
	    ogg_stream_reset_serialno(&os, ogg_page_serialno(&og);;
Packit 664db3
	 }
Packit 664db3
         /*Add page to the bitstream*/
Packit 664db3
         ogg_stream_pagein(&os, &og);
Packit 664db3
         page_granule = ogg_page_granulepos(&og);
Packit 664db3
         page_nb_packets = ogg_page_packets(&og);
Packit 664db3
         if (page_granule>0 && frame_size)
Packit 664db3
         {
Packit 664db3
            /* FIXME: shift the granule values if --force-* is specified */
Packit 664db3
            skip_samples = frame_size*(page_nb_packets*granule_frame_size*nframes - (page_granule-last_granule))/granule_frame_size;
Packit 664db3
            if (ogg_page_eos(&og))
Packit 664db3
               skip_samples = -skip_samples;
Packit 664db3
            /*else if (!ogg_page_bos(&og))
Packit 664db3
               skip_samples = 0;*/
Packit 664db3
         } else
Packit 664db3
         {
Packit 664db3
            skip_samples = 0;
Packit 664db3
         }
Packit 664db3
         /*printf ("page granulepos: %d %d %d\n", skip_samples, page_nb_packets, (int)page_granule);*/
Packit 664db3
         last_granule = page_granule;
Packit 664db3
         /*Extract all available packets*/
Packit 664db3
         while (!eos && ogg_stream_packetout(&os, &op) == 1 && op.bytes>=8)
Packit 664db3
         {
Packit 664db3
	    if (!memcmp(op.packet, "CELT    ", 8)) {
Packit 664db3
	       celt_serialno = os.serialno;
Packit 664db3
	    }
Packit 664db3
	    if (celt_serialno == -1 || os.serialno != celt_serialno)
Packit 664db3
	       break;
Packit 664db3
            /*If first packet, process as CELT header*/
Packit 664db3
            if (packet_count==0)
Packit 664db3
            {
Packit 664db3
               st = process_header(&op, enh_enabled, &frame_size, &granule_frame_size, &rate, &nframes, forceMode, &channels, &lookahead, &extra_headers, quiet, &mode);
Packit 664db3
               if (!st)
Packit 664db3
                  exit(1);
Packit 664db3
               if (!nframes)
Packit 664db3
                  nframes=1;
Packit 664db3
               fout = out_file_open(outFile, rate, &channels);
Packit 664db3
Packit 664db3
            } else if (packet_count==1)
Packit 664db3
            {
Packit 664db3
               if (!quiet)
Packit 664db3
                  print_comments((char*)op.packet, op.bytes);
Packit 664db3
            } else if (packet_count<=1+extra_headers)
Packit 664db3
            {
Packit 664db3
               /* Ignore extra headers */
Packit 664db3
            } else {
Packit 664db3
               int lost=0;
Packit 664db3
               if (loss_percent>0 && 100*((float)rand())/RAND_MAX
Packit 664db3
                  lost=1;
Packit 664db3
Packit 664db3
               /*End of stream condition*/
Packit 664db3
               if (op.e_o_s && os.serialno == celt_serialno) /* don't care for anything except celt eos */
Packit 664db3
                  eos=1;
Packit 664db3
	       
Packit 664db3
               {
Packit 664db3
                  int ret;
Packit 664db3
                  /*Decode frame*/
Packit 664db3
                  if (!lost)
Packit 664db3
                     ret = celt051_decode(st, (unsigned char*)op.packet, op.bytes, output);
Packit 664db3
                  else
Packit 664db3
                     ret = celt051_decode(st, NULL, 0, output);
Packit 664db3
Packit 664db3
                  /*for (i=0;i
Packit 664db3
                    printf ("%d\n", (int)output[i]);*/
Packit 664db3
Packit 664db3
                  if (ret!=0)
Packit 664db3
                  {
Packit 664db3
                     fprintf (stderr, "Decoding error: corrupted stream?\n");
Packit 664db3
                     break;
Packit 664db3
                  }
Packit 664db3
Packit 664db3
                  if (print_bitrate) {
Packit 664db3
                     celt_int32_t tmp=op.bytes;
Packit 664db3
                     char ch=13;
Packit 664db3
                     fputc (ch, stderr);
Packit 664db3
                     fprintf (stderr, "Bitrate in use: %d bytes/packet     ", tmp);
Packit 664db3
                  }
Packit 664db3
                  /*Convert to short and save to output file*/
Packit 664db3
                  if (strlen(outFile)!=0)
Packit 664db3
                  {
Packit 664db3
                     for (i=0;i
Packit 664db3
                        out[i]=le_short(output[i]);
Packit 664db3
                  } else {
Packit 664db3
                     for (i=0;i
Packit 664db3
                        out[i]=output[i];
Packit 664db3
                  }
Packit 664db3
                  {
Packit 664db3
                     int frame_offset = 0;
Packit 664db3
                     int new_frame_size = frame_size;
Packit 664db3
                     /*printf ("packet %d %d\n", packet_no, skip_samples);*/
Packit 664db3
                     /*fprintf (stderr, "packet %d %d %d\n", packet_no, skip_samples, lookahead);*/
Packit 664db3
                     if (firstpacket == 1)
Packit 664db3
                     {
Packit 664db3
                        /*printf ("chopping first packet\n");*/
Packit 664db3
                        new_frame_size -= lookahead;
Packit 664db3
                        frame_offset = lookahead;
Packit 664db3
                        firstpacket = 0;
Packit 664db3
                     }
Packit 664db3
                     if (new_frame_size>0)
Packit 664db3
                     {  
Packit 664db3
#if defined WIN32 || defined _WIN32
Packit 664db3
                        if (strlen(outFile)==0)
Packit 664db3
                           WIN_Play_Samples (out+frame_offset*channels, sizeof(short) * new_frame_size*channels);
Packit 664db3
                        else
Packit 664db3
#endif
Packit 664db3
                           fwrite(out+frame_offset*channels, sizeof(short), new_frame_size*channels, fout);
Packit 664db3
                  
Packit 664db3
                        audio_size+=sizeof(short)*new_frame_size*channels;
Packit 664db3
                     }
Packit 664db3
                  }
Packit 664db3
               }
Packit 664db3
            }
Packit 664db3
            packet_count++;
Packit 664db3
         }
Packit 664db3
      }
Packit 664db3
      if (feof(fin))
Packit 664db3
         break;
Packit 664db3
Packit 664db3
   }
Packit 664db3
Packit 664db3
   if (fout && wav_format)
Packit 664db3
   {
Packit 664db3
      if (fseek(fout,4,SEEK_SET)==0)
Packit 664db3
      {
Packit 664db3
         int tmp;
Packit 664db3
         tmp = le_int(audio_size+36);
Packit 664db3
         fwrite(&tmp,4,1,fout);
Packit 664db3
         if (fseek(fout,32,SEEK_CUR)==0)
Packit 664db3
         {
Packit 664db3
            tmp = le_int(audio_size);
Packit 664db3
            fwrite(&tmp,4,1,fout);
Packit 664db3
         } else
Packit 664db3
         {
Packit 664db3
            fprintf (stderr, "First seek worked, second didn't\n");
Packit 664db3
         }
Packit 664db3
      } else {
Packit 664db3
         fprintf (stderr, "Cannot seek on wave file, size will be incorrect\n");
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
Packit 664db3
   if (st)
Packit 664db3
   {
Packit 664db3
      celt051_decoder_destroy(st);
Packit 664db3
      celt051_mode_destroy(mode);
Packit 664db3
   } else {
Packit 664db3
      fprintf (stderr, "This doesn't look like a CELT file\n");
Packit 664db3
   }
Packit 664db3
   if (stream_init)
Packit 664db3
      ogg_stream_clear(&os);
Packit 664db3
   ogg_sync_clear(&oy;;
Packit 664db3
Packit 664db3
#if defined WIN32 || defined _WIN32
Packit 664db3
   if (strlen(outFile)==0)
Packit 664db3
      WIN_Audio_close ();
Packit 664db3
#endif
Packit 664db3
Packit 664db3
   if (close_in)
Packit 664db3
      fclose(fin);
Packit 664db3
   if (fout != NULL)
Packit 664db3
      fclose(fout);   
Packit 664db3
Packit 664db3
   return 0;
Packit 664db3
}