1 ///
2 /// \file SoapySDR/ConverterPrimatives.hpp
3 ///
4 /// inline Soapy real format Converter Primitives.
5 ///
6 /// \copyright
7 /// Copyright (c) 2017-2018 Coburn Wightman
8 /// SPDX-License-Identifier: BSL-1.0
9 ///
10 
11 #pragma once
12 #include <stdint.h>
13 
14 namespace SoapySDR
15 {
16 
17 const uint32_t U32_ZERO_OFFSET = uint32_t(1<<31);
18 const uint16_t U16_ZERO_OFFSET = uint16_t(1<<15);
19 const uint8_t   U8_ZERO_OFFSET =  uint8_t(1<<7);
20 
21 const uint32_t S32_FULL_SCALE = uint32_t(1<<31);
22 const uint16_t S16_FULL_SCALE = uint16_t(1<<15);
23 const uint8_t   S8_FULL_SCALE =  uint8_t(1<<7);
24 
25 /*!
26  * Conversion Primitives for converting real values between Soapy formats.
27  * \param from the value to convert from
28  * \return the converted value
29  */
30 
31 // type conversion: float <> signed integers
32 
F32toS32(float from)33 inline int32_t F32toS32(float from){
34   return int32_t(from * S32_FULL_SCALE);
35 }
S32toF32(int32_t from)36 inline float S32toF32(int32_t from){
37   return float(from) / S32_FULL_SCALE;
38 }
39 
F32toS16(float from)40 inline int16_t F32toS16(float from){
41   return int16_t(from * S16_FULL_SCALE);
42 }
S16toF32(int16_t from)43 inline float S16toF32(int16_t from){
44   return float(from) / S16_FULL_SCALE;
45 }
46 
F32toS8(float from)47 inline int8_t F32toS8(float from){
48   return int8_t(from * S8_FULL_SCALE);
49 }
S8toF32(int8_t from)50 inline float S8toF32(int8_t from){
51   return float(from) / S8_FULL_SCALE;
52 }
53 
54 
55 // type conversion: offset binary <> two's complement (signed) integers
56 
U32toS32(uint32_t from)57 inline int32_t U32toS32(uint32_t from){
58   return int32_t(from - U32_ZERO_OFFSET);
59 }
60 
S32toU32(int32_t from)61 inline uint32_t S32toU32(int32_t from){
62   return uint32_t(from) + U32_ZERO_OFFSET;
63 }
64 
U16toS16(uint16_t from)65 inline int16_t U16toS16(uint16_t from){
66   return int16_t(from - U16_ZERO_OFFSET);
67 }
68 
S16toU16(int16_t from)69 inline uint16_t S16toU16(int16_t from){
70   return uint16_t(from) + U16_ZERO_OFFSET;
71 }
72 
U8toS8(uint8_t from)73 inline int8_t U8toS8(uint8_t from){
74   return int8_t(from - U8_ZERO_OFFSET);
75 }
76 
S8toU8(int8_t from)77 inline uint8_t S8toU8(int8_t from){
78   return uint8_t(from) + U8_ZERO_OFFSET;
79 }
80 
81 // size conversion: signed <> signed
82 
S32toS16(int32_t from)83 inline int16_t S32toS16(int32_t from){
84   return int16_t(from >> 16);
85 }
S16toS32(int16_t from)86 inline int32_t S16toS32(int16_t from){
87   return int32_t(from << 16);
88 }
89 
S16toS8(int16_t from)90 inline int8_t S16toS8(int16_t from){
91   return int8_t(from >> 8);
92 }
S8toS16(int8_t from)93 inline int16_t S8toS16(int8_t from){
94   return int16_t(from << 8);
95 }
96 
97 // compound conversions
98 
99 // float <> unsigned (type and size)
100 
F32toU32(float from)101 inline uint32_t F32toU32(float from){
102   return S32toU32(F32toS32(from));
103 }
U32toF32(uint32_t from)104 inline float U32toF32(uint32_t from){
105   return S32toF32(U32toS32(from));
106 }
107 
F32toU16(float from)108 inline uint16_t F32toU16(float from){
109   return S16toU16(F32toS16(from));
110 }
U16toF32(uint16_t from)111 inline float U16toF32(uint16_t from){
112   return S16toF32(U16toS16(from));
113 }
114 
F32toU8(float from)115 inline uint8_t F32toU8(float from){
116   return S8toU8(F32toS8(from));
117 }
U8toF32(uint8_t from)118 inline float U8toF32(uint8_t from){
119   return S8toF32(U8toS8(from));
120 }
121 
122 // signed <> unsigned (type and size)
123 
S32toU16(int32_t from)124 inline uint16_t S32toU16(int32_t from){
125   return S16toU16(S32toS16(from));
126 }
U16toS32(uint16_t from)127 inline int32_t U16toS32(uint16_t from){
128   return S16toS32(U16toS16(from));
129 }
130 
S32toU8(int32_t from)131 inline uint8_t S32toU8(int32_t from){
132   return S8toU8(S16toS8(S32toS16(from)));
133 }
U8toS32(uint8_t from)134 inline int32_t U8toS32(uint8_t from){
135   return S16toS32(S8toS16(U8toS8(from)));
136 }
137 
S16toU8(int16_t from)138 inline uint8_t S16toU8(int16_t from){
139   return S8toU8(S16toS8(from));
140 }
U8toS16(uint8_t from)141 inline int16_t U8toS16(uint8_t from){
142   return S8toS16(U8toS8(from));
143 }
144 
S8toU16(int8_t from)145 inline uint16_t S8toU16(int8_t from){
146   return S16toU16(S8toS16(from));
147 }
U16toS8(uint16_t from)148 inline int8_t U16toS8(uint16_t from){
149   return S16toS8(U16toS16(from));
150 }
151 
152 
153 }
154