GNU Radio Manual and C++ API Reference  3.7.7
The Free & Open Software Radio Ecosystem
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
volk_8ic_x2_multiply_conjugate_16ic.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2012, 2014 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef INCLUDED_volk_8ic_x2_multiply_conjugate_16ic_a_H
24 #define INCLUDED_volk_8ic_x2_multiply_conjugate_16ic_a_H
25 
26 #include <inttypes.h>
27 #include <stdio.h>
28 #include <volk/volk_complex.h>
29 
30 #ifdef LV_HAVE_SSE4_1
31 #include <smmintrin.h>
32 /*!
33  \brief Multiplys the one complex vector with the complex conjugate of the second complex vector and stores their results in the third vector
34  \param cVector The complex vector where the results will be stored
35  \param aVector One of the complex vectors to be multiplied
36  \param bVector The complex vector which will be converted to complex conjugate and multiplied
37  \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
38 */
39 static inline void volk_8ic_x2_multiply_conjugate_16ic_a_sse4_1(lv_16sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t* bVector, unsigned int num_points){
40  unsigned int number = 0;
41  const unsigned int quarterPoints = num_points / 4;
42 
43  __m128i x, y, realz, imagz;
44  lv_16sc_t* c = cVector;
45  const lv_8sc_t* a = aVector;
46  const lv_8sc_t* b = bVector;
47  __m128i conjugateSign = _mm_set_epi16(-1, 1, -1, 1, -1, 1, -1, 1);
48 
49  for(;number < quarterPoints; number++){
50  // Convert into 8 bit values into 16 bit values
51  x = _mm_cvtepi8_epi16(_mm_loadl_epi64((__m128i*)a));
52  y = _mm_cvtepi8_epi16(_mm_loadl_epi64((__m128i*)b));
53 
54  // Calculate the ar*cr - ai*(-ci) portions
55  realz = _mm_madd_epi16(x,y);
56 
57  // Calculate the complex conjugate of the cr + ci j values
58  y = _mm_sign_epi16(y, conjugateSign);
59 
60  // Shift the order of the cr and ci values
61  y = _mm_shufflehi_epi16(_mm_shufflelo_epi16(y, _MM_SHUFFLE(2,3,0,1) ), _MM_SHUFFLE(2,3,0,1));
62 
63  // Calculate the ar*(-ci) + cr*(ai)
64  imagz = _mm_madd_epi16(x,y);
65 
66  _mm_store_si128((__m128i*)c, _mm_packs_epi32(_mm_unpacklo_epi32(realz, imagz), _mm_unpackhi_epi32(realz, imagz)));
67 
68  a += 4;
69  b += 4;
70  c += 4;
71  }
72 
73  number = quarterPoints * 4;
74  int16_t* c16Ptr = (int16_t*)&cVector[number];
75  int8_t* a8Ptr = (int8_t*)&aVector[number];
76  int8_t* b8Ptr = (int8_t*)&bVector[number];
77  for(; number < num_points; number++){
78  float aReal = (float)*a8Ptr++;
79  float aImag = (float)*a8Ptr++;
80  lv_32fc_t aVal = lv_cmake(aReal, aImag );
81  float bReal = (float)*b8Ptr++;
82  float bImag = (float)*b8Ptr++;
83  lv_32fc_t bVal = lv_cmake( bReal, -bImag );
84  lv_32fc_t temp = aVal * bVal;
85 
86  *c16Ptr++ = (int16_t)lv_creal(temp);
87  *c16Ptr++ = (int16_t)lv_cimag(temp);
88  }
89 }
90 #endif /* LV_HAVE_SSE4_1 */
91 
92 #ifdef LV_HAVE_GENERIC
93 /*!
94  \brief Multiplys the one complex vector with the complex conjugate of the second complex vector and stores their results in the third vector
95  \param cVector The complex vector where the results will be stored
96  \param aVector One of the complex vectors to be multiplied
97  \param bVector The complex vector which will be converted to complex conjugate and multiplied
98  \param num_points The number of complex values in aVector and bVector to be multiplied together and stored into cVector
99 */
100 static inline void volk_8ic_x2_multiply_conjugate_16ic_generic(lv_16sc_t* cVector, const lv_8sc_t* aVector, const lv_8sc_t* bVector, unsigned int num_points){
101  unsigned int number = 0;
102  int16_t* c16Ptr = (int16_t*)cVector;
103  int8_t* a8Ptr = (int8_t*)aVector;
104  int8_t* b8Ptr = (int8_t*)bVector;
105  for(number =0; number < num_points; number++){
106  float aReal = (float)*a8Ptr++;
107  float aImag = (float)*a8Ptr++;
108  lv_32fc_t aVal = lv_cmake(aReal, aImag );
109  float bReal = (float)*b8Ptr++;
110  float bImag = (float)*b8Ptr++;
111  lv_32fc_t bVal = lv_cmake( bReal, -bImag );
112  lv_32fc_t temp = aVal * bVal;
113 
114  *c16Ptr++ = (int16_t)lv_creal(temp);
115  *c16Ptr++ = (int16_t)lv_cimag(temp);
116  }
117 }
118 #endif /* LV_HAVE_GENERIC */
119 
120 
121 
122 
123 #endif /* INCLUDED_volk_8ic_x2_multiply_conjugate_16ic_a_H */
short complex lv_16sc_t
Definition: volk_complex.h:53
#define lv_cmake(r, i)
Definition: volk_complex.h:59
signed short int16_t
Definition: stdint.h:76
signed char int8_t
Definition: stdint.h:75
float complex lv_32fc_t
Definition: volk_complex.h:56
#define lv_creal(x)
Definition: volk_complex.h:76
char complex lv_8sc_t
Provide typedefs and operators for all complex types in C and C++.
Definition: volk_complex.h:52
#define lv_cimag(x)
Definition: volk_complex.h:78