Home | History | Annotate | Download | only in libFLAC
      1 /* libFLAC - Free Lossless Audio Codec library
      2  * Copyright (C) 2000-2009  Josh Coalson
      3  * Copyright (C) 2011-2016  Xiph.Org Foundation
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * - Redistributions of source code must retain the above copyright
     10  * notice, this list of conditions and the following disclaimer.
     11  *
     12  * - Redistributions in binary form must reproduce the above copyright
     13  * notice, this list of conditions and the following disclaimer in the
     14  * documentation and/or other materials provided with the distribution.
     15  *
     16  * - Neither the name of the Xiph.org Foundation nor the names of its
     17  * contributors may be used to endorse or promote products derived from
     18  * this software without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     23  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
     24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 #ifdef HAVE_CONFIG_H
     34 #  include <config.h>
     35 #endif
     36 
     37 #include "private/cpu.h"
     38 
     39 #ifndef FLAC__INTEGER_ONLY_LIBRARY
     40 #ifndef FLAC__NO_ASM
     41 #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN
     42 #include "private/fixed.h"
     43 #ifdef FLAC__SSSE3_SUPPORTED
     44 
     45 #include <tmmintrin.h> /* SSSE3 */
     46 #include <math.h>
     47 #include "private/macros.h"
     48 #include "share/compat.h"
     49 #include "FLAC/assert.h"
     50 
     51 #ifdef FLAC__CPU_IA32
     52 #define m128i_to_i64(dest, src) _mm_storel_epi64((__m128i*)&dest, src)
     53 #else
     54 #define m128i_to_i64(dest, src) dest = _mm_cvtsi128_si64(src)
     55 #endif
     56 
     57 FLAC__SSE_TARGET("ssse3")
     58 unsigned FLAC__fixed_compute_best_predictor_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1])
     59 {
     60 	FLAC__uint32 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4;
     61 	unsigned i, order;
     62 
     63 	__m128i total_err0, total_err1, total_err2;
     64 
     65 	{
     66 		FLAC__int32 itmp;
     67 		__m128i last_error;
     68 
     69 		last_error = _mm_cvtsi32_si128(data[-1]);							// 0   0   0   le0
     70 		itmp = data[-2];
     71 		last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
     72 		last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp));	// 0   0   le0 le1
     73 		itmp -= data[-3];
     74 		last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
     75 		last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp));	// 0   le0 le1 le2
     76 		itmp -= data[-3] - data[-4];
     77 		last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
     78 		last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp));	// le0 le1 le2 le3
     79 
     80 		total_err0 = total_err1 = _mm_setzero_si128();
     81 		for(i = 0; i < data_len; i++) {
     82 			__m128i err0, err1;
     83 			err0 = _mm_cvtsi32_si128(data[i]);								// 0   0   0   e0
     84 			err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0));			// e0  e0  e0  e0
     85 #if 1 /* OPT_SSE */
     86 			err1 = _mm_sub_epi32(err1, last_error);
     87 			last_error = _mm_srli_si128(last_error, 4);						// 0   le0 le1 le2
     88 			err1 = _mm_sub_epi32(err1, last_error);
     89 			last_error = _mm_srli_si128(last_error, 4);						// 0   0   le0 le1
     90 			err1 = _mm_sub_epi32(err1, last_error);
     91 			last_error = _mm_srli_si128(last_error, 4);						// 0   0   0   le0
     92 			err1 = _mm_sub_epi32(err1, last_error);							// e1  e2  e3  e4
     93 #else
     94 			last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8));	// le0  le1  le2+le0  le3+le1
     95 			last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4));	// le0  le1+le0  le2+le0+le1  le3+le1+le2+le0
     96 			err1 = _mm_sub_epi32(err1, last_error);							// e1  e2  e3  e4
     97 #endif
     98 			last_error = _mm_alignr_epi8(err0, err1, 4);					// e0  e1  e2  e3
     99 
    100 			err0 = _mm_abs_epi32(err0);
    101 			err1 = _mm_abs_epi32(err1);
    102 
    103 			total_err0 = _mm_add_epi32(total_err0, err0);					// 0   0   0   te0
    104 			total_err1 = _mm_add_epi32(total_err1, err1);					// te1 te2 te3 te4
    105 		}
    106 	}
    107 
    108 	total_error_0 = _mm_cvtsi128_si32(total_err0);
    109 	total_err2 = total_err1;											// te1  te2  te3  te4
    110 	total_err1 = _mm_srli_si128(total_err1, 8);							//  0    0   te1  te2
    111 	total_error_4 = _mm_cvtsi128_si32(total_err2);
    112 	total_error_2 = _mm_cvtsi128_si32(total_err1);
    113 	total_err2 = _mm_srli_si128(total_err2,	4);							//  0   te1  te2  te3
    114 	total_err1 = _mm_srli_si128(total_err1, 4);							//  0    0    0   te1
    115 	total_error_3 = _mm_cvtsi128_si32(total_err2);
    116 	total_error_1 = _mm_cvtsi128_si32(total_err1);
    117 
    118 	/* prefer higher order */
    119 	if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
    120 		order = 0;
    121 	else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4))
    122 		order = 1;
    123 	else if(total_error_2 < flac_min(total_error_3, total_error_4))
    124 		order = 2;
    125 	else if(total_error_3 < total_error_4)
    126 		order = 3;
    127 	else
    128 		order = 4;
    129 
    130 	/* Estimate the expected number of bits per residual signal sample. */
    131 	/* 'total_error*' is linearly related to the variance of the residual */
    132 	/* signal, so we use it directly to compute E(|x|) */
    133 	FLAC__ASSERT(data_len > 0 || total_error_0 == 0);
    134 	FLAC__ASSERT(data_len > 0 || total_error_1 == 0);
    135 	FLAC__ASSERT(data_len > 0 || total_error_2 == 0);
    136 	FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
    137 	FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
    138 
    139 	residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0);
    140 	residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0);
    141 	residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0);
    142 	residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0);
    143 	residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0);
    144 
    145 	return order;
    146 }
    147 
    148 FLAC__SSE_TARGET("ssse3")
    149 unsigned FLAC__fixed_compute_best_predictor_wide_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1])
    150 {
    151 	FLAC__uint64 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4;
    152 	unsigned i, order;
    153 
    154 	__m128i total_err0, total_err1, total_err3;
    155 
    156 	{
    157 		FLAC__int32 itmp;
    158 		__m128i last_error, zero = _mm_setzero_si128();
    159 
    160 		last_error = _mm_cvtsi32_si128(data[-1]);							// 0   0   0   le0
    161 		itmp = data[-2];
    162 		last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
    163 		last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp));	// 0   0   le0 le1
    164 		itmp -= data[-3];
    165 		last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
    166 		last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp));	// 0   le0 le1 le2
    167 		itmp -= data[-3] - data[-4];
    168 		last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
    169 		last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp));	// le0 le1 le2 le3
    170 
    171 		total_err0 = total_err1 = total_err3 = _mm_setzero_si128();
    172 		for(i = 0; i < data_len; i++) {
    173 			__m128i err0, err1;
    174 			err0 = _mm_cvtsi32_si128(data[i]);								// 0   0   0   e0
    175 			err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0));			// e0  e0  e0  e0
    176 #if 1 /* OPT_SSE */
    177 			err1 = _mm_sub_epi32(err1, last_error);
    178 			last_error = _mm_srli_si128(last_error, 4);						// 0   le0 le1 le2
    179 			err1 = _mm_sub_epi32(err1, last_error);
    180 			last_error = _mm_srli_si128(last_error, 4);						// 0   0   le0 le1
    181 			err1 = _mm_sub_epi32(err1, last_error);
    182 			last_error = _mm_srli_si128(last_error, 4);						// 0   0   0   le0
    183 			err1 = _mm_sub_epi32(err1, last_error);							// e1  e2  e3  e4
    184 #else
    185 			last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8));	// le0  le1  le2+le0  le3+le1
    186 			last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4));	// le0  le1+le0  le2+le0+le1  le3+le1+le2+le0
    187 			err1 = _mm_sub_epi32(err1, last_error);							// e1  e2  e3  e4
    188 #endif
    189 			last_error = _mm_alignr_epi8(err0, err1, 4);					// e0  e1  e2  e3
    190 
    191 			err0 = _mm_abs_epi32(err0);
    192 			err1 = _mm_abs_epi32(err1);										// |e1| |e2| |e3| |e4|
    193 
    194 			total_err0 = _mm_add_epi64(total_err0, err0);					//        0       te0
    195 			err0 = _mm_unpacklo_epi32(err1, zero);							//   0  |e3|   0  |e4|
    196 			err1 = _mm_unpackhi_epi32(err1, zero);							//   0  |e1|   0  |e2|
    197 			total_err3 = _mm_add_epi64(total_err3, err0);					//       te3      te4
    198 			total_err1 = _mm_add_epi64(total_err1, err1);					//       te1      te2
    199 		}
    200 	}
    201 
    202 	m128i_to_i64(total_error_0, total_err0);
    203 	m128i_to_i64(total_error_4, total_err3);
    204 	m128i_to_i64(total_error_2, total_err1);
    205 	total_err3 = _mm_srli_si128(total_err3,	8);							//         0      te3
    206 	total_err1 = _mm_srli_si128(total_err1, 8);							//         0      te1
    207 	m128i_to_i64(total_error_3, total_err3);
    208 	m128i_to_i64(total_error_1, total_err1);
    209 
    210 	/* prefer higher order */
    211 	if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4))
    212 		order = 0;
    213 	else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4))
    214 		order = 1;
    215 	else if(total_error_2 < flac_min(total_error_3, total_error_4))
    216 		order = 2;
    217 	else if(total_error_3 < total_error_4)
    218 		order = 3;
    219 	else
    220 		order = 4;
    221 
    222 	/* Estimate the expected number of bits per residual signal sample. */
    223 	/* 'total_error*' is linearly related to the variance of the residual */
    224 	/* signal, so we use it directly to compute E(|x|) */
    225 	FLAC__ASSERT(data_len > 0 || total_error_0 == 0);
    226 	FLAC__ASSERT(data_len > 0 || total_error_1 == 0);
    227 	FLAC__ASSERT(data_len > 0 || total_error_2 == 0);
    228 	FLAC__ASSERT(data_len > 0 || total_error_3 == 0);
    229 	FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
    230 
    231 	residual_bits_per_sample[0] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0);
    232 	residual_bits_per_sample[1] = (float)((total_error_1 > 0) ? log(M_LN2 * (double)total_error_1 / (double)data_len) / M_LN2 : 0.0);
    233 	residual_bits_per_sample[2] = (float)((total_error_2 > 0) ? log(M_LN2 * (double)total_error_2 / (double)data_len) / M_LN2 : 0.0);
    234 	residual_bits_per_sample[3] = (float)((total_error_3 > 0) ? log(M_LN2 * (double)total_error_3 / (double)data_len) / M_LN2 : 0.0);
    235 	residual_bits_per_sample[4] = (float)((total_error_4 > 0) ? log(M_LN2 * (double)total_error_4 / (double)data_len) / M_LN2 : 0.0);
    236 
    237 	return order;
    238 }
    239 
    240 #endif /* FLAC__SSSE3_SUPPORTED */
    241 #endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
    242 #endif /* FLAC__NO_ASM */
    243 #endif /* FLAC__INTEGER_ONLY_LIBRARY */
    244