Moves opus_compare to the same base64 tar.gz as the rest of the code
[opus.git] / src / opus_multistream.c
index b02636a..b5f7bba 100644 (file)
@@ -148,13 +148,13 @@ int opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams)
 
 
 int opus_multistream_encoder_init(
-      OpusMSEncoder *st,            /* Encoder state */
-      opus_int32 Fs,                     /* Sampling rate of input signal (Hz) */
-      int channels,               /* Number of channels (1/2) in input signal */
+      OpusMSEncoder *st,
+      opus_int32 Fs,
+      int channels,
       int streams,
       int coupled_streams,
       unsigned char *mapping,
-      int application             /* Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO) */
+      int application
 )
 {
    int coupled_size;
@@ -188,13 +188,13 @@ int opus_multistream_encoder_init(
 }
 
 OpusMSEncoder *opus_multistream_encoder_create(
-      opus_int32 Fs,                     /* Sampling rate of input signal (Hz) */
-      int channels,               /* Number of channels (1/2) in input signal */
+      opus_int32 Fs,
+      int channels,
       int streams,
       int coupled_streams,
       unsigned char *mapping,
-      int application,            /* Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO) */
-      int *error                  /* Error code */
+      int application,
+      int *error
 )
 {
    int ret;
@@ -222,11 +222,11 @@ int opus_multistream_encode(
 #else
 int opus_multistream_encode_float(
 #endif
-    OpusMSEncoder *st,            /* Encoder state */
-    const opus_val16 *pcm,      /* Input signal (interleaved if 2 channels). length is frame_size*channels */
-    int frame_size,             /* Number of samples per frame of input signal */
-    unsigned char *data,        /* Output payload (no more than max_data_bytes long) */
-    int max_data_bytes          /* Allocated memory for payload; don't use for controlling bitrate */
+    OpusMSEncoder *st,
+    const opus_val16 *pcm,
+    int frame_size,
+    unsigned char *data,
+    int max_data_bytes
 )
 {
    int coupled_size;
@@ -307,11 +307,11 @@ int opus_multistream_encode_float(
 
 #ifndef DISABLE_FLOAT_API
 int opus_multistream_encode_float(
-    OpusMSEncoder *st,          /* Encoder state */
-    const float *pcm,           /* Input signal (interleaved if 2 channels). length is frame_size*channels */
-    int frame_size,             /* Number of samples per frame of input signal */
-    unsigned char *data,        /* Output payload (no more than max_data_bytes long) */
-    int max_data_bytes          /* Allocated memory for payload; don't use for controlling bitrate */
+    OpusMSEncoder *st,
+    const float *pcm,
+    int frame_size,
+    unsigned char *data,
+    int max_data_bytes
 )
 {
    int i, ret;
@@ -331,11 +331,11 @@ int opus_multistream_encode_float(
 #else
 
 int opus_multistream_encode(
-    OpusMSEncoder *st,          /* Encoder state */
-    const opus_int16 *pcm,      /* Input signal (interleaved if 2 channels). length is frame_size*channels */
-    int frame_size,             /* Number of samples per frame of input signal */
-    unsigned char *data,        /* Output payload (no more than max_data_bytes long) */
-    int max_data_bytes          /* Allocated memory for payload; don't use for controlling bitrate */
+    OpusMSEncoder *st,
+    const opus_int16 *pcm,
+    int frame_size,
+    unsigned char *data,
+    int max_data_bytes
 )
 {
    int i, ret;
@@ -370,7 +370,7 @@ int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
    case OPUS_SET_BITRATE_REQUEST:
    {
       int chan, s;
-      opus_uint32 value = va_arg(ap, opus_uint32);
+      opus_int32 value = va_arg(ap, opus_int32);
       chan = st->layout.nb_streams + st->layout.nb_coupled_streams;
       value /= chan;
       for (s=0;s<st->layout.nb_streams;s++)
@@ -381,8 +381,21 @@ int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
       }
    }
    break;
-   /* FIXME: Add missing ones */
    case OPUS_GET_BITRATE_REQUEST:
+   {
+      int s;
+      opus_int32 *value = va_arg(ap, opus_int32*);
+      *value = 0;
+      for (s=0;s<st->layout.nb_streams;s++)
+      {
+         opus_int32 rate;
+         OpusEncoder *enc;
+         enc = (OpusEncoder*)ptr;
+         opus_encoder_ctl(enc, request, &rate);
+         *value += rate;
+      }
+   }
+   break;
    case OPUS_GET_VBR_REQUEST:
    case OPUS_GET_APPLICATION_REQUEST:
    case OPUS_GET_BANDWIDTH_REQUEST:
@@ -393,10 +406,28 @@ int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
    case OPUS_GET_VBR_CONSTRAINT_REQUEST:
    case OPUS_GET_SIGNAL_REQUEST:
    case OPUS_GET_LOOKAHEAD_REQUEST:
+   case OPUS_GET_INBAND_FEC_REQUEST:
+   {
+      OpusEncoder *enc;
+      /* For int32* GET params, just query the first stream */
+      opus_int32 *value = va_arg(ap, opus_int32*);
+      enc = (OpusEncoder*)ptr;
+      ret = opus_encoder_ctl(enc, request, value);
+   }
+   break;
+   case OPUS_SET_COMPLEXITY_REQUEST:
+   case OPUS_SET_VBR_REQUEST:
+   case OPUS_SET_VBR_CONSTRAINT_REQUEST:
+   case OPUS_SET_BANDWIDTH_REQUEST:
+   case OPUS_SET_SIGNAL_REQUEST:
+   case OPUS_SET_APPLICATION_REQUEST:
+   case OPUS_SET_INBAND_FEC_REQUEST:
+   case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
+   case OPUS_SET_DTX_REQUEST:
    {
       int s;
-      /* This works for int32* params */
-      opus_uint32 *value = va_arg(ap, opus_uint32*);
+      /* This works for int32 params */
+      opus_int32 value = va_arg(ap, opus_int32);
       for (s=0;s<st->layout.nb_streams;s++)
       {
          OpusEncoder *enc;
@@ -412,26 +443,28 @@ int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
       }
    }
    break;
-   default:
+   case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
    {
       int s;
-      /* This works for int32 params */
-      opus_uint32 value = va_arg(ap, opus_uint32);
-      for (s=0;s<st->layout.nb_streams;s++)
+      opus_int32 stream_id;
+      OpusEncoder **value;
+      stream_id = va_arg(ap, opus_int32);
+      if (stream_id<0 || stream_id >= st->layout.nb_streams)
+         ret = OPUS_BAD_ARG;
+      value = va_arg(ap, OpusEncoder**);
+      for (s=0;s<stream_id;s++)
       {
-         OpusEncoder *enc;
-
-         enc = (OpusEncoder*)ptr;
          if (s < st->layout.nb_coupled_streams)
             ptr += align(coupled_size);
          else
             ptr += align(mono_size);
-         ret = opus_encoder_ctl(enc, request, value);
-         if (ret < 0)
-            break;
       }
+      *value = (OpusEncoder*)ptr;
    }
-   break;
+      break;
+   default:
+      ret = OPUS_UNIMPLEMENTED;
+      break;
    }
 
    va_end(ap);
@@ -459,9 +492,9 @@ int opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams)
 }
 
 int opus_multistream_decoder_init(
-      OpusMSDecoder *st,            /* Encoder state */
-      opus_int32 Fs,                     /* Sampling rate of input signal (Hz) */
-      int channels,               /* Number of channels (1/2) in input signal */
+      OpusMSDecoder *st,
+      opus_int32 Fs,
+      int channels,
       int streams,
       int coupled_streams,
       unsigned char *mapping
@@ -500,12 +533,12 @@ int opus_multistream_decoder_init(
 
 
 OpusMSDecoder *opus_multistream_decoder_create(
-      opus_int32 Fs,                     /* Sampling rate of input signal (Hz) */
-      int channels,               /* Number of channels (1/2) in input signal */
+      opus_int32 Fs,
+      int channels,
       int streams,
       int coupled_streams,
       unsigned char *mapping,
-      int *error                  /* Error code */
+      int *error
 )
 {
    int ret;
@@ -530,7 +563,7 @@ OpusMSDecoder *opus_multistream_decoder_create(
 }
 
 static int opus_multistream_decode_native(
-      OpusMSDecoder *st,            /* Encoder state */
+      OpusMSDecoder *st,
       const unsigned char *data,
       int len,
       opus_val16 *pcm,
@@ -630,7 +663,7 @@ static int opus_multistream_decode_native(
 
 #ifdef FIXED_POINT
 int opus_multistream_decode(
-      OpusMSDecoder *st,            /* Encoder state */
+      OpusMSDecoder *st,
       const unsigned char *data,
       int len,
       opus_int16 *pcm,
@@ -684,7 +717,7 @@ int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,
 }
 
 int opus_multistream_decode_float(
-      OpusMSDecoder *st,            /* Encoder state */
+      OpusMSDecoder *st,
       const unsigned char *data,
       int len,
       float *pcm,
@@ -710,26 +743,66 @@ int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
    ptr = (char*)st + align(sizeof(OpusMSDecoder));
    switch (request)
    {
-       default:
+       case OPUS_GET_BANDWIDTH_REQUEST:
+       case OPUS_GET_FINAL_RANGE_REQUEST:
        {
           int s;
-          /* This only works for int32* params, but that's all we have right now */
           opus_uint32 *value = va_arg(ap, opus_uint32*);
           for (s=0;s<st->layout.nb_streams;s++)
           {
-             OpusDecoder *enc;
+             OpusDecoder *dec;
+
+             dec = (OpusDecoder*)ptr;
+             if (s < st->layout.nb_coupled_streams)
+                ptr += align(coupled_size);
+             else
+                ptr += align(mono_size);
+             ret = opus_decoder_ctl(dec, request, value);
+             if (ret < 0)
+                break;
+          }
+       }
+       break;
+       case OPUS_RESET_STATE:
+       {
+          int s;
+          for (s=0;s<st->layout.nb_streams;s++)
+          {
+             OpusDecoder *dec;
 
-             enc = (OpusDecoder*)ptr;
+             dec = (OpusDecoder*)ptr;
              if (s < st->layout.nb_coupled_streams)
                 ptr += align(coupled_size);
              else
                 ptr += align(mono_size);
-             ret = opus_decoder_ctl(enc, request, value);
+             ret = opus_decoder_ctl(dec, OPUS_RESET_STATE);
              if (ret < 0)
                 break;
           }
        }
        break;
+       case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST:
+       {
+          int s;
+          opus_int32 stream_id;
+          OpusDecoder **value;
+          stream_id = va_arg(ap, opus_int32);
+          if (stream_id<0 || stream_id >= st->layout.nb_streams)
+             ret = OPUS_BAD_ARG;
+          value = va_arg(ap, OpusDecoder**);
+          for (s=0;s<stream_id;s++)
+          {
+             if (s < st->layout.nb_coupled_streams)
+                ptr += align(coupled_size);
+             else
+                ptr += align(mono_size);
+          }
+          *value = (OpusDecoder*)ptr;
+       }
+          break;
+       default:
+          ret = OPUS_UNIMPLEMENTED;
+       break;
    }
 
    va_end(ap);