aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/convert/convert_pack_sc12.cpp
blob: 97a4af206d44c9463fd9ee7853631fe4ffc5ea8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//
// Copyright 2017 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//

#include "convert_pack_sc12.hpp"

using namespace uhd::convert;

template <typename type, towire32_type towire>
struct convert_star_1_to_sc12_item32_1 : public converter
{
    convert_star_1_to_sc12_item32_1(void):_scalar(0.0)
    {
        //NOP
    }

    void set_scalar(const double scalar)
    {
        _scalar = scalar;
    }

    void operator()(const input_type &inputs, const output_type &outputs, const size_t nsamps)
    {
        const std::complex<type> *input = reinterpret_cast<const std::complex<type> *>(inputs[0]);

        /*
         * Effectively outputs will point to a managed_buffer instance. These buffers are 32 bit aligned.
         * For a detailed description see comments in 'convert_unpack_sc12.cpp'.
         */
        const size_t head_samps = size_t(outputs[0]) & 0x3;
        int enable;
        size_t rewind = 0;
        switch(head_samps)
        {
            case 0: break;
            case 1: rewind = 9; break;
            case 2: rewind = 6; break;
            case 3: rewind = 3; break;
        }
        item32_sc12_3x *output = reinterpret_cast<item32_sc12_3x *>(size_t(outputs[0]) - rewind);

        //helper variables
        size_t i = 0, o = 0;

        //handle the head case
        switch (head_samps)
        {
        case 0:
            break; //no head
        case 1:
            enable = CONVERT12_LINE2;
            convert_star_4_to_sc12_item32_3<type, towire>(0, 0, 0, input[0], enable, output[o++], _scalar);
            break;
        case 2:
            enable = CONVERT12_LINE2 | CONVERT12_LINE1;
            convert_star_4_to_sc12_item32_3<type, towire>(0, 0, input[0], input[1], enable, output[o++], _scalar);
            break;
        case 3:
            enable = CONVERT12_LINE2 | CONVERT12_LINE1 | CONVERT12_LINE0;
            convert_star_4_to_sc12_item32_3<type, towire>(0, input[0], input[1], input[2], enable, output[o++], _scalar);
            break;
        }
        i += head_samps;

        //convert the body
        while (i+3 < nsamps)
        {
            convert_star_4_to_sc12_item32_3<type, towire>(input[i+0], input[i+1], input[i+2], input[i+3], CONVERT12_LINE_ALL, output[o], _scalar);
            o++; i += 4;
        }

        //handle the tail case
        const size_t tail_samps = nsamps - i;
        switch (tail_samps)
        {
        case 0:
            break; //no tail
        case 1:
            enable = CONVERT12_LINE0;
            convert_star_4_to_sc12_item32_3<type, towire>(input[i+0], 0, 0, 0, enable, output[o], _scalar);
            break;
        case 2:
            enable = CONVERT12_LINE0 | CONVERT12_LINE1;
            convert_star_4_to_sc12_item32_3<type, towire>(input[i+0], input[i+1], 0, 0, enable, output[o], _scalar);
            break;
        case 3:
            enable = CONVERT12_LINE0 | CONVERT12_LINE1 | CONVERT12_LINE2;
            convert_star_4_to_sc12_item32_3<type, towire>(input[i+0], input[i+1], input[i+2], 0, enable, output[o], _scalar);
            break;
        }
    }

    double _scalar;
};

static converter::sptr make_convert_fc32_1_to_sc12_item32_le_1(void)
{
    return converter::sptr(new convert_star_1_to_sc12_item32_1<float, uhd::wtohx>());
}

static converter::sptr make_convert_fc32_1_to_sc12_item32_be_1(void)
{
    return converter::sptr(new convert_star_1_to_sc12_item32_1<float, uhd::ntohx>());
}

static converter::sptr make_convert_sc16_1_to_sc12_item32_le_1(void)
{
    return converter::sptr(new convert_star_1_to_sc12_item32_1<short, uhd::wtohx>());
}

static converter::sptr make_convert_sc16_1_to_sc12_item32_be_1(void)
{
    return converter::sptr(new convert_star_1_to_sc12_item32_1<short, uhd::ntohx>());
}

UHD_STATIC_BLOCK(register_convert_pack_sc12)
{
    //uhd::convert::register_bytes_per_item("sc12", 3/*bytes*/); //registered in unpack

    uhd::convert::id_type id;
    id.num_inputs = 1;
    id.num_outputs = 1;

    id.input_format = "fc32";
    id.output_format = "sc12_item32_le";
    uhd::convert::register_converter(id, &make_convert_fc32_1_to_sc12_item32_le_1, PRIORITY_GENERAL);
    id.output_format = "sc12_item32_be";
    uhd::convert::register_converter(id, &make_convert_fc32_1_to_sc12_item32_be_1, PRIORITY_GENERAL);

    id.input_format = "sc16";
    id.output_format = "sc12_item32_le";
    uhd::convert::register_converter(id, &make_convert_sc16_1_to_sc12_item32_le_1, PRIORITY_GENERAL);
    id.output_format = "sc12_item32_be";
    uhd::convert::register_converter(id, &make_convert_sc16_1_to_sc12_item32_be_1, PRIORITY_GENERAL);
}