Moves the main headers from src/ to include/
[opus.git] / src / opus_decoder.c
index bd0886b..4f4d648 100644 (file)
 #include "opus.h"
 #include "entdec.h"
 #include "modes.h"
-#include "silk_API.h"
+#include "API.h"
 #include "stack_alloc.h"
 #include "float_cast.h"
 #include "opus_private.h"
 #include "os_support.h"
+#include "structs.h"
+#include "define.h"
 
 struct OpusDecoder {
    int          celt_dec_offset;
    int          silk_dec_offset;
    int          channels;
    opus_int32   Fs;          /** Sampling rate (at the API level) */
+   silk_DecControlStruct DecControl;
 
    /* Everything beyond this point gets cleared on a reset */
 #define OPUS_DECODER_RESET_START stream_channels
@@ -70,6 +73,8 @@ int opus_decoder_get_size(int channels)
 {
    int silkDecSizeBytes, celtDecSizeBytes;
    int ret;
+   if (channels<1 || channels > 2)
+      return 0;
    ret = silk_Get_Decoder_Size( &silkDecSizeBytes );
    if(ret)
       return 0;
@@ -84,8 +89,9 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
    CELTDecoder *celt_dec;
    int ret, silkDecSizeBytes;
 
-   if (channels<1 || channels > 2)
+   if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2))
       return OPUS_BAD_ARG;
+
    OPUS_CLEAR((char*)st, opus_decoder_get_size(channels));
    /* Initialize SILK encoder */
    ret = silk_Get_Decoder_Size(&silkDecSizeBytes);
@@ -99,6 +105,8 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
    st->stream_channels = st->channels = channels;
 
    st->Fs = Fs;
+   st->DecControl.API_sampleRate = st->Fs;
+   st->DecControl.nChannelsAPI      = st->channels;
 
    /* Reset decoder */
    ret = silk_InitDecoder( silk_dec );
@@ -118,7 +126,14 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
 OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)
 {
    int ret;
-   OpusDecoder *st = (OpusDecoder *)opus_alloc(opus_decoder_get_size(channels));
+   OpusDecoder *st;
+   if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2))
+   {
+      if (error)
+         *error = OPUS_BAD_ARG;
+      return NULL;
+   }
+   st = (OpusDecoder *)opus_alloc(opus_decoder_get_size(channels));
    if (st == NULL)
    {
       if (error)
@@ -175,7 +190,6 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
     CELTDecoder *celt_dec;
     int i, silk_ret=0, celt_ret=0;
     ec_dec dec;
-    silk_DecControlStruct DecControl;
     opus_int32 silk_frame_size;
     VARDECL(opus_int16, pcm_silk);
     VARDECL(opus_val16, pcm_transition);
@@ -231,9 +245,10 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
 
     ALLOC(pcm_transition, F5*st->channels, opus_val16);
 
-    if (data!=NULL && !st->prev_redundancy && mode != st->prev_mode && st->prev_mode > 0
-               && !(mode == MODE_SILK_ONLY && st->prev_mode == MODE_HYBRID)
-               && !(mode == MODE_HYBRID && st->prev_mode == MODE_SILK_ONLY))
+    if (data!=NULL && st->prev_mode > 0 && (
+            (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy)
+         || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) )
+         )
     {
        transition = 1;
        if (mode == MODE_CELT_ONLY)
@@ -248,7 +263,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
         frame_size = audiosize;
     }
 
-    ALLOC(pcm_silk, frame_size*st->channels, opus_int16);
+    ALLOC(pcm_silk, IMAX(F10, frame_size)*st->channels, opus_int16);
     ALLOC(redundant_audio, F5*st->channels, opus_val16);
 
     /* SILK processing */
@@ -260,24 +275,27 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
         if (st->prev_mode==MODE_CELT_ONLY)
                silk_InitDecoder( silk_dec );
 
-        DecControl.API_sampleRate = st->Fs;
-        DecControl.nChannelsAPI      = st->channels;
-        DecControl.nChannelsInternal = st->stream_channels;
-        DecControl.payloadSize_ms = 1000 * audiosize / st->Fs;
-        if( mode == MODE_SILK_ONLY ) {
-            if( st->bandwidth == OPUS_BANDWIDTH_NARROWBAND ) {
-                DecControl.internalSampleRate = 8000;
-            } else if( st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) {
-                DecControl.internalSampleRate = 12000;
-            } else if( st->bandwidth == OPUS_BANDWIDTH_WIDEBAND ) {
-                DecControl.internalSampleRate = 16000;
+        /* The SILK PLC cannot support produce frames of less than 10 ms */
+        st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs);
+
+        if (data != NULL)
+        {
+            st->DecControl.nChannelsInternal = st->stream_channels;
+            if( mode == MODE_SILK_ONLY ) {
+                if( st->bandwidth == OPUS_BANDWIDTH_NARROWBAND ) {
+                    st->DecControl.internalSampleRate = 8000;
+                } else if( st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) {
+                    st->DecControl.internalSampleRate = 12000;
+                } else if( st->bandwidth == OPUS_BANDWIDTH_WIDEBAND ) {
+                    st->DecControl.internalSampleRate = 16000;
+                } else {
+                    st->DecControl.internalSampleRate = 16000;
+                    silk_assert( 0 );
+                }
             } else {
-               DecControl.internalSampleRate = 16000;
-                SKP_assert( 0 );
+                /* Hybrid mode */
+                st->DecControl.internalSampleRate = 16000;
             }
-        } else {
-            /* Hybrid mode */
-            DecControl.internalSampleRate = 16000;
         }
 
         lost_flag = data == NULL ? 1 : 2 * decode_fec;
@@ -285,7 +303,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
         do {
             /* Call SILK decoder */
             int first_frame = decoded_samples == 0;
-            silk_ret = silk_Decode( silk_dec, &DecControl,
+            silk_ret = silk_Decode( silk_dec, &st->DecControl,
                 lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size );
             if( silk_ret ) {
                if (lost_flag) {
@@ -304,28 +322,26 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
     }
 
     start_band = 0;
-    if (mode != MODE_CELT_ONLY && data != NULL && ec_tell(&dec)+29+8*(st->mode == MODE_HYBRID) < 8*len)
+    if (!decode_fec && mode != MODE_CELT_ONLY && data != NULL && ec_tell(&dec)+17+20*(st->mode == MODE_HYBRID) <= 8*len)
     {
         /* Check if we have a redundant 0-8 kHz band */
-        redundancy = ec_dec_bit_logp(&dec, 12);
+        if (mode == MODE_HYBRID)
+           redundancy = ec_dec_bit_logp(&dec, 12);
+        else
+           redundancy = 1;
         if (redundancy)
         {
             celt_to_silk = ec_dec_bit_logp(&dec, 1);
-            if (mode == MODE_HYBRID)
-               redundancy_bytes = 2 + ec_dec_uint(&dec, 256);
-            else {
-               redundancy_bytes = len - ((ec_tell(&dec)+7)>>3);
-               /* Can only happen on an invalid packet */
-               if (redundancy_bytes<0)
-               {
-                       redundancy_bytes = 0;
-                       redundancy = 0;
-               }
-            }
+            /* redundancy_bytes will be at least two, in the non-hybrid case due to the ec_tell() check above */
+            redundancy_bytes = mode==MODE_HYBRID ? (opus_int32)ec_dec_uint(&dec, 256)+2 : len-((ec_tell(&dec)+7)>>3);
             len -= redundancy_bytes;
-            if (len<0) {
-               RESTORE_STACK;
-               return OPUS_INVALID_PACKET;
+            /* This is a sanity check. It should never happen for a valid packet,
+               so the exact behaviour is not normative. */
+            if (len*8 < ec_tell(&dec))
+            {
+               len=0;
+               redundancy_bytes=0;
+               redundancy = 0;
             }
             /* Shrink decoder because of raw bits */
             dec.storage -= redundancy_bytes;
@@ -369,23 +385,29 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
         celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
         celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL);
         celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
-        celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
     }
 
     /* MUST be after PLC */
     celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band));
 
-    if (transition)
-       celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
-
     if (mode != MODE_SILK_ONLY)
     {
-       int celt_frame_size = IMIN(F20, frame_size);
+        int celt_frame_size = IMIN(F20, frame_size);
+        /* Make sure to discard any previous CELT state */
+        if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy)
+            celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
         /* Decode CELT */
         celt_ret = celt_decode_with_ec(celt_dec, decode_fec?NULL:data, len, pcm, celt_frame_size, &dec);
     } else {
+       unsigned char silence[2] = {0xFF, 0xFF};
        for (i=0;i<frame_size*st->channels;i++)
           pcm[i] = 0;
+       /* For hybrid -> SILK transitions, we let the CELT MDCT do a fade-out by decoding a silence frame */
+       if (st->prev_mode == MODE_HYBRID)
+       {
+          celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
+          celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL);
+       }
     }
 
     if (mode != MODE_CELT_ONLY)
@@ -395,7 +417,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
             pcm[i] = SAT16(pcm[i] + pcm_silk[i]);
 #else
         for (i=0;i<frame_size*st->channels;i++)
-            pcm[i] = pcm[i] + (1./32768.)*pcm_silk[i];
+            pcm[i] = pcm[i] + (opus_val16)((1./32768.)*pcm_silk[i]);
 #endif
     }
 
@@ -428,12 +450,23 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
     }
     if (transition)
     {
-       for (i=0;i<st->channels*F2_5;i++)
-               pcm[i] = pcm_transition[i];
-       if (audiosize >= F5)
-           smooth_fade(pcm_transition+st->channels*F2_5, pcm+st->channels*F2_5,
-                   pcm+st->channels*F2_5, F2_5,
-                   st->channels, window, st->Fs);
+       if (audiosize >= F5)
+       {
+          for (i=0;i<st->channels*F2_5;i++)
+             pcm[i] = pcm_transition[i];
+          smooth_fade(pcm_transition+st->channels*F2_5, pcm+st->channels*F2_5,
+                pcm+st->channels*F2_5, F2_5,
+                st->channels, window, st->Fs);
+       } else {
+          /* Not enough time to do a clean transition, but we do it anyway
+             This will not preserve amplitude perfectly and may introduce
+             a bit of temporal aliasing, but it shouldn't be too bad and
+             that's pretty much the best we can do. In any case, generating this
+             transition it pretty silly in the first place */
+          smooth_fade(pcm_transition, pcm,
+                pcm, F2_5,
+                st->channels, window, st->Fs);
+       }
     }
 
     if (len <= 1)
@@ -442,7 +475,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
        st->rangeFinal = dec.rng ^ redundant_rng;
 
     st->prev_mode = mode;
-    st->prev_redundancy = redundancy;
+    st->prev_redundancy = redundancy && !celt_to_silk;
     RESTORE_STACK;
        return celt_ret<0 ? celt_ret : audiosize;
 
@@ -544,7 +577,7 @@ static int opus_packet_parse_impl(const unsigned char *data, int len,
          return OPUS_INVALID_PACKET;
       /* VBR flag is bit 7 */
       cbr = !(ch&0x80);
-      if (cbr)
+      if (!cbr)
       {
          /* VBR case */
          last_size = len;
@@ -653,7 +686,7 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data,
        tot_offset += offset;
 
        if (count*st->frame_size > frame_size)
-               return OPUS_BAD_ARG;
+               return OPUS_BUFFER_TOO_SMALL;
        nb_samples=0;
        for (i=0;i<count;i++)
        {
@@ -693,7 +726,7 @@ int opus_decode_float(OpusDecoder *st, const unsigned char *data,
    if (ret > 0)
    {
       for (i=0;i<ret*st->channels;i++)
-         pcm[i] = (1./32768.)*(out[i]);
+         pcm[i] = (1.f/32768.f)*(out[i]);
    }
    RESTORE_STACK;
    return ret;
@@ -733,6 +766,12 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
 {
    int ret = OPUS_OK;
    va_list ap;
+   void *silk_dec;
+   CELTDecoder *celt_dec;
+
+   silk_dec = (char*)st+st->silk_dec_offset;
+   celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
+
 
    va_start(ap, request);
 
@@ -752,12 +791,6 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
    break;
    case OPUS_RESET_STATE:
    {
-      void *silk_dec;
-      CELTDecoder *celt_dec;
-
-      silk_dec = (char*)st+st->silk_dec_offset;
-      celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
-
       OPUS_CLEAR((char*)&st->OPUS_DECODER_RESET_START,
             sizeof(OpusDecoder)-
             ((char*)&st->OPUS_DECODER_RESET_START - (char*)st));
@@ -768,6 +801,20 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
       st->frame_size = st->Fs/400;
    }
    break;
+   case OPUS_GET_PITCH_REQUEST:
+   {
+      int *value = va_arg(ap, opus_int32*);
+      if (value==NULL)
+      {
+         ret = OPUS_BAD_ARG;
+         break;
+      }
+      if (st->prev_mode == MODE_CELT_ONLY)
+         celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value));
+      else
+         *value = st->DecControl.prevPitchLag;
+   }
+   break;
    default:
       /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/
       ret = OPUS_UNIMPLEMENTED;