Encoder now understands wav files, slight modif to LSP quantization
authorjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Wed, 5 Jun 2002 06:07:18 +0000 (06:07 +0000)
committerjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Wed, 5 Jun 2002 06:07:18 +0000 (06:07 +0000)
weighting

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

libspeex/Makefile.am
libspeex/quant_lsp.c
libspeex/speex_header.h [new file with mode: 0644]
src/Makefile.am
src/speexenc.c
src/wav_io.c [new file with mode: 0644]

index 8f1bee3..ccead19 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in. -*-Makefile-*-
 
-# $Id: Makefile.am,v 1.29 2002/05/29 03:41:28 jmvalin Exp $
+# $Id: Makefile.am,v 1.30 2002/06/05 06:07:18 jmvalin Exp $
 
 # Disable automatic dependency tracking if using other tools than gcc and gmake
 #AUTOMAKE_OPTIONS = no-dependencies
@@ -31,7 +31,8 @@ libspeex_la_SOURCES = nb_celp.c \
 
 
 include_HEADERS =  speex.h \
-       speex_bits.h
+       speex_bits.h \
+       speex_header.h
 
 noinst_HEADERS = lsp.h \
        nb_celp.h \
index 745d1ce..e93f1ec 100644 (file)
@@ -95,8 +95,13 @@ void lsp_quant_nb(float *lsp, float *qlsp, int order, SpeexBits *bits)
    quant_weight[order-1] = 1/(qlsp[order-1]-qlsp[order-2]);
    for (i=1;i<order-1;i++)
    {
+#if 1
+      tmp1 = 1/((.15+qlsp[i]-qlsp[i-1])*(.15+qlsp[i]-qlsp[i-1]));
+      tmp2 = 1/((.15+qlsp[i+1]-qlsp[i])*(.15+qlsp[i+1]-qlsp[i]));
+#else
       tmp1 = 1/(qlsp[i]-qlsp[i-1]);
       tmp2 = 1/(qlsp[i+1]-qlsp[i]);
+#endif
       quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2;
    }
    id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);
diff --git a/libspeex/speex_header.h b/libspeex/speex_header.h
new file mode 100644 (file)
index 0000000..1688dab
--- /dev/null
@@ -0,0 +1,32 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: speex_header.h
+
+   Describes the different modes of the codec
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+   
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+   
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+
+#ifndef SPEEX_HEADER_H
+#define SPEEX_HEADER_H
+
+typedef struct SpeexHeader {
+   int rate;
+   int mode;
+   int nb_channels;
+} SpeexHeader;
+
+#endif
index 7c7a577..c226b81 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in. -*-Makefile-*-
 
-# $Id: Makefile.am,v 1.3 2002/05/15 21:47:51 jmvalin Exp $
+# $Id: Makefile.am,v 1.4 2002/06/05 06:07:18 jmvalin Exp $
 
 # Disable automatic dependency tracking if using other tools than gcc and gmake
 #AUTOMAKE_OPTIONS = no-dependencies
@@ -12,8 +12,8 @@ noinst_HEADERS =
 
 bin_PROGRAMS = speexenc speexdec
 
-speexenc_SOURCES = speexenc.c
+speexenc_SOURCES = speexenc.c wav_io.c
 speexenc_LDADD = $(top_srcdir)/libspeex/libspeex.la $(LIB_OGG)
 
-speexdec_SOURCES = speexdec.c
+speexdec_SOURCES = speexdec.c wav_io.c
 speexdec_LDADD = $(top_srcdir)/libspeex/libspeex.la $(LIB_OGG)
index 4c1eb8d..e91fef5 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "speex.h"
 #include <ogg/ogg.h>
+#include "wav_io.h"
 
 /*Write an Ogg page to a file pointer*/
 int oe_write_page(ogg_page *page, FILE *fp)
@@ -77,6 +78,7 @@ int main(int argc, char **argv)
       {"version", no_argument, NULL, 0},
       {0, 0, 0, 0}
    };
+   int rate, chan, fmt, size;
 
    ogg_stream_state os;
    ogg_page             og;
@@ -136,27 +138,18 @@ int main(int argc, char **argv)
    inFile=argv[optind];
    outFile=argv[optind+1];
 
-   /*Initialize Ogg stream struct*/
-   if (ogg_stream_init(&os, 0)==-1)
-   {
-      fprintf(stderr,"Stream init failed\n");
-      exit(1);
-   }
-
    if (wideband && narrowband)
    {
       fprintf (stderr,"Cannot specify both wideband and narrowband at the same time\n");
       exit(1);
    };
-   if (!wideband)
-      narrowband=1;
-   if (narrowband)
-      mode=&speex_nb_mode;
-   if (wideband)
-      mode=&speex_wb_mode;
 
-   /*Initialize Speex encoder*/
-   st = speex_encoder_init(mode);
+   /*Initialize Ogg stream struct*/
+   if (ogg_stream_init(&os, 0)==-1)
+   {
+      fprintf(stderr,"Stream init failed\n");
+      exit(1);
+   }
 
    if (strcmp(inFile, "-")==0)
       fin=stdin;
@@ -169,6 +162,35 @@ int main(int argc, char **argv)
          exit(1);
       }
    }
+
+   rate=0;
+   if (strcmp(inFile+strlen(inFile)-4,".wav")==0)
+      if (read_wav_header(fin, &rate, &chan, &fmt, &size)==-1)
+         exit(1);
+   /*fprintf (stderr, "wave info: %d %d %d %d\n", rate, chan, fmt, size);*/
+
+   if (rate==16000)
+   {
+      wideband=1;
+      if (narrowband)
+         fprintf (stderr,"Warning: encoding a wideband file in narrowband\n");
+   } else if (rate==8000)
+   {
+      narrowband=1;
+      if (wideband)
+         fprintf (stderr,"Warning: encoding a narrowband file in wideband\n");
+   }
+
+   if (!wideband)
+      narrowband=1;
+   if (narrowband)
+      mode=&speex_nb_mode;
+   if (wideband)
+      mode=&speex_wb_mode;
+
+   /*Initialize Speex encoder*/
+   st = speex_encoder_init(mode);
+
    if (strcmp(outFile,"-")==0)
       fout=stdout;
    else 
@@ -181,6 +203,7 @@ int main(int argc, char **argv)
       }
    }
 
+
    /*Write header (format will change)*/
    {
 
diff --git a/src/wav_io.c b/src/wav_io.c
new file mode 100644 (file)
index 0000000..28743c1
--- /dev/null
@@ -0,0 +1,116 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: wav_io.c
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+   
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+   
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <stdio.h>
+#include <string.h>
+
+int read_wav_header(FILE *file, int *rate, int *channels, int *format, int *size)
+{
+   char ch[5];
+   int itmp;
+   short stmp;
+
+   ch[4]=0;
+   fread(ch, 1, 4, file);
+   if (strcmp(ch, "RIFF")!=0)
+   {
+      fseek(file, 0, SEEK_SET);
+      return 0;
+   }
+
+   fread(&itmp, 4, 1, file);
+   /*FIXME: swap bytes*/
+   *size = itmp-36;
+
+   fread(ch, 1, 4, file);
+   if (strcmp(ch, "WAVE")!=0)
+   {
+      fprintf (stderr, "RIFF file is not a WAVE file\n");
+      return -1;
+   }
+
+   fread(ch, 1, 4, file);
+   if (strcmp(ch, "fmt ")!=0)
+   {
+      fprintf (stderr, "Corrupted WAVE file: no \"fmt \"\n");
+      return -1;
+   }
+   
+   fread(&itmp, 4, 1, file);
+   /*FIXME: swap bytes*/
+   if (itmp!=16)
+   {
+      fprintf (stderr, "Only 16-bit PCM supported\n");
+      return -1;
+   }
+
+   fread(&stmp, 2, 1, file);
+   /*FIXME: swap bytes*/
+   if (stmp!=1)
+   {
+      fprintf (stderr, "Only 16-bit PCM supported\n");
+      return -1;
+   }
+
+   fread(&stmp, 2, 1, file);
+   /*FIXME: swap bytes*/
+   *channels = stmp;
+
+   fread(&itmp, 4, 1, file);
+   /*FIXME: swap bytes*/
+   *rate = itmp;
+
+   fread(&itmp, 4, 1, file);
+   /*FIXME: swap bytes*/
+   if (itmp!=*rate**channels*2)
+   {
+      fprintf (stderr, "Corrupted header: ByteRate mismatch\n");
+      return -1;
+   }
+
+   fread(&stmp, 2, 1, file);
+   /*FIXME: swap bytes*/
+   if (stmp!=*channels*2)
+   {
+      fprintf (stderr, "Corrupted header: BlockAlign mismatch\n");
+      return -1;
+   }
+
+   fread(&stmp, 2, 1, file);
+   /*FIXME: swap bytes*/
+   if (stmp!=16)
+   {
+      fprintf (stderr, "Only 16-bit linear supported\n");
+      return -1;
+   }
+
+   fread(ch, 1, 4, file);
+   if (strcmp(ch, "data")!=0)
+   {
+      fprintf (stderr, "Corrupted WAVE file: no \"data\"\n");
+      return -1;
+   }
+
+   /*Ignore this for now*/
+   fread(&itmp, 4, 1, file);
+   /*FIXME: swap bytes*/
+
+   *format=16;
+
+   return 1;
+}