void test_soft_clip(void)
{
   int i,j;
   float x[1024];
   float s[8] = {0, 0, 0, 0, 0, 0, 0, 0};
   fprintf(stdout,"  Testing opus_pcm_soft_clip... ");
   for(i=0;i<1024;i++)
   {
      for (j=0;j<1024;j++)
      {
        x[j]=(j&255)*(1/32.f)-4.f;
      }
      opus_pcm_soft_clip(&x[i],1024-i,1,s);
      for (j=i;j<1024;j++)
      {
        if(x[j]>1.f)test_failed();
        if(x[j]<-1.f)test_failed();
      }
   }
   for(i=1;i<9;i++)
   {
      for (j=0;j<1024;j++)
      {
        x[j]=(j&255)*(1/32.f)-4.f;
      }
      opus_pcm_soft_clip(x,1024/i,i,s);
      for (j=0;j<(1024/i)*i;j++)
      {
        if(x[j]>1.f)test_failed();
        if(x[j]<-1.f)test_failed();
      }
   }
   opus_pcm_soft_clip(x,0,1,s);
   opus_pcm_soft_clip(x,1,0,s);
   opus_pcm_soft_clip(x,1,1,0);
   opus_pcm_soft_clip(x,1,-1,s);
   opus_pcm_soft_clip(x,-1,1,s);
   opus_pcm_soft_clip(0,1,1,s);
   printf("OK.\n");
}
Beispiel #2
0
int opus_decode_native(OpusDecoder *st, const unsigned char *data,
                       opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec,
                       int self_delimited, opus_int32 *packet_offset, int soft_clip)
{
    int i, nb_samples;
    int count, offset;
    unsigned char toc;
    int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels;
    /* 48 x 2.5 ms = 120 ms */
    opus_int16 size[48];
    if (decode_fec<0 || decode_fec>1)
        return OPUS_BAD_ARG;
    /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */
    if ((decode_fec || len==0 || data==NULL) && frame_size%(st->Fs/400)!=0)
        return OPUS_BAD_ARG;
    if (len==0 || data==NULL)
    {
        int pcm_count=0;
        do {
            int ret;
            ret = opus_decode_frame(st, NULL, 0, pcm+pcm_count*st->channels, frame_size-pcm_count, 0);
            if (ret<0)
                return ret;
            pcm_count += ret;
        } while (pcm_count < frame_size);
        celt_assert(pcm_count == frame_size);
        if (OPUS_CHECK_ARRAY(pcm, pcm_count*st->channels))
            OPUS_PRINT_INT(pcm_count);
        st->last_packet_duration = pcm_count;
        return pcm_count;
    } else if (len<0)
        return OPUS_BAD_ARG;

    packet_mode = opus_packet_get_mode(data);
    packet_bandwidth = opus_packet_get_bandwidth(data);
    packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs);
    packet_stream_channels = opus_packet_get_nb_channels(data);

    count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL,
                                   size, &offset, packet_offset);
    if (count<0)
        return count;

    data += offset;

    if (decode_fec)
    {
        int duration_copy;
        int ret;
        /* If no FEC can be present, run the PLC (recursive call) */
        if (frame_size < packet_frame_size || packet_mode == MODE_CELT_ONLY || st->mode == MODE_CELT_ONLY)
            return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL, soft_clip);
        /* Otherwise, run the PLC on everything except the size for which we might have FEC */
        duration_copy = st->last_packet_duration;
        if (frame_size-packet_frame_size!=0)
        {
            ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 0, 0, NULL, soft_clip);
            if (ret<0)
            {
                st->last_packet_duration = duration_copy;
                return ret;
            }
            celt_assert(ret==frame_size-packet_frame_size);
        }
        /* Complete with FEC */
        st->mode = packet_mode;
        st->bandwidth = packet_bandwidth;
        st->frame_size = packet_frame_size;
        st->stream_channels = packet_stream_channels;
        ret = opus_decode_frame(st, data, size[0], pcm+st->channels*(frame_size-packet_frame_size),
                                packet_frame_size, 1);
        if (ret<0)
            return ret;
        else {
            if (OPUS_CHECK_ARRAY(pcm, frame_size*st->channels))
                OPUS_PRINT_INT(frame_size);
            st->last_packet_duration = frame_size;
            return frame_size;
        }
    }

    if (count*packet_frame_size > frame_size)
        return OPUS_BUFFER_TOO_SMALL;

    /* Update the state as the last step to avoid updating it on an invalid packet */
    st->mode = packet_mode;
    st->bandwidth = packet_bandwidth;
    st->frame_size = packet_frame_size;
    st->stream_channels = packet_stream_channels;

    nb_samples=0;
    for (i=0; i<count; i++)
    {
        int ret;
        ret = opus_decode_frame(st, data, size[i], pcm+nb_samples*st->channels, frame_size-nb_samples, 0);
        if (ret<0)
            return ret;
        celt_assert(ret==packet_frame_size);
        data += size[i];
        nb_samples += ret;
    }
    st->last_packet_duration = nb_samples;
    if (OPUS_CHECK_ARRAY(pcm, nb_samples*st->channels))
        OPUS_PRINT_INT(nb_samples);
#ifndef FIXED_POINT
    if (soft_clip)
        opus_pcm_soft_clip(pcm, nb_samples, st->channels, st->softclip_mem);
    else
        st->softclip_mem[0]=st->softclip_mem[1]=0;
#endif
    return nb_samples;
}