LCOV - code coverage report
Current view: top level - media/libopus/silk - resampler_private_down_FIR.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 84 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 2 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /***********************************************************************
       2             : Copyright (c) 2006-2011, Skype Limited. All rights reserved.
       3             : Redistribution and use in source and binary forms, with or without
       4             : modification, are permitted provided that the following conditions
       5             : are met:
       6             : - Redistributions of source code must retain the above copyright notice,
       7             : this list of conditions and the following disclaimer.
       8             : - Redistributions in binary form must reproduce the above copyright
       9             : notice, this list of conditions and the following disclaimer in the
      10             : documentation and/or other materials provided with the distribution.
      11             : - Neither the name of Internet Society, IETF or IETF Trust, nor the
      12             : names of specific contributors, may be used to endorse or promote
      13             : products derived from this software without specific prior written
      14             : permission.
      15             : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
      16             : AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      17             : IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      18             : ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
      19             : LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      20             : CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      21             : SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      22             : INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      23             : CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      24             : ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      25             : POSSIBILITY OF SUCH DAMAGE.
      26             : ***********************************************************************/
      27             : 
      28             : #ifdef HAVE_CONFIG_H
      29             : #include "config.h"
      30             : #endif
      31             : 
      32             : #include "SigProc_FIX.h"
      33             : #include "resampler_private.h"
      34             : #include "stack_alloc.h"
      35             : 
      36           0 : static OPUS_INLINE opus_int16 *silk_resampler_private_down_FIR_INTERPOL(
      37             :     opus_int16          *out,
      38             :     opus_int32          *buf,
      39             :     const opus_int16    *FIR_Coefs,
      40             :     opus_int            FIR_Order,
      41             :     opus_int            FIR_Fracs,
      42             :     opus_int32          max_index_Q16,
      43             :     opus_int32          index_increment_Q16
      44             : )
      45             : {
      46             :     opus_int32 index_Q16, res_Q6;
      47             :     opus_int32 *buf_ptr;
      48             :     opus_int32 interpol_ind;
      49             :     const opus_int16 *interpol_ptr;
      50             : 
      51           0 :     switch( FIR_Order ) {
      52             :         case RESAMPLER_DOWN_ORDER_FIR0:
      53           0 :             for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {
      54             :                 /* Integer part gives pointer to buffered input */
      55           0 :                 buf_ptr = buf + silk_RSHIFT( index_Q16, 16 );
      56             : 
      57             :                 /* Fractional part gives interpolation coefficients */
      58           0 :                 interpol_ind = silk_SMULWB( index_Q16 & 0xFFFF, FIR_Fracs );
      59             : 
      60             :                 /* Inner product */
      61           0 :                 interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR0 / 2 * interpol_ind ];
      62           0 :                 res_Q6 = silk_SMULWB(         buf_ptr[ 0 ], interpol_ptr[ 0 ] );
      63           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 1 ], interpol_ptr[ 1 ] );
      64           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], interpol_ptr[ 2 ] );
      65           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], interpol_ptr[ 3 ] );
      66           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 4 ], interpol_ptr[ 4 ] );
      67           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 5 ], interpol_ptr[ 5 ] );
      68           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 6 ], interpol_ptr[ 6 ] );
      69           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 7 ], interpol_ptr[ 7 ] );
      70           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 8 ], interpol_ptr[ 8 ] );
      71           0 :                 interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR0 / 2 * ( FIR_Fracs - 1 - interpol_ind ) ];
      72           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 17 ], interpol_ptr[ 0 ] );
      73           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 16 ], interpol_ptr[ 1 ] );
      74           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 15 ], interpol_ptr[ 2 ] );
      75           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 14 ], interpol_ptr[ 3 ] );
      76           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 13 ], interpol_ptr[ 4 ] );
      77           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 12 ], interpol_ptr[ 5 ] );
      78           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 11 ], interpol_ptr[ 6 ] );
      79           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 10 ], interpol_ptr[ 7 ] );
      80           0 :                 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[  9 ], interpol_ptr[ 8 ] );
      81             : 
      82             :                 /* Scale down, saturate and store in output array */
      83           0 :                 *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );
      84             :             }
      85           0 :             break;
      86             :         case RESAMPLER_DOWN_ORDER_FIR1:
      87           0 :             for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {
      88             :                 /* Integer part gives pointer to buffered input */
      89           0 :                 buf_ptr = buf + silk_RSHIFT( index_Q16, 16 );
      90             : 
      91             :                 /* Inner product */
      92           0 :                 res_Q6 = silk_SMULWB(         silk_ADD32( buf_ptr[  0 ], buf_ptr[ 23 ] ), FIR_Coefs[  0 ] );
      93           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  1 ], buf_ptr[ 22 ] ), FIR_Coefs[  1 ] );
      94           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  2 ], buf_ptr[ 21 ] ), FIR_Coefs[  2 ] );
      95           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  3 ], buf_ptr[ 20 ] ), FIR_Coefs[  3 ] );
      96           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  4 ], buf_ptr[ 19 ] ), FIR_Coefs[  4 ] );
      97           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  5 ], buf_ptr[ 18 ] ), FIR_Coefs[  5 ] );
      98           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  6 ], buf_ptr[ 17 ] ), FIR_Coefs[  6 ] );
      99           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  7 ], buf_ptr[ 16 ] ), FIR_Coefs[  7 ] );
     100           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  8 ], buf_ptr[ 15 ] ), FIR_Coefs[  8 ] );
     101           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  9 ], buf_ptr[ 14 ] ), FIR_Coefs[  9 ] );
     102           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 10 ], buf_ptr[ 13 ] ), FIR_Coefs[ 10 ] );
     103           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 11 ], buf_ptr[ 12 ] ), FIR_Coefs[ 11 ] );
     104             : 
     105             :                 /* Scale down, saturate and store in output array */
     106           0 :                 *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );
     107             :             }
     108           0 :             break;
     109             :         case RESAMPLER_DOWN_ORDER_FIR2:
     110           0 :             for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {
     111             :                 /* Integer part gives pointer to buffered input */
     112           0 :                 buf_ptr = buf + silk_RSHIFT( index_Q16, 16 );
     113             : 
     114             :                 /* Inner product */
     115           0 :                 res_Q6 = silk_SMULWB(         silk_ADD32( buf_ptr[  0 ], buf_ptr[ 35 ] ), FIR_Coefs[  0 ] );
     116           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  1 ], buf_ptr[ 34 ] ), FIR_Coefs[  1 ] );
     117           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  2 ], buf_ptr[ 33 ] ), FIR_Coefs[  2 ] );
     118           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  3 ], buf_ptr[ 32 ] ), FIR_Coefs[  3 ] );
     119           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  4 ], buf_ptr[ 31 ] ), FIR_Coefs[  4 ] );
     120           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  5 ], buf_ptr[ 30 ] ), FIR_Coefs[  5 ] );
     121           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  6 ], buf_ptr[ 29 ] ), FIR_Coefs[  6 ] );
     122           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  7 ], buf_ptr[ 28 ] ), FIR_Coefs[  7 ] );
     123           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  8 ], buf_ptr[ 27 ] ), FIR_Coefs[  8 ] );
     124           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[  9 ], buf_ptr[ 26 ] ), FIR_Coefs[  9 ] );
     125           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 10 ], buf_ptr[ 25 ] ), FIR_Coefs[ 10 ] );
     126           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 11 ], buf_ptr[ 24 ] ), FIR_Coefs[ 11 ] );
     127           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 12 ], buf_ptr[ 23 ] ), FIR_Coefs[ 12 ] );
     128           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 13 ], buf_ptr[ 22 ] ), FIR_Coefs[ 13 ] );
     129           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 14 ], buf_ptr[ 21 ] ), FIR_Coefs[ 14 ] );
     130           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 15 ], buf_ptr[ 20 ] ), FIR_Coefs[ 15 ] );
     131           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 16 ], buf_ptr[ 19 ] ), FIR_Coefs[ 16 ] );
     132           0 :                 res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 17 ], buf_ptr[ 18 ] ), FIR_Coefs[ 17 ] );
     133             : 
     134             :                 /* Scale down, saturate and store in output array */
     135           0 :                 *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );
     136             :             }
     137           0 :             break;
     138             :         default:
     139           0 :             silk_assert( 0 );
     140             :     }
     141           0 :     return out;
     142             : }
     143             : 
     144             : /* Resample with a 2nd order AR filter followed by FIR interpolation */
     145           0 : void silk_resampler_private_down_FIR(
     146             :     void                            *SS,            /* I/O  Resampler state             */
     147             :     opus_int16                      out[],          /* O    Output signal               */
     148             :     const opus_int16                in[],           /* I    Input signal                */
     149             :     opus_int32                      inLen           /* I    Number of input samples     */
     150             : )
     151             : {
     152           0 :     silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS;
     153             :     opus_int32 nSamplesIn;
     154             :     opus_int32 max_index_Q16, index_increment_Q16;
     155             :     VARDECL( opus_int32, buf );
     156             :     const opus_int16 *FIR_Coefs;
     157             :     SAVE_STACK;
     158             : 
     159           0 :     ALLOC( buf, S->batchSize + S->FIR_Order, opus_int32 );
     160             : 
     161             :     /* Copy buffered samples to start of buffer */
     162           0 :     silk_memcpy( buf, S->sFIR.i32, S->FIR_Order * sizeof( opus_int32 ) );
     163             : 
     164           0 :     FIR_Coefs = &S->Coefs[ 2 ];
     165             : 
     166             :     /* Iterate over blocks of frameSizeIn input samples */
     167           0 :     index_increment_Q16 = S->invRatio_Q16;
     168             :     while( 1 ) {
     169           0 :         nSamplesIn = silk_min( inLen, S->batchSize );
     170             : 
     171             :         /* Second-order AR filter (output in Q8) */
     172           0 :         silk_resampler_private_AR2( S->sIIR, &buf[ S->FIR_Order ], in, S->Coefs, nSamplesIn );
     173             : 
     174           0 :         max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 );
     175             : 
     176             :         /* Interpolate filtered signal */
     177           0 :         out = silk_resampler_private_down_FIR_INTERPOL( out, buf, FIR_Coefs, S->FIR_Order,
     178             :             S->FIR_Fracs, max_index_Q16, index_increment_Q16 );
     179             : 
     180           0 :         in += nSamplesIn;
     181           0 :         inLen -= nSamplesIn;
     182             : 
     183           0 :         if( inLen > 1 ) {
     184             :             /* More iterations to do; copy last part of filtered signal to beginning of buffer */
     185           0 :             silk_memcpy( buf, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) );
     186             :         } else {
     187           0 :             break;
     188             :         }
     189             :     }
     190             : 
     191             :     /* Copy last part of filtered signal to the state for the next call */
     192           0 :     silk_memcpy( S->sFIR.i32, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) );
     193             :     RESTORE_STACK;
     194           0 : }

Generated by: LCOV version 1.13