media/libopus/src/opus.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/libopus/src/opus.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,329 @@
     1.4 +/* Copyright (c) 2011 Xiph.Org Foundation, Skype Limited
     1.5 +   Written by Jean-Marc Valin and Koen Vos */
     1.6 +/*
     1.7 +   Redistribution and use in source and binary forms, with or without
     1.8 +   modification, are permitted provided that the following conditions
     1.9 +   are met:
    1.10 +
    1.11 +   - Redistributions of source code must retain the above copyright
    1.12 +   notice, this list of conditions and the following disclaimer.
    1.13 +
    1.14 +   - Redistributions in binary form must reproduce the above copyright
    1.15 +   notice, this list of conditions and the following disclaimer in the
    1.16 +   documentation and/or other materials provided with the distribution.
    1.17 +
    1.18 +   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1.19 +   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    1.20 +   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    1.21 +   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
    1.22 +   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    1.23 +   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    1.24 +   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    1.25 +   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    1.26 +   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    1.27 +   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    1.28 +   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.29 +*/
    1.30 +
    1.31 +#ifdef HAVE_CONFIG_H
    1.32 +#include "config.h"
    1.33 +#endif
    1.34 +
    1.35 +#include "opus.h"
    1.36 +#include "opus_private.h"
    1.37 +
    1.38 +#ifndef DISABLE_FLOAT_API
    1.39 +OPUS_EXPORT void opus_pcm_soft_clip(float *_x, int N, int C, float *declip_mem)
    1.40 +{
    1.41 +   int c;
    1.42 +   int i;
    1.43 +   float *x;
    1.44 +
    1.45 +   if (C<1 || N<1 || !_x || !declip_mem) return;
    1.46 +
    1.47 +   /* First thing: saturate everything to +/- 2 which is the highest level our
    1.48 +      non-linearity can handle. At the point where the signal reaches +/-2,
    1.49 +      the derivative will be zero anyway, so this doesn't introduce any
    1.50 +      discontinuity in the derivative. */
    1.51 +   for (i=0;i<N*C;i++)
    1.52 +      _x[i] = MAX16(-2.f, MIN16(2.f, _x[i]));
    1.53 +   for (c=0;c<C;c++)
    1.54 +   {
    1.55 +      float a;
    1.56 +      float x0;
    1.57 +      int curr;
    1.58 +
    1.59 +      x = _x+c;
    1.60 +      a = declip_mem[c];
    1.61 +      /* Continue applying the non-linearity from the previous frame to avoid
    1.62 +         any discontinuity. */
    1.63 +      for (i=0;i<N;i++)
    1.64 +      {
    1.65 +         if (x[i*C]*a>=0)
    1.66 +            break;
    1.67 +         x[i*C] = x[i*C]+a*x[i*C]*x[i*C];
    1.68 +      }
    1.69 +
    1.70 +      curr=0;
    1.71 +      x0 = x[0];
    1.72 +      while(1)
    1.73 +      {
    1.74 +         int start, end;
    1.75 +         float maxval;
    1.76 +         int special=0;
    1.77 +         int peak_pos;
    1.78 +         for (i=curr;i<N;i++)
    1.79 +         {
    1.80 +            if (x[i*C]>1 || x[i*C]<-1)
    1.81 +               break;
    1.82 +         }
    1.83 +         if (i==N)
    1.84 +         {
    1.85 +            a=0;
    1.86 +            break;
    1.87 +         }
    1.88 +         peak_pos = i;
    1.89 +         start=end=i;
    1.90 +         maxval=ABS16(x[i*C]);
    1.91 +         /* Look for first zero crossing before clipping */
    1.92 +         while (start>0 && x[i*C]*x[(start-1)*C]>=0)
    1.93 +            start--;
    1.94 +         /* Look for first zero crossing after clipping */
    1.95 +         while (end<N && x[i*C]*x[end*C]>=0)
    1.96 +         {
    1.97 +            /* Look for other peaks until the next zero-crossing. */
    1.98 +            if (ABS16(x[end*C])>maxval)
    1.99 +            {
   1.100 +               maxval = ABS16(x[end*C]);
   1.101 +               peak_pos = end;
   1.102 +            }
   1.103 +            end++;
   1.104 +         }
   1.105 +         /* Detect the special case where we clip before the first zero crossing */
   1.106 +         special = (start==0 && x[i*C]*x[0]>=0);
   1.107 +
   1.108 +         /* Compute a such that maxval + a*maxval^2 = 1 */
   1.109 +         a=(maxval-1)/(maxval*maxval);
   1.110 +         if (x[i*C]>0)
   1.111 +            a = -a;
   1.112 +         /* Apply soft clipping */
   1.113 +         for (i=start;i<end;i++)
   1.114 +            x[i*C] = x[i*C]+a*x[i*C]*x[i*C];
   1.115 +
   1.116 +         if (special && peak_pos>=2)
   1.117 +         {
   1.118 +            /* Add a linear ramp from the first sample to the signal peak.
   1.119 +               This avoids a discontinuity at the beginning of the frame. */
   1.120 +            float delta;
   1.121 +            float offset = x0-x[0];
   1.122 +            delta = offset / peak_pos;
   1.123 +            for (i=curr;i<peak_pos;i++)
   1.124 +            {
   1.125 +               offset -= delta;
   1.126 +               x[i*C] += offset;
   1.127 +               x[i*C] = MAX16(-1.f, MIN16(1.f, x[i*C]));
   1.128 +            }
   1.129 +         }
   1.130 +         curr = end;
   1.131 +         if (curr==N)
   1.132 +            break;
   1.133 +      }
   1.134 +      declip_mem[c] = a;
   1.135 +   }
   1.136 +}
   1.137 +#endif
   1.138 +
   1.139 +int encode_size(int size, unsigned char *data)
   1.140 +{
   1.141 +   if (size < 252)
   1.142 +   {
   1.143 +      data[0] = size;
   1.144 +      return 1;
   1.145 +   } else {
   1.146 +      data[0] = 252+(size&0x3);
   1.147 +      data[1] = (size-(int)data[0])>>2;
   1.148 +      return 2;
   1.149 +   }
   1.150 +}
   1.151 +
   1.152 +static int parse_size(const unsigned char *data, opus_int32 len, opus_int16 *size)
   1.153 +{
   1.154 +   if (len<1)
   1.155 +   {
   1.156 +      *size = -1;
   1.157 +      return -1;
   1.158 +   } else if (data[0]<252)
   1.159 +   {
   1.160 +      *size = data[0];
   1.161 +      return 1;
   1.162 +   } else if (len<2)
   1.163 +   {
   1.164 +      *size = -1;
   1.165 +      return -1;
   1.166 +   } else {
   1.167 +      *size = 4*data[1] + data[0];
   1.168 +      return 2;
   1.169 +   }
   1.170 +}
   1.171 +
   1.172 +int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
   1.173 +      int self_delimited, unsigned char *out_toc,
   1.174 +      const unsigned char *frames[48], opus_int16 size[48],
   1.175 +      int *payload_offset, opus_int32 *packet_offset)
   1.176 +{
   1.177 +   int i, bytes;
   1.178 +   int count;
   1.179 +   int cbr;
   1.180 +   unsigned char ch, toc;
   1.181 +   int framesize;
   1.182 +   opus_int32 last_size;
   1.183 +   opus_int32 pad = 0;
   1.184 +   const unsigned char *data0 = data;
   1.185 +
   1.186 +   if (size==NULL)
   1.187 +      return OPUS_BAD_ARG;
   1.188 +
   1.189 +   framesize = opus_packet_get_samples_per_frame(data, 48000);
   1.190 +
   1.191 +   cbr = 0;
   1.192 +   toc = *data++;
   1.193 +   len--;
   1.194 +   last_size = len;
   1.195 +   switch (toc&0x3)
   1.196 +   {
   1.197 +   /* One frame */
   1.198 +   case 0:
   1.199 +      count=1;
   1.200 +      break;
   1.201 +   /* Two CBR frames */
   1.202 +   case 1:
   1.203 +      count=2;
   1.204 +      cbr = 1;
   1.205 +      if (!self_delimited)
   1.206 +      {
   1.207 +         if (len&0x1)
   1.208 +            return OPUS_INVALID_PACKET;
   1.209 +         last_size = len/2;
   1.210 +         /* If last_size doesn't fit in size[0], we'll catch it later */
   1.211 +         size[0] = (opus_int16)last_size;
   1.212 +      }
   1.213 +      break;
   1.214 +   /* Two VBR frames */
   1.215 +   case 2:
   1.216 +      count = 2;
   1.217 +      bytes = parse_size(data, len, size);
   1.218 +      len -= bytes;
   1.219 +      if (size[0]<0 || size[0] > len)
   1.220 +         return OPUS_INVALID_PACKET;
   1.221 +      data += bytes;
   1.222 +      last_size = len-size[0];
   1.223 +      break;
   1.224 +   /* Multiple CBR/VBR frames (from 0 to 120 ms) */
   1.225 +   default: /*case 3:*/
   1.226 +      if (len<1)
   1.227 +         return OPUS_INVALID_PACKET;
   1.228 +      /* Number of frames encoded in bits 0 to 5 */
   1.229 +      ch = *data++;
   1.230 +      count = ch&0x3F;
   1.231 +      if (count <= 0 || framesize*count > 5760)
   1.232 +         return OPUS_INVALID_PACKET;
   1.233 +      len--;
   1.234 +      /* Padding flag is bit 6 */
   1.235 +      if (ch&0x40)
   1.236 +      {
   1.237 +         int p;
   1.238 +         do {
   1.239 +            int tmp;
   1.240 +            if (len<=0)
   1.241 +               return OPUS_INVALID_PACKET;
   1.242 +            p = *data++;
   1.243 +            len--;
   1.244 +            tmp = p==255 ? 254: p;
   1.245 +            len -= tmp;
   1.246 +            pad += tmp;
   1.247 +         } while (p==255);
   1.248 +      }
   1.249 +      if (len<0)
   1.250 +         return OPUS_INVALID_PACKET;
   1.251 +      /* VBR flag is bit 7 */
   1.252 +      cbr = !(ch&0x80);
   1.253 +      if (!cbr)
   1.254 +      {
   1.255 +         /* VBR case */
   1.256 +         last_size = len;
   1.257 +         for (i=0;i<count-1;i++)
   1.258 +         {
   1.259 +            bytes = parse_size(data, len, size+i);
   1.260 +            len -= bytes;
   1.261 +            if (size[i]<0 || size[i] > len)
   1.262 +               return OPUS_INVALID_PACKET;
   1.263 +            data += bytes;
   1.264 +            last_size -= bytes+size[i];
   1.265 +         }
   1.266 +         if (last_size<0)
   1.267 +            return OPUS_INVALID_PACKET;
   1.268 +      } else if (!self_delimited)
   1.269 +      {
   1.270 +         /* CBR case */
   1.271 +         last_size = len/count;
   1.272 +         if (last_size*count!=len)
   1.273 +            return OPUS_INVALID_PACKET;
   1.274 +         for (i=0;i<count-1;i++)
   1.275 +            size[i] = (opus_int16)last_size;
   1.276 +      }
   1.277 +      break;
   1.278 +   }
   1.279 +   /* Self-delimited framing has an extra size for the last frame. */
   1.280 +   if (self_delimited)
   1.281 +   {
   1.282 +      bytes = parse_size(data, len, size+count-1);
   1.283 +      len -= bytes;
   1.284 +      if (size[count-1]<0 || size[count-1] > len)
   1.285 +         return OPUS_INVALID_PACKET;
   1.286 +      data += bytes;
   1.287 +      /* For CBR packets, apply the size to all the frames. */
   1.288 +      if (cbr)
   1.289 +      {
   1.290 +         if (size[count-1]*count > len)
   1.291 +            return OPUS_INVALID_PACKET;
   1.292 +         for (i=0;i<count-1;i++)
   1.293 +            size[i] = size[count-1];
   1.294 +      } else if (bytes+size[count-1] > last_size)
   1.295 +         return OPUS_INVALID_PACKET;
   1.296 +   } else
   1.297 +   {
   1.298 +      /* Because it's not encoded explicitly, it's possible the size of the
   1.299 +         last packet (or all the packets, for the CBR case) is larger than
   1.300 +         1275. Reject them here.*/
   1.301 +      if (last_size > 1275)
   1.302 +         return OPUS_INVALID_PACKET;
   1.303 +      size[count-1] = (opus_int16)last_size;
   1.304 +   }
   1.305 +
   1.306 +   if (payload_offset)
   1.307 +      *payload_offset = (int)(data-data0);
   1.308 +
   1.309 +   for (i=0;i<count;i++)
   1.310 +   {
   1.311 +      if (frames)
   1.312 +         frames[i] = data;
   1.313 +      data += size[i];
   1.314 +   }
   1.315 +
   1.316 +   if (packet_offset)
   1.317 +      *packet_offset = pad+(opus_int32)(data-data0);
   1.318 +
   1.319 +   if (out_toc)
   1.320 +      *out_toc = toc;
   1.321 +
   1.322 +   return count;
   1.323 +}
   1.324 +
   1.325 +int opus_packet_parse(const unsigned char *data, opus_int32 len,
   1.326 +      unsigned char *out_toc, const unsigned char *frames[48],
   1.327 +      opus_int16 size[48], int *payload_offset)
   1.328 +{
   1.329 +   return opus_packet_parse_impl(data, len, 0, out_toc,
   1.330 +                                 frames, size, payload_offset, NULL);
   1.331 +}
   1.332 +

mercurial