fixed some bugs in wave input: should now handle extra chunks as well
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Sun, 5 Jan 2003 08:46:33 +0000 (08:46 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Sun, 5 Jan 2003 08:46:33 +0000 (08:46 +0000)
as extended "fmt " chunks. Also, fixed a bug in invalid comment handling.

git-svn-id: http://svn.xiph.org/trunk/speex@4200 0101bb08-14d6-0310-b084-bc0e0c8e3800

doc/manual.lyx
libspeex/nb_celp.c
src/speexdec.c
src/speexenc.c
src/wav_io.c

index 913adc0..5c1ee90 100644 (file)
@@ -3210,7 +3210,22 @@ Complexity (variable)
 \layout Standard
 
 With Speex, it is possible to vary the complexity allowed for the encoder.
+ This is done by controlling how the search is performed with an integer
+ ranging from 1 to 10 in a way that's similar to the -1 to -9 options to
  
+\emph on 
+gzip
+\emph default 
+ and 
+\emph on 
+bzip2
+\emph default 
+ compression utilities.
+ For normal use, the noise level at complexity 1is between 1 and 2 dB higher
+ than at complexity 10, but the CPU requirements for complexity 10 is about
+ 5 time higher than for complexity 1.
+ In practice, the best trade-off is between complexity 2 and 4, though higher
+ settings are often useful when encoding non-speech sounds like DTMF tones.
 \layout Subsection*
 
 Variable Bit-Rate (VBR)
@@ -3227,8 +3242,8 @@ difficulty
 
  of the audio being encoded.
  In the example of Speex, sounds like vowels and high-energy transients
- require a higher bit-rate to achieve good quality, while fricatives (s,f
- sounds) can be coded adequately with less bits.
+ require a higher bit-rate to achieve good quality, while fricatives (e.g.
+ s,f sounds) can be coded adequately with less bits.
  For this reason, VBR can achive lower bit-rate for the same quality, or
  a better quality for a certain bit-rate.
  Despite its advantages, VBR has two main drawbacks: first, by only specifying
@@ -3243,6 +3258,9 @@ Average Bit-Rate (ABR)
 
 Average bit-rate solves one of the problems of VBR, as it dynamically adjusts
  VBR quality in order to meet a specific target bit-rate.
+ Because the quality/bit-rate is adjusted in real-time (open-loop), the
+ global quality will be slightly lower than that obtained be encoding in
+ VBR with exactly the right quality setting to meet the target average bit-rate.
 \layout Subsection*
 
 Voice Activity Detection (VAD)
@@ -3254,7 +3272,7 @@ When enabled, voice activity detection detects whether the audio being encoded
  is only useful in non-VBR operation.
  In this case, Speex detects non-speech periods and encode them with just
  enough bits to reproduce the background noise.
- This is calles 
+ This is called 
 \begin_inset Quotes eld
 \end_inset 
 
@@ -3463,7 +3481,7 @@ n For decoding at n Hz sampling rate
 \layout Description
 
 --packet-loss\SpecialChar ~
-n Simulate n % rando m packet loss
+n Simulate n % random packet loss
 \layout Description
 
 -V Verbose operation, print bit-rate currently in use
index a557329..c8b1bae 100644 (file)
@@ -51,7 +51,6 @@
 #define cos speex_cos
 #endif
 
-extern int training_weight;
 #ifndef M_PI
 #define M_PI           3.14159265358979323846  /* pi */
 #endif
@@ -64,10 +63,6 @@ float exc_gain_quant_scal1[2]={-0.35, 0.05};
 
 #define sqr(x) ((x)*(x))
 
-#ifndef min
-#define min(a,b) ((a) < (b) ? (a) : (b))
-#endif
-
 void *nb_encoder_init(SpeexMode *m)
 {
    EncState *st;
@@ -76,6 +71,8 @@ void *nb_encoder_init(SpeexMode *m)
 
    mode=(SpeexNBMode *)m->mode;
    st = (EncState*)speex_alloc(sizeof(EncState));
+   if (!st)
+      return NULL;
    st->mode=m;
 
    st->frameSize = mode->frameSize;
index 36eea07..5cd9459 100644 (file)
@@ -86,7 +86,7 @@ static void print_comments(char *comments, int length)
    end = c+length;
    len=readint(c, 0);
    c+=4;
-   if (c+len>=end)
+   if (c+len>end)
    {
       fprintf (stderr, "Invalid/corrupted comments\n");
       return;
@@ -94,7 +94,7 @@ static void print_comments(char *comments, int length)
    fwrite(c, 1, len, stderr);
    c+=len;
    fprintf (stderr, "\n");
-   if (c+4>=end)
+   if (c+4>end)
    {
       fprintf (stderr, "Invalid/corrupted comments\n");
       return;
@@ -103,14 +103,14 @@ static void print_comments(char *comments, int length)
    c+=4;
    for (i=0;i<nb_fields;i++)
    {
-      if (c+4>=end)
+      if (c+4>end)
       {
          fprintf (stderr, "Invalid/corrupted comments\n");
          return;
       }
       len=readint(c, 0);
       c+=4;
-      if (c+len>=end)
+      if (c+len>end)
       {
          fprintf (stderr, "Invalid/corrupted comments\n");
          return;
index a041dda..53bcbc1 100644 (file)
@@ -71,14 +71,21 @@ int oe_write_page(ogg_page *page, FILE *fp)
 #define MAX_FRAME_BYTES 2000
 
 /* Convert input audio bits, endians and channels */
-int read_samples(FILE *fin,int frame_size, int bits, int channels, int lsb, float * input)
+static int read_samples(FILE *fin,int frame_size, int bits, int channels, int lsb, float * input, char *buff)
 {   
    unsigned char in[MAX_FRAME_BYTES*2];
    int i;
    short *s;
 
    /*Read input audio*/
-   fread(in,bits/8*channels, frame_size, fin);
+   if (buff)
+   {
+      for (i=0;i<12;i++)
+         in[i]=buff[i];
+      fread(in+12,1,bits/8*channels*frame_size-12, fin);
+   } else {
+      fread(in,bits/8*channels, frame_size, fin);
+   }
    if (feof(fin))
       return 1;
    s=(short*)in;
@@ -237,6 +244,8 @@ int main(int argc, char **argv)
    int eos=0;
    int bitrate=0;
    int cumul_bits=0, enc_frames=0;
+   char first_bytes[12];
+   int wave_input=0;
    comment_init(&comments, &comments_length, vendor_string);
 
    /*Process command-line options*/
@@ -399,11 +408,16 @@ int main(int argc, char **argv)
       close_in=1;
    }
 
-   if (strcmp(inFile+strlen(inFile)-4,".wav")==0 || strcmp(inFile+strlen(inFile)-4,".WAV")==0)
    {
-      if (read_wav_header(fin, &rate, &chan, &fmt, &size)==-1)
-         exit(1);
-      lsb=1; /* CHECK: exists big-endian .wav ?? */
+      fread(first_bytes, 1, 12, fin);
+      if (strncmp(first_bytes,"RIFF",4)==0 && strncmp(first_bytes,"RIFF",4)==0)
+      {
+         size = le_int((*(int*)(first_bytes+4))-36);
+         if (read_wav_header(fin, &rate, &chan, &fmt, &size)==-1)
+            exit(1);
+         wave_input=1;
+         lsb=1; /* CHECK: exists big-endian .wav ?? */
+      }
    }
 
    if (!mode && !rate)
@@ -584,9 +598,14 @@ int main(int argc, char **argv)
 
    speex_bits_init(&bits);
 
-   if (read_samples(fin,frame_size,fmt,chan,lsb,input))
-      eos=1;
-
+   if (!wave_input)
+   {
+      if (read_samples(fin,frame_size,fmt,chan,lsb,input, first_bytes))
+         eos=1;
+   } else {
+      if (read_samples(fin,frame_size,fmt,chan,lsb,input, NULL))
+         eos=1;
+   }
    /*Main encoding loop (one frame per iteration)*/
    while (!eos)
    {
@@ -610,7 +629,7 @@ int main(int argc, char **argv)
          
       }
 
-      if (read_samples(fin,frame_size,fmt,chan,lsb,input))
+      if (read_samples(fin,frame_size,fmt,chan,lsb,input, NULL))
       {
          eos=1;
          op.e_o_s = 1;
index 81f45c8..f5fc2b9 100644 (file)
@@ -41,8 +41,11 @@ int read_wav_header(FILE *file, int *rate, int *channels, int *format, int *size
    short stmp;
    int bpersec;
    short balign;
+   int skip_bytes;
+   int i;
 
    ch[4]=0;
+#if 0
    fread(ch, 1, 4, file);
    if (strcmp(ch, "RIFF")!=0)
    {
@@ -59,22 +62,35 @@ int read_wav_header(FILE *file, int *rate, int *channels, int *format, int *size
       fprintf (stderr, "RIFF file is not a WAVE file\n");
       return -1;
    }
-
+#endif
    fread(ch, 1, 4, file);
-   if (strcmp(ch, "fmt ")!=0)
+   while (strcmp(ch, "fmt ")!=0)
+   {
+      fread(&itmp, 4, 1, file);
+      itmp = le_int(itmp);
+      /*fprintf (stderr, "skip=%d\n", itmp);*/
+      /*strange way of seeking, but it works even for pipes*/
+      for (i=0;i<itmp;i++)
+         fgetc(file);
+      /*fseek(file, itmp, SEEK_CUR);*/
+      fread(ch, 1, 4, file);
+      if (feof(file))
+      {
+         fprintf (stderr, "Corrupted WAVE file: no \"fmt \"\n");
+         return -1;
+      }
+   }
+   /*if (strcmp(ch, "fmt ")!=0)
    {
       fprintf (stderr, "Corrupted WAVE file: no \"fmt \"\n");
       return -1;
-   }
+      }*/
    
    fread(&itmp, 4, 1, file);
    itmp = le_int(itmp);
-   if (itmp!=16)
-   {
-      fprintf (stderr, "Unsupported WAVE file fmt chunk, not PCM?\n");
-      return -1;
-   }
-
+   skip_bytes=itmp-16;
+   /*fprintf (stderr, "skip=%d\n", skip_bytes);*/
+   
    fread(&stmp, 2, 1, file);
    stmp = le_short(stmp);
    if (stmp!=1)
@@ -129,17 +145,36 @@ int read_wav_header(FILE *file, int *rate, int *channels, int *format, int *size
       return -1;
    }
 
+   
+   /*strange way of seeking, but it works even for pipes*/
+   if (skip_bytes>0)
+      for (i=0;i<skip_bytes;i++)
+         fgetc(file);
+
+   /*fseek(file, skip_bytes, SEEK_CUR);*/
+
    fread(ch, 1, 4, file);
-   if (strcmp(ch, "data")!=0)
+   while (strcmp(ch, "data")!=0)
    {
-      fprintf (stderr, "Corrupted WAVE file: no \"data\"\n");
-      return -1;
+      fread(&itmp, 4, 1, file);
+      itmp = le_int(itmp);
+      /*strange way of seeking, but it works even for pipes*/
+      for (i=0;i<itmp;i++)
+         fgetc(file);
+      /*fseek(file, itmp, SEEK_CUR);*/
+      fread(ch, 1, 4, file);
+      if (feof(file))
+      {
+         fprintf (stderr, "Corrupted WAVE file: no \"data\"\n");
+         return -1;
+      }
    }
 
    /*Ignore this for now*/
    fread(&itmp, 4, 1, file);
    itmp = le_int(itmp);
 
+   *size=itmp;
 
    return 1;
 }