[xiph-cvs] cvs commit: speex/src speexdec.c speexenc.c

Jean-Marc Valin jm at xiph.org
Thu Nov 7 14:13:16 PST 2002



jm          02/11/07 17:13:16

  Modified:    libspeex Makefile.am speex_stereo.h stereo.c
               src      speexdec.c speexenc.c
  Log:
  Implemented stereo at the decoder side

Revision  Changes    Path
1.46      +2 -2      speex/libspeex/Makefile.am

Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/speex/libspeex/Makefile.am,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -r1.45 -r1.46
--- Makefile.am	5 Nov 2002 15:57:19 -0000	1.45
+++ Makefile.am	7 Nov 2002 22:13:15 -0000	1.46
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in. -*-Makefile-*-
 
-# $Id: Makefile.am,v 1.45 2002/11/05 15:57:19 jm Exp $
+# $Id: Makefile.am,v 1.46 2002/11/07 22:13:15 jm Exp $
 
 # Disable automatic dependency tracking if using other tools than gcc and gmake
 #AUTOMAKE_OPTIONS = no-dependencies
@@ -60,7 +60,7 @@
         ltp_sse.h \
         filters_sse.h \
         math_approx.h \
-	stereo.h
+	speex_stereo.h
         
         
 libspeex_la_LDFLAGS = -release $(LT_RELEASE)

<p><p>1.2       +5 -3      speex/libspeex/speex_stereo.h

Index: speex_stereo.h
===================================================================
RCS file: /usr/local/cvsroot/speex/libspeex/speex_stereo.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- speex_stereo.h	5 Nov 2002 15:57:19 -0000	1.1
+++ speex_stereo.h	7 Nov 2002 22:13:15 -0000	1.2
@@ -39,10 +39,12 @@
    float e_ratio;
 } SpeexStereoState;
 
-#define SPEEX_DEFAULT_STEREO_STATE {1,2}
+#define SPEEX_STEREO_STATE_INIT {1,.5}
 
-void encode_stereo(float *data, int frame_size, SpeexBits *bits);
+void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits);
 
-void decode_stereo(float *data, int frame_size, SpeexStereoState *stereo);
+void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo);
+
+int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data);
 
 #endif

<p><p>1.3       +8 -9      speex/libspeex/stereo.c

Index: stereo.c
===================================================================
RCS file: /usr/local/cvsroot/speex/libspeex/stereo.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- stereo.c	7 Nov 2002 06:10:37 -0000	1.2
+++ stereo.c	7 Nov 2002 22:13:15 -0000	1.3
@@ -37,8 +37,6 @@
 /*float e_ratio_quant[4] = {1, 1.26, 1.587, 2};*/
 static float e_ratio_quant[4] = {.25, .315, .397, .5};
 
-#include <stdio.h>
-
 void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits)
 {
    int i, tmp;
@@ -81,9 +79,10 @@
    float balance, e_ratio;
    int i;
    float e_tot=0, e_left, e_right, e_sum;
+
    balance=stereo->balance;
    e_ratio=stereo->e_ratio;
-   for (i=frame_size-1;i>=0;i++)
+   for (i=frame_size-1;i>=0;i--)
    {
       e_tot += data[i]*data[i];
    }
@@ -93,15 +92,15 @@
 
    e_left  = sqrt(e_left/e_tot);
    e_right = sqrt(e_right/e_tot);
-   
-   for (i=frame_size-1;i>=0;i++)
+
+   for (i=frame_size-1;i>=0;i--)
    {
-      data[2*i] = e_left*data[i];
-      data[2*i+1] = e_right*data[i];
+      float ftmp=data[i];
+      data[2*i] = e_left*ftmp;
+      data[2*i+1] = e_right*ftmp;
    }
 }
 
-
 int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data)
 {
    SpeexStereoState *stereo;
@@ -112,7 +111,7 @@
    if (speex_bits_unpack_unsigned(bits, 1))
       sign=-1;
    tmp = speex_bits_unpack_unsigned(bits, 5);
-   stereo->balance = sign*exp(.25*tmp);
+   stereo->balance = exp(sign*.25*tmp);
 
    tmp = speex_bits_unpack_unsigned(bits, 2);
    stereo->e_ratio = e_ratio_quant[tmp];

<p><p>1.56      +44 -12    speex/src/speexdec.c

Index: speexdec.c
===================================================================
RCS file: /usr/local/cvsroot/speex/src/speexdec.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -r1.55 -r1.56
--- speexdec.c	6 Nov 2002 21:27:31 -0000	1.55
+++ speexdec.c	7 Nov 2002 22:13:15 -0000	1.56
@@ -60,6 +60,8 @@
 #include <string.h>
 #include "wav_io.h"
 #include "speex_header.h"
+#include "speex_stereo.h"
+#include "speex_callbacks.h"
 #include "misc.h"
 
 #define MAX_FRAME_SIZE 2000
@@ -91,7 +93,7 @@
    }
 }
 
-FILE *out_file_open(char *outFile, int rate)
+FILE *out_file_open(char *outFile, int rate, int *channels)
 {
    FILE *fout=NULL;
    /*Open output file*/
@@ -110,6 +112,8 @@
       }
       
       stereo=0;
+      if (*channels=2)
+         stereo=1;
       if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo)==-1)
       {
          perror("SNDCTL_DSP_STEREO");
@@ -118,8 +122,10 @@
       }
       if (stereo!=0)
       {
+         if (*channels==1)
+            fprintf (stderr, "Cannot set mono mode, will decode in stereo\n");
+         *channels=2;
          fprintf (stderr, "Cannot set mono mode\n");
-         exit(1);
       }
 
       if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate)==-1)
@@ -160,7 +166,7 @@
             exit(1);
          }
          if (strcmp(outFile+strlen(outFile)-4,".wav")==0 || strcmp(outFile+strlen(outFile)-4,".WAV")==0)
-            write_wav_header(fout, rate, 1, 0, 0);
+            write_wav_header(fout, rate, *channels, 0, 0);
       }
    }
    return fout;
@@ -190,6 +196,8 @@
    printf (" --no-enh              Disable perceptual enhancement (default FOR NOW)\n");
    printf (" --force-nb            Force decoding in narrowband, even for wideband\n");
    printf (" --force-wb            Force decoding in wideband, even for narrowband\n");
+   printf (" --mono                Force decoding in mono\n");
+   printf (" --stereo              Force decoding in stereo\n");
    printf (" --packet-loss n       Simulate n %% random packet loss\n");
    printf (" -V                    Verbose mode (show bit-rate)\n"); 
    printf (" -h, --help            This help\n");
@@ -207,13 +215,14 @@
    printf ("Speex decoder version " VERSION " (compiled " __DATE__ ")\n");
 }
 
-static void *process_header(ogg_packet *op, int enh_enabled, int *frame_size, int *rate, int *nframes, int forceMode)
+static void *process_header(ogg_packet *op, int enh_enabled, int *frame_size, int *rate, int *nframes, int forceMode, int *channels, SpeexStereoState *stereo)
 {
    void *st;
    SpeexMode *mode;
    SpeexHeader *header;
    int modeID;
-   
+   SpeexCallback callback;
+      
    header = speex_packet_to_header((char*)op->packet, op->bytes);
    if (!header)
    {
@@ -246,6 +255,11 @@
    st = speex_decoder_init(mode);
    speex_decoder_ctl(st, SPEEX_SET_ENH, &enh_enabled);
    speex_decoder_ctl(st, SPEEX_GET_FRAME_SIZE, frame_size);
+
+   callback.callback_id = SPEEX_INBAND_STEREO;
+   callback.func = speex_std_stereo_request_handler;
+   callback.data = stereo;
+   speex_decoder_ctl(st, SPEEX_SET_HANDLER, &callback);
    
    /* FIXME: need to adjust in case the forceMode option is set */
    *rate = header->rate;
@@ -254,6 +268,9 @@
    if (header->mode==0 && forceMode==1)
       *rate*=2;
    *nframes = header->frames_per_packet;
+
+   if (*channels==-1)
+      *channels = header->nb_channels;
    
    fprintf (stderr, "Decoding %d Hz audio using %s mode", 
             *rate, mode->modeName);
@@ -292,6 +309,8 @@
       {"no-pf", no_argument, NULL, 0},
       {"force-nb", no_argument, NULL, 0},
       {"force-wb", no_argument, NULL, 0},
+      {"mono", no_argument, NULL, 0},
+      {"stereo", no_argument, NULL, 0},
       {"packet-loss", required_argument, NULL, 0},
       {0, 0, 0, 0}
    };
@@ -307,6 +326,8 @@
    int forceMode=-1;
    int audio_size=0;
    float loss_percent=-1;
+   SpeexStereoState stereo = SPEEX_STEREO_STATE_INIT;
+   int channels=-1;
 
    enh_enabled = 0;
 
@@ -349,6 +370,12 @@
          } else if (strcmp(long_options[option_index].name,"force-wb")==0)
          {
             forceMode=1;
+         } 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,"packet-loss")==0)
          {
             loss_percent = atof(optarg);
@@ -437,12 +464,12 @@
             if (packet_count==0)
             {
                int rate;
-               st = process_header(&op, enh_enabled, &frame_size, &rate, &nframes, forceMode);
+               st = process_header(&op, enh_enabled, &frame_size, &rate, &nframes, forceMode, &channels, &stereo);
                if (!nframes)
                   nframes=1;
                if (!st)
                   exit(1);
-               fout = out_file_open(outFile, rate);
+               fout = out_file_open(outFile, rate, &channels);
 
             } else if (packet_count==1){
                print_comments((char*)op.packet, op.bytes);
@@ -471,6 +498,9 @@
                   else
                      speex_decode(st, NULL, output);
 
+                  if (channels==2)
+                     speex_decode_stereo(output, frame_size, &stereo);
+
                   if (print_bitrate) {
                      int tmp;
                      char ch=13;
@@ -479,7 +509,7 @@
                      fprintf (stderr, "Bitrate is use: %d bps     ", tmp);
                   }
                   /*PCM saturation (just in case)*/
-                  for (i=0;i<frame_size;i++)
+                  for (i=0;i<frame_size*channels;i++)
                   {
                      if (output[i]>32000.0)
                         output[i]=32000.0;
@@ -487,15 +517,17 @@
                         output[i]=-32000.0;
                   }
                   /*Convert to short and save to output file*/
-                  for (i=0;i<frame_size;i++)
+                  for (i=0;i<frame_size*channels;i++)
                      out[i]=(short)le_short((short)output[i]);
 #if defined WIN32 || defined _WIN32
                   if (strlen(outFile)==0)
-                      WIN_Play_Samples (out, sizeof(short) * frame_size);
+                      WIN_Play_Samples (out, sizeof(short) * frame_size*channels);
                   else
 #endif
-                  fwrite(out, sizeof(short), frame_size, fout);
-                  audio_size+=sizeof(short)*frame_size;
+                  fwrite(out, sizeof(short), frame_size*channels, fout);
+                  
+                  /*FIXME: Not sure we should multiply by channels here*/
+                  audio_size+=sizeof(short)*frame_size*channels;
                }
             }
             packet_count++;

<p><p>1.56      +2 -0      speex/src/speexenc.c

Index: speexenc.c
===================================================================
RCS file: /usr/local/cvsroot/speex/src/speexenc.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -r1.55 -r1.56
--- speexenc.c	7 Nov 2002 06:10:37 -0000	1.55
+++ speexenc.c	7 Nov 2002 22:13:16 -0000	1.56
@@ -42,6 +42,7 @@
 #include <ogg/ogg.h>
 #include "wav_io.h"
 #include "speex_header.h"
+#include "speex_stereo.h"
 #include "misc.h"
 
 #if defined WIN32 || defined _WIN32
@@ -441,6 +442,7 @@
    speex_init_header(&header, rate, 1, mode);
    header.frames_per_packet=nframes;
    header.vbr=vbr_enabled;
+   header.nb_channels = chan;
 
    fprintf (stderr, "Encoding %d Hz audio using %s mode\n", 
             header.rate, mode->modeName);

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list