Ejemplo n.º 1
0
SWIGEXPORT jint JNICALL Java_com_morlunk_jumble_audio_celt11_CELT11JNI_celt_1decoder_1ctl(JNIEnv *jenv, jclass jcls, jlong jarg1, jint jarg2) {
  jint jresult = 0 ;
  CELTDecoder *arg1 = (CELTDecoder *) 0 ;
  int arg2 ;
  void *arg3 = 0 ;
  int result;
  
  (void)jenv;
  (void)jcls;
  arg1 = *(CELTDecoder **)&jarg1; 
  arg2 = (int)jarg2; 
  result = (int)celt_decoder_ctl(arg1,arg2,arg3);
  jresult = (jint)result; 
  return jresult;
}
Ejemplo n.º 2
0
int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
{
   void *silk_dec;
   CELTDecoder *celt_dec;
   int ret, silkDecSizeBytes;

   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);
   if (ret)
      return OPUS_INTERNAL_ERROR;

   silkDecSizeBytes = align(silkDecSizeBytes);
   st->silk_dec_offset = align(sizeof(OpusDecoder));
   st->celt_dec_offset = st->silk_dec_offset+silkDecSizeBytes;
   silk_dec = (char*)st+st->silk_dec_offset;
   celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
   st->stream_channels = st->channels = channels;

   st->Fs = Fs;
   st->DecControl.API_sampleRate = st->Fs;
   st->DecControl.nChannelsAPI      = st->channels;
   st->arch = opus_select_arch();

   /* Reset decoder */
   ret = silk_InitDecoder( silk_dec );
   if(ret)return OPUS_INTERNAL_ERROR;

   /* Initialize CELT decoder */
   ret = celt_decoder_init(celt_dec, Fs, channels);
   if(ret!=OPUS_OK)return OPUS_INTERNAL_ERROR;

   celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0));

   st->prev_mode = 0;
   st->frame_size = Fs/400;
   return OPUS_OK;
}
Ejemplo n.º 3
0
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);

    switch (request)
    {
    case OPUS_GET_BANDWIDTH_REQUEST:
    {
        opus_int32 *value = va_arg(ap, opus_int32*);
        if (!value)
        {
            goto bad_arg;
        }
        *value = st->bandwidth;
    }
    break;
    case OPUS_GET_FINAL_RANGE_REQUEST:
    {
        opus_uint32 *value = va_arg(ap, opus_uint32*);
        if (!value)
        {
            goto bad_arg;
        }
        *value = st->rangeFinal;
    }
    break;
    case OPUS_RESET_STATE:
    {
        OPUS_CLEAR((char*)&st->OPUS_DECODER_RESET_START,
                   sizeof(OpusDecoder)-
                   ((char*)&st->OPUS_DECODER_RESET_START - (char*)st));

        celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
        silk_InitDecoder( silk_dec );
        st->stream_channels = st->channels;
        st->frame_size = st->Fs/400;
    }
    break;
    case OPUS_GET_SAMPLE_RATE_REQUEST:
    {
        opus_int32 *value = va_arg(ap, opus_int32*);
        if (!value)
        {
            goto bad_arg;
        }
        *value = st->Fs;
    }
    break;
    case OPUS_GET_PITCH_REQUEST:
    {
        opus_int32 *value = va_arg(ap, opus_int32*);
        if (!value)
        {
            goto bad_arg;
        }
        if (st->prev_mode == MODE_CELT_ONLY)
            celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value));
        else
            *value = st->DecControl.prevPitchLag;
    }
    break;
    case OPUS_GET_GAIN_REQUEST:
    {
        opus_int32 *value = va_arg(ap, opus_int32*);
        if (!value)
        {
            goto bad_arg;
        }
        *value = st->decode_gain;
    }
    break;
    case OPUS_SET_GAIN_REQUEST:
    {
        opus_int32 value = va_arg(ap, opus_int32);
        if (value<-32768 || value>32767)
        {
            goto bad_arg;
        }
        st->decode_gain = value;
    }
    break;
    case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
    {
        opus_uint32 *value = va_arg(ap, opus_uint32*);
        if (!value)
        {
            goto bad_arg;
        }
        *value = st->last_packet_duration;
    }
    break;
    default:
        /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/
        ret = OPUS_UNIMPLEMENTED;
        break;
    }

    va_end(ap);
    return ret;
bad_arg:
    va_end(ap);
    return OPUS_BAD_ARG;
}
Ejemplo n.º 4
0
static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
                             opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
{
    void *silk_dec;
    CELTDecoder *celt_dec;
    int i, silk_ret=0, celt_ret=0;
    ec_dec dec;
    opus_int32 silk_frame_size;
    int pcm_silk_size;
    VARDECL(opus_int16, pcm_silk);
    int pcm_transition_silk_size;
    VARDECL(opus_val16, pcm_transition_silk);
    int pcm_transition_celt_size;
    VARDECL(opus_val16, pcm_transition_celt);
    opus_val16 *pcm_transition=NULL;
    int redundant_audio_size;
    VARDECL(opus_val16, redundant_audio);

    int audiosize;
    int mode;
    int transition=0;
    int start_band;
    int redundancy=0;
    int redundancy_bytes = 0;
    int celt_to_silk=0;
    int c;
    int F2_5, F5, F10, F20;
    const opus_val16 *window;
    opus_uint32 redundant_rng = 0;
    int celt_accum;
    ALLOC_STACK;

    silk_dec = (char*)st+st->silk_dec_offset;
    celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
    F20 = st->Fs/50;
    F10 = F20>>1;
    F5 = F10>>1;
    F2_5 = F5>>1;
    if (frame_size < F2_5)
    {
        RESTORE_STACK;
        return OPUS_BUFFER_TOO_SMALL;
    }
    /* Limit frame_size to avoid excessive stack allocations. */
    frame_size = IMIN(frame_size, st->Fs/25*3);
    /* Payloads of 1 (2 including ToC) or 0 trigger the PLC/DTX */
    if (len<=1)
    {
        data = NULL;
        /* In that case, don't conceal more than what the ToC says */
        frame_size = IMIN(frame_size, st->frame_size);
    }
    if (data != NULL)
    {
        audiosize = st->frame_size;
        mode = st->mode;
        ec_dec_init(&dec,(unsigned char*)data,len);
    } else {
        audiosize = frame_size;
        mode = st->prev_mode;

        if (mode == 0)
        {
            /* If we haven't got any packet yet, all we can do is return zeros */
            for (i=0; i<audiosize*st->channels; i++)
                pcm[i] = 0;
            RESTORE_STACK;
            return audiosize;
        }

        /* Avoids trying to run the PLC on sizes other than 2.5 (CELT), 5 (CELT),
           10, or 20 (e.g. 12.5 or 30 ms). */
        if (audiosize > F20)
        {
            do {
                int ret = opus_decode_frame(st, NULL, 0, pcm, IMIN(audiosize, F20), 0);
                if (ret<0)
                {
                    RESTORE_STACK;
                    return ret;
                }
                pcm += ret*st->channels;
                audiosize -= ret;
            } while (audiosize > 0);
            RESTORE_STACK;
            return frame_size;
        } else if (audiosize < F20)
        {
            if (audiosize > F10)
                audiosize = F10;
            else if (mode != MODE_SILK_ONLY && audiosize > F5 && audiosize < F10)
                audiosize = F5;
        }
    }

    /* In fixed-point, we can tell CELT to do the accumulation on top of the
       SILK PCM buffer. This saves some stack space. */
#ifdef FIXED_POINT
    celt_accum = (mode != MODE_CELT_ONLY) && (frame_size >= F10);
#else
    celt_accum = 0;
#endif

    pcm_transition_silk_size = ALLOC_NONE;
    pcm_transition_celt_size = ALLOC_NONE;
    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;
        /* Decide where to allocate the stack memory for pcm_transition */
        if (mode == MODE_CELT_ONLY)
            pcm_transition_celt_size = F5*st->channels;
        else
            pcm_transition_silk_size = F5*st->channels;
    }
    ALLOC(pcm_transition_celt, pcm_transition_celt_size, opus_val16);
    if (transition && mode == MODE_CELT_ONLY)
    {
        pcm_transition = pcm_transition_celt;
        opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
    }
    if (audiosize > frame_size)
    {
        /*fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosize, frame_size, mode);*/
        RESTORE_STACK;
        return OPUS_BAD_ARG;
    } else {
        frame_size = audiosize;
    }

    /* Don't allocate any memory when in CELT-only mode */
    pcm_silk_size = (mode != MODE_CELT_ONLY && !celt_accum) ? IMAX(F10, frame_size)*st->channels : ALLOC_NONE;
    ALLOC(pcm_silk, pcm_silk_size, opus_int16);

    /* SILK processing */
    if (mode != MODE_CELT_ONLY)
    {
        int lost_flag, decoded_samples;
        opus_int16 *pcm_ptr;
#ifdef FIXED_POINT
        if (celt_accum)
            pcm_ptr = pcm;
        else
#endif
            pcm_ptr = pcm_silk;

        if (st->prev_mode==MODE_CELT_ONLY)
            silk_InitDecoder( silk_dec );

        /* The SILK PLC cannot 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 {
                /* Hybrid mode */
                st->DecControl.internalSampleRate = 16000;
            }
        }

        lost_flag = data == NULL ? 1 : 2 * decode_fec;
        decoded_samples = 0;
        do {
            /* Call SILK decoder */
            int first_frame = decoded_samples == 0;
            silk_ret = silk_Decode( silk_dec, &st->DecControl,
                                    lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size );
            if( silk_ret ) {
                if (lost_flag) {
                    /* PLC failure should not be fatal */
                    silk_frame_size = frame_size;
                    for (i=0; i<frame_size*st->channels; i++)
                        pcm_ptr[i] = 0;
                } else {
                    RESTORE_STACK;
                    return OPUS_INTERNAL_ERROR;
                }
            }
            pcm_ptr += silk_frame_size * st->channels;
            decoded_samples += silk_frame_size;
        } while( decoded_samples < frame_size );
    }

    start_band = 0;
    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 */
        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);
            /* 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;
            /* 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;
        }
    }
    if (mode != MODE_CELT_ONLY)
        start_band = 17;

    {
        int endband=21;

        switch(st->bandwidth)
        {
        case OPUS_BANDWIDTH_NARROWBAND:
            endband = 13;
            break;
        case OPUS_BANDWIDTH_MEDIUMBAND:
        case OPUS_BANDWIDTH_WIDEBAND:
            endband = 17;
            break;
        case OPUS_BANDWIDTH_SUPERWIDEBAND:
            endband = 19;
            break;
        case OPUS_BANDWIDTH_FULLBAND:
            endband = 21;
            break;
        }
        celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband));
        celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels));
    }

    if (redundancy)
    {
        transition = 0;
        pcm_transition_silk_size=ALLOC_NONE;
    }

    ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16);

    if (transition && mode != MODE_CELT_ONLY)
    {
        pcm_transition = pcm_transition_silk;
        opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
    }

    /* Only allocation memory for redundancy if/when needed */
    redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE;
    ALLOC(redundant_audio, redundant_audio_size, opus_val16);

    /* 5 ms redundant frame for CELT->SILK*/
    if (redundancy && celt_to_silk)
    {
        celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
        celt_decode_with_ec(celt_dec, data+len, redundancy_bytes,
                            redundant_audio, F5, NULL, 0);
        celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
    }

    /* MUST be after PLC */
    celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band));

    if (mode != MODE_SILK_ONLY)
    {
        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, celt_accum);
    } else {
        unsigned char silence[2] = {0xFF, 0xFF};
        if (!celt_accum)
        {
            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 && !(redundancy && celt_to_silk && st->prev_redundancy) )
        {
            celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
            celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL, celt_accum);
        }
    }

    if (mode != MODE_CELT_ONLY && !celt_accum)
    {
#ifdef FIXED_POINT
        for (i=0; i<frame_size*st->channels; i++)
            pcm[i] = SAT16(ADD32(pcm[i], pcm_silk[i]));
#else
        for (i=0; i<frame_size*st->channels; i++)
            pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]);
#endif
    }

    {
        const CELTMode *celt_mode;
        celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode));
        window = celt_mode->window;
    }

    /* 5 ms redundant frame for SILK->CELT */
    if (redundancy && !celt_to_silk)
    {
        celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
        celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));

        celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL, 0);
        celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
        smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5,
                    pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs);
    }
    if (redundancy && celt_to_silk)
    {
        for (c=0; c<st->channels; c++)
        {
            for (i=0; i<F2_5; i++)
                pcm[st->channels*i+c] = redundant_audio[st->channels*i+c];
        }
        smooth_fade(redundant_audio+st->channels*F2_5, pcm+st->channels*F2_5,
                    pcm+st->channels*F2_5, F2_5, st->channels, window, st->Fs);
    }
    if (transition)
    {
        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(st->decode_gain)
    {
        opus_val32 gain;
        gain = celt_exp2(MULT16_16_P15(QCONST16(6.48814081e-4f, 25), st->decode_gain));
        for (i=0; i<frame_size*st->channels; i++)
        {
            opus_val32 x;
            x = MULT16_32_P16(pcm[i],gain);
            pcm[i] = SATURATE(x, 32767);
        }
    }

    if (len <= 1)
        st->rangeFinal = 0;
    else
        st->rangeFinal = dec.rng ^ redundant_rng;

    st->prev_mode = mode;
    st->prev_redundancy = redundancy && !celt_to_silk;

    if (celt_ret>=0)
    {
        if (OPUS_CHECK_ARRAY(pcm, audiosize*st->channels))
            OPUS_PRINT_INT(audiosize);
    }

    RESTORE_STACK;
    return celt_ret < 0 ? celt_ret : audiosize;

}
Ejemplo n.º 5
0
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);

   switch (request)
   {
   case OPUS_GET_BANDWIDTH_REQUEST:
   {
      opus_int32 *value = va_arg(ap, opus_int32*);
      *value = st->bandwidth;
   }
   break;
   case OPUS_GET_FINAL_RANGE_REQUEST:
   {
      opus_uint32 *value = va_arg(ap, opus_uint32*);
      *value = st->rangeFinal;
   }
   break;
   case OPUS_RESET_STATE:
   {
      OPUS_CLEAR((char*)&st->OPUS_DECODER_RESET_START,
            sizeof(OpusDecoder)-
            ((char*)&st->OPUS_DECODER_RESET_START - (char*)st));

      celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
      silk_InitDecoder( silk_dec );
      st->stream_channels = st->channels;
      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;
      break;
   }

   va_end(ap);
   return ret;
}
Ejemplo n.º 6
0
int main(int argc, char *argv[])
{
   int err;
   char *inFile, *outFile;
   FILE *fin, *fout;
   CELTMode *mode=NULL;
   CELTEncoder *enc;
   CELTDecoder *dec;
   int len;
   celt_int32 frame_size, channels;
   int bytes_per_packet;
   unsigned char data[MAX_PACKET];
   int rate;
   int complexity;
#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)
   int i;
   double rmsd = 0;
#endif
   int count = 0;
   celt_int32 skip;
   celt_int16 *in, *out;
   if (argc != 9 && argc != 8 && argc != 7)
   {
      fprintf (stderr, "Usage: testcelt <rate> <channels> <frame size> "
               " <bytes per packet> [<complexity> [packet loss rate]] "
               "<input> <output>\n");
      return 1;
   }
   
   rate = atoi(argv[1]);
   channels = atoi(argv[2]);
   frame_size = atoi(argv[3]);
   mode = celt_mode_create(rate, frame_size, NULL);
   if (mode == NULL)
   {
      fprintf(stderr, "failed to create a mode\n");
      return 1;
   }

   bytes_per_packet = atoi(argv[4]);
   if (bytes_per_packet < 0 || bytes_per_packet > MAX_PACKET)
   {
      fprintf (stderr, "bytes per packet must be between 0 and %d\n",
                        MAX_PACKET);
      return 1;
   }

   inFile = argv[argc-2];
   fin = fopen(inFile, "rb");
   if (!fin)
   {
      fprintf (stderr, "Could not open input file %s\n", argv[argc-2]);
      return 1;
   }
   outFile = argv[argc-1];
   fout = fopen(outFile, "wb+");
   if (!fout)
   {
      fprintf (stderr, "Could not open output file %s\n", argv[argc-1]);
      return 1;
   }
   
   enc = celt_encoder_create_custom(mode, channels, &err);
   if (err != 0)
   {
      fprintf(stderr, "Failed to create the encoder: %s\n", celt_strerror(err));
      return 1;
   }
   dec = celt_decoder_create_custom(mode, channels, &err);
   if (err != 0)
   {
      fprintf(stderr, "Failed to create the decoder: %s\n", celt_strerror(err));
      return 1;
   }
   celt_decoder_ctl(dec, CELT_GET_LOOKAHEAD(&skip));

   if (argc>7)
   {
      complexity=atoi(argv[5]);
      celt_encoder_ctl(enc,CELT_SET_COMPLEXITY(complexity));
   }
   
   in = (celt_int16*)malloc(frame_size*channels*sizeof(celt_int16));
   out = (celt_int16*)malloc(frame_size*channels*sizeof(celt_int16));

   while (!feof(fin))
   {
      int ret;
      err = fread(in, sizeof(short), frame_size*channels, fin);
      if (feof(fin))
         break;
      len = celt_encode(enc, in, frame_size, data, bytes_per_packet);
      if (len <= 0)
         fprintf (stderr, "celt_encode() failed: %s\n", celt_strerror(len));

      /* This is for simulating bit errors */
#if 0
      int errors = 0;
      int eid = 0;
      /* This simulates random bit error */
      for (i=0;i<len*8;i++)
      {
         if (rand()%atoi(argv[8])==0)
         {
            if (i<64)
            {
               errors++;
               eid = i;
            }
            data[i/8] ^= 1<<(7-(i%8));
         }
      }
      if (errors == 1)
         data[eid/8] ^= 1<<(7-(eid%8));
      else if (errors%2 == 1)
         data[rand()%8] ^= 1<<rand()%8;
#endif

#if 1 /* Set to zero to use the encoder's output instead */
      /* This is to simulate packet loss */
      if (argc==9 && rand()%1000<atoi(argv[argc-3]))
      /*if (errors && (errors%2==0))*/
         ret = celt_decode(dec, NULL, len, out, frame_size);
      else
         ret = celt_decode(dec, data, len, out, frame_size);
      if (ret < 0)
         fprintf(stderr, "celt_decode() failed: %s\n", celt_strerror(ret));
#else
      for (i=0;i<ret*channels;i++)
         out[i] = in[i];
#endif
#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)
      for (i=0;i<ret*channels;i++)
      {
         rmsd += (in[i]-out[i])*1.0*(in[i]-out[i]);
         /*out[i] -= in[i];*/
      }
#endif
      count++;
      fwrite(out+skip*channels, sizeof(short), (ret-skip)*channels, fout);
      skip = 0;
   }
   PRINT_MIPS(stderr);
   
   celt_encoder_destroy(enc);
   celt_decoder_destroy(dec);
   fclose(fin);
   fclose(fout);
   celt_mode_destroy(mode);
   free(in);
   free(out);
#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)
   if (rmsd > 0)
   {
      rmsd = sqrt(rmsd/(1.0*frame_size*channels*count));
      fprintf (stderr, "Error: encoder doesn't match decoder\n");
      fprintf (stderr, "RMS mismatch is %f\n", rmsd);
      return 1;
   } else {
      fprintf (stderr, "Encoder matches decoder!!\n");
   }
#endif
   return 0;
}