[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