//
// Copyright 2017 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
#include
#include
#include "convert_common.hpp"
using namespace uhd::convert;
typedef uint32_t (*tohost32_type)(uint32_t);
/* C language specification requires this to be packed
* (i.e., line0, line1, line2 will be in adjacent memory locations).
* If this was not true, we'd need compiler flags here to specify
* alignment/packing.
*/
struct item32_sc12_3x
{
item32_t line0;
item32_t line1;
item32_t line2;
};
/*
* convert_sc12_item32_3_to_star_4 takes in 3 lines with 32 bit each
* and converts them 4 samples of type 'std::complex'.
* The structure of the 3 lines is as follows:
* _ _ _ _ _ _ _ _
* |_ _ _1_ _ _|_ _|
* |_2_ _ _|_ _ _3_|
* |_ _|_ _ _4_ _ _|
*
* The numbers mark the position of one complex sample.
*/
template
void convert_sc12_item32_3_to_star_4
(
const item32_sc12_3x &input,
std::complex &out0,
std::complex &out1,
std::complex &out2,
std::complex &out3,
const double scalar,
typename std::enable_if::value>::type* = NULL
)
{
//step 0: extract the lines from the input buffer
const item32_t line0 = tohost(input.line0);
const item32_t line1 = tohost(input.line1);
const item32_t line2 = tohost(input.line2);
const uint64_t line01 = (uint64_t(line0) << 32) | line1;
const uint64_t line12 = (uint64_t(line1) << 32) | line2;
//step 1: shift out and mask off the individual numbers
const type i0 = type(int16_t((line0 >> 16) & 0xfff0)*scalar);
const type q0 = type(int16_t((line0 >> 4) & 0xfff0)*scalar);
const type i1 = type(int16_t((line01 >> 24) & 0xfff0)*scalar);
const type q1 = type(int16_t((line1 >> 12) & 0xfff0)*scalar);
const type i2 = type(int16_t((line1 >> 0) & 0xfff0)*scalar);
const type q2 = type(int16_t((line12 >> 20) & 0xfff0)*scalar);
const type i3 = type(int16_t((line2 >> 8) & 0xfff0)*scalar);
const type q3 = type(int16_t((line2 << 4) & 0xfff0)*scalar);
//step 2: load the outputs
out0 = std::complex(i0, q0);
out1 = std::complex(i1, q1);
out2 = std::complex(i2, q2);
out3 = std::complex(i3, q3);
}
template
void convert_sc12_item32_3_to_star_4
(
const item32_sc12_3x &input,
std::complex &out0,
std::complex &out1,
std::complex &out2,
std::complex &out3,
const double,
typename std::enable_if::value>::type* = NULL
)
{
//step 0: extract the lines from the input buffer
const item32_t line0 = tohost(input.line0);
const item32_t line1 = tohost(input.line1);
const item32_t line2 = tohost(input.line2);
const uint64_t line01 = (uint64_t(line0) << 32) | line1;
const uint64_t line12 = (uint64_t(line1) << 32) | line2;
//step 1: extract and load the outputs
out0 = std::complex(line0 >> 16 & 0xfff0, line0 >> 4 & 0xfff0);
out1 = std::complex(line01 >> 24 & 0xfff0, line1 >> 12 & 0xfff0);
out2 = std::complex(line1 >> 0 & 0xfff0, line12 >> 20 & 0xfff0);
out3 = std::complex(line2 >> 8 & 0xfff0, line2 << 4 & 0xfff0);
}