1 //
2 // Copyright 2017 Ettus Research LLC
3 // Copyright 2018 Ettus Research, a National Instruments Company
4 //
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7 
8 #include "convert_pack_sc12.hpp"
9 
10 using namespace uhd::convert;
11 
12 template <typename type, towire32_type towire>
13 struct convert_star_1_to_sc12_item32_1 : public converter
14 {
convert_star_1_to_sc12_item32_1convert_star_1_to_sc12_item32_115     convert_star_1_to_sc12_item32_1(void) : _scalar(0.0)
16     {
17         // NOP
18     }
19 
set_scalarconvert_star_1_to_sc12_item32_120     void set_scalar(const double scalar)
21     {
22         _scalar = scalar;
23     }
24 
operator ()convert_star_1_to_sc12_item32_125     void operator()(
26         const input_type& inputs, const output_type& outputs, const size_t nsamps)
27     {
28         const std::complex<type>* input =
29             reinterpret_cast<const std::complex<type>*>(inputs[0]);
30 
31         /*
32          * Effectively outputs will point to a managed_buffer instance. These buffers are
33          * 32 bit aligned. For a detailed description see comments in
34          * 'convert_unpack_sc12.cpp'.
35          */
36         const size_t head_samps = size_t(outputs[0]) & 0x3;
37         int enable;
38         size_t rewind = 0;
39         switch (head_samps) {
40             case 0:
41                 break;
42             case 1:
43                 rewind = 9;
44                 break;
45             case 2:
46                 rewind = 6;
47                 break;
48             case 3:
49                 rewind = 3;
50                 break;
51         }
52         item32_sc12_3x* output =
53             reinterpret_cast<item32_sc12_3x*>(size_t(outputs[0]) - rewind);
54 
55         // helper variables
56         size_t i = 0, o = 0;
57 
58         // handle the head case
59         switch (head_samps) {
60             case 0:
61                 break; // no head
62             case 1:
63                 enable = CONVERT12_LINE2;
64                 convert_star_4_to_sc12_item32_3<type, towire>(
65                     0, 0, 0, input[0], enable, output[o++], _scalar);
66                 break;
67             case 2:
68                 enable = CONVERT12_LINE2 | CONVERT12_LINE1;
69                 convert_star_4_to_sc12_item32_3<type, towire>(
70                     0, 0, input[0], input[1], enable, output[o++], _scalar);
71                 break;
72             case 3:
73                 enable = CONVERT12_LINE2 | CONVERT12_LINE1 | CONVERT12_LINE0;
74                 convert_star_4_to_sc12_item32_3<type, towire>(
75                     0, input[0], input[1], input[2], enable, output[o++], _scalar);
76                 break;
77         }
78         i += head_samps;
79 
80         // convert the body
81         while (i + 3 < nsamps) {
82             convert_star_4_to_sc12_item32_3<type, towire>(input[i + 0],
83                 input[i + 1],
84                 input[i + 2],
85                 input[i + 3],
86                 CONVERT12_LINE_ALL,
87                 output[o],
88                 _scalar);
89             o++;
90             i += 4;
91         }
92 
93         // handle the tail case
94         const size_t tail_samps = nsamps - i;
95         switch (tail_samps) {
96             case 0:
97                 break; // no tail
98             case 1:
99                 enable = CONVERT12_LINE0;
100                 convert_star_4_to_sc12_item32_3<type, towire>(
101                     input[i + 0], 0, 0, 0, enable, output[o], _scalar);
102                 break;
103             case 2:
104                 enable = CONVERT12_LINE0 | CONVERT12_LINE1;
105                 convert_star_4_to_sc12_item32_3<type, towire>(
106                     input[i + 0], input[i + 1], 0, 0, enable, output[o], _scalar);
107                 break;
108             case 3:
109                 enable = CONVERT12_LINE0 | CONVERT12_LINE1 | CONVERT12_LINE2;
110                 convert_star_4_to_sc12_item32_3<type, towire>(input[i + 0],
111                     input[i + 1],
112                     input[i + 2],
113                     0,
114                     enable,
115                     output[o],
116                     _scalar);
117                 break;
118         }
119     }
120 
121     double _scalar;
122 };
123 
make_convert_fc32_1_to_sc12_item32_le_1(void)124 static converter::sptr make_convert_fc32_1_to_sc12_item32_le_1(void)
125 {
126     return converter::sptr(new convert_star_1_to_sc12_item32_1<float, uhd::wtohx>());
127 }
128 
make_convert_fc32_1_to_sc12_item32_be_1(void)129 static converter::sptr make_convert_fc32_1_to_sc12_item32_be_1(void)
130 {
131     return converter::sptr(new convert_star_1_to_sc12_item32_1<float, uhd::ntohx>());
132 }
133 
make_convert_sc16_1_to_sc12_item32_le_1(void)134 static converter::sptr make_convert_sc16_1_to_sc12_item32_le_1(void)
135 {
136     return converter::sptr(new convert_star_1_to_sc12_item32_1<short, uhd::wtohx>());
137 }
138 
make_convert_sc16_1_to_sc12_item32_be_1(void)139 static converter::sptr make_convert_sc16_1_to_sc12_item32_be_1(void)
140 {
141     return converter::sptr(new convert_star_1_to_sc12_item32_1<short, uhd::ntohx>());
142 }
143 
UHD_STATIC_BLOCK(register_convert_pack_sc12)144 UHD_STATIC_BLOCK(register_convert_pack_sc12)
145 {
146     // uhd::convert::register_bytes_per_item("sc12", 3/*bytes*/); //registered in unpack
147 
148     uhd::convert::id_type id;
149     id.num_inputs  = 1;
150     id.num_outputs = 1;
151 
152     id.input_format  = "fc32";
153     id.output_format = "sc12_item32_le";
154     uhd::convert::register_converter(
155         id, &make_convert_fc32_1_to_sc12_item32_le_1, PRIORITY_GENERAL);
156     id.output_format = "sc12_item32_be";
157     uhd::convert::register_converter(
158         id, &make_convert_fc32_1_to_sc12_item32_be_1, PRIORITY_GENERAL);
159 
160     id.input_format  = "sc16";
161     id.output_format = "sc12_item32_le";
162     uhd::convert::register_converter(
163         id, &make_convert_sc16_1_to_sc12_item32_le_1, PRIORITY_GENERAL);
164     id.output_format = "sc12_item32_be";
165     uhd::convert::register_converter(
166         id, &make_convert_sc16_1_to_sc12_item32_be_1, PRIORITY_GENERAL);
167 }
168