media/libopus/silk/stereo_LR_to_MS.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/libopus/silk/stereo_LR_to_MS.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,229 @@
     1.4 +/***********************************************************************
     1.5 +Copyright (c) 2006-2011, Skype Limited. All rights reserved.
     1.6 +Redistribution and use in source and binary forms, with or without
     1.7 +modification, are permitted provided that the following conditions
     1.8 +are met:
     1.9 +- Redistributions of source code must retain the above copyright notice,
    1.10 +this list of conditions and the following disclaimer.
    1.11 +- Redistributions in binary form must reproduce the above copyright
    1.12 +notice, this list of conditions and the following disclaimer in the
    1.13 +documentation and/or other materials provided with the distribution.
    1.14 +- Neither the name of Internet Society, IETF or IETF Trust, nor the
    1.15 +names of specific contributors, may be used to endorse or promote
    1.16 +products derived from this software without specific prior written
    1.17 +permission.
    1.18 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    1.19 +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.20 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1.21 +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    1.22 +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    1.23 +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    1.24 +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    1.25 +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    1.26 +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    1.27 +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    1.28 +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 "main.h"
    1.36 +#include "stack_alloc.h"
    1.37 +
    1.38 +/* Convert Left/Right stereo signal to adaptive Mid/Side representation */
    1.39 +void silk_stereo_LR_to_MS(
    1.40 +    stereo_enc_state            *state,                         /* I/O  State                                       */
    1.41 +    opus_int16                  x1[],                           /* I/O  Left input signal, becomes mid signal       */
    1.42 +    opus_int16                  x2[],                           /* I/O  Right input signal, becomes side signal     */
    1.43 +    opus_int8                   ix[ 2 ][ 3 ],                   /* O    Quantization indices                        */
    1.44 +    opus_int8                   *mid_only_flag,                 /* O    Flag: only mid signal coded                 */
    1.45 +    opus_int32                  mid_side_rates_bps[],           /* O    Bitrates for mid and side signals           */
    1.46 +    opus_int32                  total_rate_bps,                 /* I    Total bitrate                               */
    1.47 +    opus_int                    prev_speech_act_Q8,             /* I    Speech activity level in previous frame     */
    1.48 +    opus_int                    toMono,                         /* I    Last frame before a stereo->mono transition */
    1.49 +    opus_int                    fs_kHz,                         /* I    Sample rate (kHz)                           */
    1.50 +    opus_int                    frame_length                    /* I    Number of samples                           */
    1.51 +)
    1.52 +{
    1.53 +    opus_int   n, is10msFrame, denom_Q16, delta0_Q13, delta1_Q13;
    1.54 +    opus_int32 sum, diff, smooth_coef_Q16, pred_Q13[ 2 ], pred0_Q13, pred1_Q13;
    1.55 +    opus_int32 LP_ratio_Q14, HP_ratio_Q14, frac_Q16, frac_3_Q16, min_mid_rate_bps, width_Q14, w_Q24, deltaw_Q24;
    1.56 +    VARDECL( opus_int16, side );
    1.57 +    VARDECL( opus_int16, LP_mid );
    1.58 +    VARDECL( opus_int16, HP_mid );
    1.59 +    VARDECL( opus_int16, LP_side );
    1.60 +    VARDECL( opus_int16, HP_side );
    1.61 +    opus_int16 *mid = &x1[ -2 ];
    1.62 +    SAVE_STACK;
    1.63 +
    1.64 +    ALLOC( side, frame_length + 2, opus_int16 );
    1.65 +    /* Convert to basic mid/side signals */
    1.66 +    for( n = 0; n < frame_length + 2; n++ ) {
    1.67 +        sum  = x1[ n - 2 ] + (opus_int32)x2[ n - 2 ];
    1.68 +        diff = x1[ n - 2 ] - (opus_int32)x2[ n - 2 ];
    1.69 +        mid[  n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 );
    1.70 +        side[ n ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( diff, 1 ) );
    1.71 +    }
    1.72 +
    1.73 +    /* Buffering */
    1.74 +    silk_memcpy( mid,  state->sMid,  2 * sizeof( opus_int16 ) );
    1.75 +    silk_memcpy( side, state->sSide, 2 * sizeof( opus_int16 ) );
    1.76 +    silk_memcpy( state->sMid,  &mid[  frame_length ], 2 * sizeof( opus_int16 ) );
    1.77 +    silk_memcpy( state->sSide, &side[ frame_length ], 2 * sizeof( opus_int16 ) );
    1.78 +
    1.79 +    /* LP and HP filter mid signal */
    1.80 +    ALLOC( LP_mid, frame_length, opus_int16 );
    1.81 +    ALLOC( HP_mid, frame_length, opus_int16 );
    1.82 +    for( n = 0; n < frame_length; n++ ) {
    1.83 +        sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 2 );
    1.84 +        LP_mid[ n ] = sum;
    1.85 +        HP_mid[ n ] = mid[ n + 1 ] - sum;
    1.86 +    }
    1.87 +
    1.88 +    /* LP and HP filter side signal */
    1.89 +    ALLOC( LP_side, frame_length, opus_int16 );
    1.90 +    ALLOC( HP_side, frame_length, opus_int16 );
    1.91 +    for( n = 0; n < frame_length; n++ ) {
    1.92 +        sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( side[ n ] + side[ n + 2 ], side[ n + 1 ], 1 ), 2 );
    1.93 +        LP_side[ n ] = sum;
    1.94 +        HP_side[ n ] = side[ n + 1 ] - sum;
    1.95 +    }
    1.96 +
    1.97 +    /* Find energies and predictors */
    1.98 +    is10msFrame = frame_length == 10 * fs_kHz;
    1.99 +    smooth_coef_Q16 = is10msFrame ?
   1.100 +        SILK_FIX_CONST( STEREO_RATIO_SMOOTH_COEF / 2, 16 ) :
   1.101 +        SILK_FIX_CONST( STEREO_RATIO_SMOOTH_COEF,     16 );
   1.102 +    smooth_coef_Q16 = silk_SMULWB( silk_SMULBB( prev_speech_act_Q8, prev_speech_act_Q8 ), smooth_coef_Q16 );
   1.103 +
   1.104 +    pred_Q13[ 0 ] = silk_stereo_find_predictor( &LP_ratio_Q14, LP_mid, LP_side, &state->mid_side_amp_Q0[ 0 ], frame_length, smooth_coef_Q16 );
   1.105 +    pred_Q13[ 1 ] = silk_stereo_find_predictor( &HP_ratio_Q14, HP_mid, HP_side, &state->mid_side_amp_Q0[ 2 ], frame_length, smooth_coef_Q16 );
   1.106 +    /* Ratio of the norms of residual and mid signals */
   1.107 +    frac_Q16 = silk_SMLABB( HP_ratio_Q14, LP_ratio_Q14, 3 );
   1.108 +    frac_Q16 = silk_min( frac_Q16, SILK_FIX_CONST( 1, 16 ) );
   1.109 +
   1.110 +    /* Determine bitrate distribution between mid and side, and possibly reduce stereo width */
   1.111 +    total_rate_bps -= is10msFrame ? 1200 : 600;      /* Subtract approximate bitrate for coding stereo parameters */
   1.112 +    if( total_rate_bps < 1 ) {
   1.113 +        total_rate_bps = 1;
   1.114 +    }
   1.115 +    min_mid_rate_bps = silk_SMLABB( 2000, fs_kHz, 900 );
   1.116 +    silk_assert( min_mid_rate_bps < 32767 );
   1.117 +    /* Default bitrate distribution: 8 parts for Mid and (5+3*frac) parts for Side. so: mid_rate = ( 8 / ( 13 + 3 * frac ) ) * total_ rate */
   1.118 +    frac_3_Q16 = silk_MUL( 3, frac_Q16 );
   1.119 +    mid_side_rates_bps[ 0 ] = silk_DIV32_varQ( total_rate_bps, SILK_FIX_CONST( 8 + 5, 16 ) + frac_3_Q16, 16+3 );
   1.120 +    /* If Mid bitrate below minimum, reduce stereo width */
   1.121 +    if( mid_side_rates_bps[ 0 ] < min_mid_rate_bps ) {
   1.122 +        mid_side_rates_bps[ 0 ] = min_mid_rate_bps;
   1.123 +        mid_side_rates_bps[ 1 ] = total_rate_bps - mid_side_rates_bps[ 0 ];
   1.124 +        /* width = 4 * ( 2 * side_rate - min_rate ) / ( ( 1 + 3 * frac ) * min_rate ) */
   1.125 +        width_Q14 = silk_DIV32_varQ( silk_LSHIFT( mid_side_rates_bps[ 1 ], 1 ) - min_mid_rate_bps,
   1.126 +            silk_SMULWB( SILK_FIX_CONST( 1, 16 ) + frac_3_Q16, min_mid_rate_bps ), 14+2 );
   1.127 +        width_Q14 = silk_LIMIT( width_Q14, 0, SILK_FIX_CONST( 1, 14 ) );
   1.128 +    } else {
   1.129 +        mid_side_rates_bps[ 1 ] = total_rate_bps - mid_side_rates_bps[ 0 ];
   1.130 +        width_Q14 = SILK_FIX_CONST( 1, 14 );
   1.131 +    }
   1.132 +
   1.133 +    /* Smoother */
   1.134 +    state->smth_width_Q14 = (opus_int16)silk_SMLAWB( state->smth_width_Q14, width_Q14 - state->smth_width_Q14, smooth_coef_Q16 );
   1.135 +
   1.136 +    /* At very low bitrates or for inputs that are nearly amplitude panned, switch to panned-mono coding */
   1.137 +    *mid_only_flag = 0;
   1.138 +    if( toMono ) {
   1.139 +        /* Last frame before stereo->mono transition; collapse stereo width */
   1.140 +        width_Q14 = 0;
   1.141 +        pred_Q13[ 0 ] = 0;
   1.142 +        pred_Q13[ 1 ] = 0;
   1.143 +        silk_stereo_quant_pred( pred_Q13, ix );
   1.144 +    } else if( state->width_prev_Q14 == 0 &&
   1.145 +        ( 8 * total_rate_bps < 13 * min_mid_rate_bps || silk_SMULWB( frac_Q16, state->smth_width_Q14 ) < SILK_FIX_CONST( 0.05, 14 ) ) )
   1.146 +    {
   1.147 +        /* Code as panned-mono; previous frame already had zero width */
   1.148 +        /* Scale down and quantize predictors */
   1.149 +        pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 );
   1.150 +        pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 );
   1.151 +        silk_stereo_quant_pred( pred_Q13, ix );
   1.152 +        /* Collapse stereo width */
   1.153 +        width_Q14 = 0;
   1.154 +        pred_Q13[ 0 ] = 0;
   1.155 +        pred_Q13[ 1 ] = 0;
   1.156 +        mid_side_rates_bps[ 0 ] = total_rate_bps;
   1.157 +        mid_side_rates_bps[ 1 ] = 0;
   1.158 +        *mid_only_flag = 1;
   1.159 +    } else if( state->width_prev_Q14 != 0 &&
   1.160 +        ( 8 * total_rate_bps < 11 * min_mid_rate_bps || silk_SMULWB( frac_Q16, state->smth_width_Q14 ) < SILK_FIX_CONST( 0.02, 14 ) ) )
   1.161 +    {
   1.162 +        /* Transition to zero-width stereo */
   1.163 +        /* Scale down and quantize predictors */
   1.164 +        pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 );
   1.165 +        pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 );
   1.166 +        silk_stereo_quant_pred( pred_Q13, ix );
   1.167 +        /* Collapse stereo width */
   1.168 +        width_Q14 = 0;
   1.169 +        pred_Q13[ 0 ] = 0;
   1.170 +        pred_Q13[ 1 ] = 0;
   1.171 +    } else if( state->smth_width_Q14 > SILK_FIX_CONST( 0.95, 14 ) ) {
   1.172 +        /* Full-width stereo coding */
   1.173 +        silk_stereo_quant_pred( pred_Q13, ix );
   1.174 +        width_Q14 = SILK_FIX_CONST( 1, 14 );
   1.175 +    } else {
   1.176 +        /* Reduced-width stereo coding; scale down and quantize predictors */
   1.177 +        pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 );
   1.178 +        pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 );
   1.179 +        silk_stereo_quant_pred( pred_Q13, ix );
   1.180 +        width_Q14 = state->smth_width_Q14;
   1.181 +    }
   1.182 +
   1.183 +    /* Make sure to keep on encoding until the tapered output has been transmitted */
   1.184 +    if( *mid_only_flag == 1 ) {
   1.185 +        state->silent_side_len += frame_length - STEREO_INTERP_LEN_MS * fs_kHz;
   1.186 +        if( state->silent_side_len < LA_SHAPE_MS * fs_kHz ) {
   1.187 +            *mid_only_flag = 0;
   1.188 +        } else {
   1.189 +            /* Limit to avoid wrapping around */
   1.190 +            state->silent_side_len = 10000;
   1.191 +        }
   1.192 +    } else {
   1.193 +        state->silent_side_len = 0;
   1.194 +    }
   1.195 +
   1.196 +    if( *mid_only_flag == 0 && mid_side_rates_bps[ 1 ] < 1 ) {
   1.197 +        mid_side_rates_bps[ 1 ] = 1;
   1.198 +        mid_side_rates_bps[ 0 ] = silk_max_int( 1, total_rate_bps - mid_side_rates_bps[ 1 ]);
   1.199 +    }
   1.200 +
   1.201 +    /* Interpolate predictors and subtract prediction from side channel */
   1.202 +    pred0_Q13  = -state->pred_prev_Q13[ 0 ];
   1.203 +    pred1_Q13  = -state->pred_prev_Q13[ 1 ];
   1.204 +    w_Q24      =  silk_LSHIFT( state->width_prev_Q14, 10 );
   1.205 +    denom_Q16  = silk_DIV32_16( (opus_int32)1 << 16, STEREO_INTERP_LEN_MS * fs_kHz );
   1.206 +    delta0_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 0 ] - state->pred_prev_Q13[ 0 ], denom_Q16 ), 16 );
   1.207 +    delta1_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 1 ] - state->pred_prev_Q13[ 1 ], denom_Q16 ), 16 );
   1.208 +    deltaw_Q24 =  silk_LSHIFT( silk_SMULWB( width_Q14 - state->width_prev_Q14, denom_Q16 ), 10 );
   1.209 +    for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) {
   1.210 +        pred0_Q13 += delta0_Q13;
   1.211 +        pred1_Q13 += delta1_Q13;
   1.212 +        w_Q24   += deltaw_Q24;
   1.213 +        sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 );    /* Q11 */
   1.214 +        sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 );               /* Q8  */
   1.215 +        sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 );       /* Q8  */
   1.216 +        x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );
   1.217 +    }
   1.218 +
   1.219 +    pred0_Q13 = -pred_Q13[ 0 ];
   1.220 +    pred1_Q13 = -pred_Q13[ 1 ];
   1.221 +    w_Q24     =  silk_LSHIFT( width_Q14, 10 );
   1.222 +    for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) {
   1.223 +        sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 );    /* Q11 */
   1.224 +        sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 );               /* Q8  */
   1.225 +        sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 );       /* Q8  */
   1.226 +        x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );
   1.227 +    }
   1.228 +    state->pred_prev_Q13[ 0 ] = (opus_int16)pred_Q13[ 0 ];
   1.229 +    state->pred_prev_Q13[ 1 ] = (opus_int16)pred_Q13[ 1 ];
   1.230 +    state->width_prev_Q14     = (opus_int16)width_Q14;
   1.231 +    RESTORE_STACK;
   1.232 +}

mercurial