Making multistream variable duration work for both the float and int API
authorJean-Marc Valin <jmvalin@jmvalin.ca>
Thu, 20 Dec 2012 05:23:01 +0000 (00:23 -0500)
committerJean-Marc Valin <jmvalin@jmvalin.ca>
Mon, 11 Feb 2013 04:53:44 +0000 (23:53 -0500)
src/opus_encoder.c
src/opus_multistream_encoder.c
src/opus_private.h

index bcfe6b4..19778a4 100644 (file)
@@ -665,11 +665,36 @@ static int transient_viterbi(const float *E, const float *E_1, int N, int frame_
    return best_state;
 }
 
+void downmix_float(const void *_x, float *sub, int subframe, int i, int C)
+{
+   const float *x;
+   int c, j;
+   x = (const float *)_x;
+   for (j=0;j<subframe;j++)
+      sub[j] = x[(subframe*i+j)*C];
+   for (c=1;c<C;c++)
+      for (j=0;j<subframe;j++)
+         sub[j] += x[(subframe*i+j)*C+c];
+}
+
+void downmix_int(const void *_x, float *sub, int subframe, int i, int C)
+{
+   const opus_int16 *x;
+   int c, j;
+   x = (const opus_int16 *)_x;
+   for (j=0;j<subframe;j++)
+      sub[j] = x[(subframe*i+j)*C];
+   for (c=1;c<C;c++)
+      for (j=0;j<subframe;j++)
+         sub[j] += x[(subframe*i+j)*C+c];
+}
+
 int optimize_framesize(const opus_val16 *x, int len, int C, opus_int32 Fs,
-                int bitrate, opus_val16 tonality, opus_val32 *mem, int buffering)
+                int bitrate, opus_val16 tonality, opus_val32 *mem, int buffering,
+                downmix_func downmix)
 {
    int N;
-   int i, c;
+   int i;
    float e[MAX_DYNAMIC_FRAMESIZE+4];
    float e_1[MAX_DYNAMIC_FRAMESIZE+3];
    float memx;
@@ -700,8 +725,6 @@ int optimize_framesize(const opus_val16 *x, int len, int C, opus_int32 Fs,
    }
    N=IMIN(len/subframe, MAX_DYNAMIC_FRAMESIZE);
    memx = x[0];
-   for (c=1;c<C;c++)
-      memx += x[c];
    for (i=0;i<N;i++)
    {
       float tmp;
@@ -709,12 +732,9 @@ int optimize_framesize(const opus_val16 *x, int len, int C, opus_int32 Fs,
       int j;
       tmp=EPSILON;
 
-      for (j=0;j<subframe;j++)
-         sub[j] = x[(subframe*i+j)*C];
-      for (c=1;c<C;c++)
-         for (j=0;j<subframe;j++)
-            sub[j] += x[(subframe*i+j)*C+c];
-
+      downmix(x, sub, subframe, i, C);
+      if (i==0)
+         memx = sub[0];
       for (j=0;j<subframe;j++)
       {
          tmpx = sub[j];
@@ -806,7 +826,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
        int LM = 3;
 #ifndef FIXED_POINT
        LM = optimize_framesize(pcm, frame_size, st->channels, st->Fs, st->bitrate_bps,
-             st->analysis.prev_tonality, st->subframe_mem, delay_compensation);
+             st->analysis.prev_tonality, st->subframe_mem, delay_compensation, downmix_float);
 #endif
        while ((st->Fs/400<<LM)>frame_size)
           LM--;
@@ -1167,6 +1187,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
        RESTORE_STACK;
        return ret;
     }
+#ifndef FIXED_POINT
     /* Perform analysis for 40-60 ms frames */
     if (perform_analysis && frame_size > st->Fs/50)
     {
@@ -1175,7 +1196,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
           tonality_analysis(&st->analysis, &analysis_info, celt_enc, pcm+i*(st->Fs/100)*st->channels, 480, st->channels, lsb_depth);
        st->voice_ratio = (int)floor(.5+100*(1-analysis_info.music_prob));
     }
-
+#endif
     curr_bandwidth = st->bandwidth;
 
     /* Chooses the appropriate mode for speech
index 1b41c65..c5fb366 100644 (file)
@@ -185,6 +185,9 @@ static int opus_multistream_encode_native
     unsigned char *data,
     opus_int32 max_data_bytes,
     int lsb_depth
+#ifndef FIXED_POINT
+    , downmix_func downmix
+#endif
 )
 {
    opus_int32 Fs;
@@ -221,7 +224,7 @@ static int opus_multistream_encode_native
       delay_compensation -= Fs/400;
 #ifndef FIXED_POINT
       LM = optimize_framesize(pcm, frame_size, channels, Fs, st->bitrate_bps,
-            0.f, st->subframe_mem, delay_compensation);
+            0.f, st->subframe_mem, delay_compensation, downmix);
 #endif
       while ((Fs/400<<LM)>frame_size)
          LM--;
@@ -410,7 +413,7 @@ int opus_multistream_encode_float
 )
 {
    return opus_multistream_encode_native(st, opus_copy_channel_in_float,
-      pcm, frame_size, data, max_data_bytes, 24);
+      pcm, frame_size, data, max_data_bytes, 24, downmix_float);
 }
 
 int opus_multistream_encode(
@@ -422,7 +425,7 @@ int opus_multistream_encode(
 )
 {
    return opus_multistream_encode_native(st, opus_copy_channel_in_short,
-      pcm, frame_size, data, max_data_bytes, 16);
+      pcm, frame_size, data, max_data_bytes, 16, downmix_int);
 }
 #endif
 
index 94de003..33a982e 100644 (file)
@@ -81,8 +81,13 @@ int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev);
 #define OPUS_SET_FORCE_MODE_REQUEST    11002
 #define OPUS_SET_FORCE_MODE(x) OPUS_SET_FORCE_MODE_REQUEST, __opus_check_int(x)
 
+typedef void (*downmix_func)(const void *, float *, int, int, int);
+void downmix_float(const void *_x, float *sub, int subframe, int i, int C);
+void downmix_int(const void *_x, float *sub, int subframe, int i, int C);
+
 int optimize_framesize(const opus_val16 *x, int len, int C, opus_int32 Fs,
-                int bitrate, opus_val16 tonality, opus_val32 *mem, int buffering);
+                int bitrate, opus_val16 tonality, opus_val32 *mem, int buffering,
+                void (*downmix)(const void *, float *, int, int, int));
 
 int encode_size(int size, unsigned char *data);