First stereo support in encoder (might be buggy), not in decoder yet.
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Thu, 7 Nov 2002 06:10:37 +0000 (06:10 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Thu, 7 Nov 2002 06:10:37 +0000 (06:10 +0000)
git-svn-id: http://svn.xiph.org/trunk/speex@4084 0101bb08-14d6-0310-b084-bc0e0c8e3800

libspeex/ltp.c
libspeex/speex_callbacks.h
libspeex/stereo.c
src/speexenc.c
src/wav_io.c

index 83f6095..e426568 100644 (file)
@@ -238,6 +238,15 @@ int  *cdbk_index
          for (j=0;j<9;j++)
             sum+=C[j]*ptr[j+3];
          if (0) {
+            float tot = fabs(ptr[1]);
+            if (ptr[0]>0)
+               tot+=ptr[0];
+            if (ptr[2]>0)
+               tot+=ptr[2];
+            if (tot>1)
+               continue;
+         }
+         if (0) {
             float tot=ptr[0]+ptr[1]+ptr[2];
             if (tot < 1.1)
                sum *= 1+.15*tot;
index 7ea0b5d..9f76781 100644 (file)
@@ -60,9 +60,12 @@ extern "C" {
 /*These are 8-bit requests*/
 /** Send a character in-band */
 #define SPEEX_INBAND_CHAR                8
+#define SPEEX_INBAND_STEREO              9
 
+/*These are 16-bit requests*/
 #define SPEEX_INBAND_MAX_BITRATE         10
 
+/*These are 32-bit requests*/
 #define SPEEX_INBAND_ACKNOWLEDGE         12
 
 /** Callback function type */
index 824a407..4885d4e 100644 (file)
 */
 
 #include "speex_stereo.h"
+#include "speex_callbacks.h"
+#include "vq.h"
+#include <math.h>
 
-void encode_stereo(float *data, int frame_size, SpeexBits *bits)
+/*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;
+   int i, tmp;
    float e_left=0, e_right=0, e_tot=0;
    float balance, e_ratio;
    for (i=0;i<frame_size;i++)
    {
       e_left  += data[2*i]*data[2*i];
       e_right += data[2*i+1]*data[2*i+1];
-      data[i] =  data[2*i]+data[2*i+1];
+      data[i] =  .5*(data[2*i]+data[2*i+1]);
       e_tot   += data[i]*data[i];
    }
    balance=(e_left+1)/(e_right+1);
    e_ratio = e_tot/(1+e_left+e_right);
+
+   /*Quantization*/
+   speex_bits_pack(bits, 14, 5);
+   speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);
+   
+   balance=4*log(balance);
+
+   /*Pack sign*/
+   if (balance>0)
+      speex_bits_pack(bits, 0, 1);
+   else
+      speex_bits_pack(bits, 1, 1);
+   balance=floor(.5+fabs(balance));
+   if (balance>30)
+      balance=31;
+   
+   speex_bits_pack(bits, (int)balance, 5);
    
+   /*Quantize energy ratio*/
+   tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4);
+   speex_bits_pack(bits, tmp, 2);
 }
 
-void decode_stereo(float *data, int frame_size, SpeexStereoState *stereo)
+void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo)
 {
    float balance, e_ratio;
    int i;
@@ -72,3 +100,22 @@ void decode_stereo(float *data, int frame_size, SpeexStereoState *stereo)
       data[2*i+1] = e_right*data[i];
    }
 }
+
+
+int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data)
+{
+   SpeexStereoState *stereo;
+   float sign=1;
+   int tmp;
+
+   stereo = (SpeexStereoState*)data;
+   if (speex_bits_unpack_unsigned(bits, 1))
+      sign=-1;
+   tmp = speex_bits_unpack_unsigned(bits, 5);
+   stereo->balance = sign*exp(.25*tmp);
+
+   tmp = speex_bits_unpack_unsigned(bits, 2);
+   stereo->e_ratio = e_ratio_quant[tmp];
+
+   return 0;
+}
index 80306e1..73ed967 100644 (file)
@@ -100,6 +100,7 @@ int read_samples(FILE *fin,int frame_size, int bits, int channels, int lsb, floa
       }
    }
 
+#if 0
    if(channels==2)
    {
       /* downmix to mono */
@@ -109,9 +110,10 @@ int read_samples(FILE *fin,int frame_size, int bits, int channels, int lsb, floa
          s[i]=d>>1;
       }
    }
+#endif
 
    /* copy to float input buffer */
-   for (i=0;i<frame_size;i++)
+   for (i=0;i<frame_size*channels;i++)
    {
       input[i]=(short)s[i];
    }
@@ -155,6 +157,7 @@ void usage()
    printf (" --be               Raw input is big-endian\n"); 
    printf (" --8bit             Raw input is 8-bit unsigned\n"); 
    printf (" --16bit            Raw input is 16-bit signed\n"); 
+   printf (" --stereo           Consider input as stereo\n"); 
    printf ("Default raw PCM input is 16-bit, little-endian, mono\n"); 
    printf ("\n");
    printf ("More information is available from the Speex site: http://www.speex.org\n");
@@ -196,6 +199,7 @@ int main(int argc, char **argv)
       {"be", no_argument, NULL, 0},
       {"lin8", no_argument, NULL, 0},
       {"lin16", no_argument, NULL, 0},
+      {"stereo", no_argument, NULL, 0},
       {"version", no_argument, NULL, 0},
       {"comment", required_argument, NULL, 0},
       {"author", required_argument, NULL, 0},
@@ -278,6 +282,9 @@ int main(int argc, char **argv)
          } else if (strcmp(long_options[option_index].name,"lin16")==0)
          {
             fmt=16;
+         } else if (strcmp(long_options[option_index].name,"stereo")==0)
+         {
+            chan=2;
          } else if (strcmp(long_options[option_index].name,"comment")==0)
          {
            comment_add(&comments, &comments_length, NULL, optarg); 
@@ -527,6 +534,8 @@ int main(int argc, char **argv)
    {
       id++;
       /*Encode current frame*/
+      if (chan==2)
+         speex_encode_stereo(input, frame_size, &bits);
       speex_encode(st, input, &bits);
       
       if (print_bitrate) {
index afac8fd..81f45c8 100644 (file)
@@ -87,9 +87,9 @@ int read_wav_header(FILE *file, int *rate, int *channels, int *format, int *size
    stmp = le_short(stmp);
    *channels = stmp;
    
-   if (stmp>1)
+   if (stmp>2)
    {
-      fprintf (stderr, "Only mono supported for now\n");
+      fprintf (stderr, "Only mono and (intensity) stereo supported\n");
       return -1;
    }