Imported Upstream version 3.2.2
[debian/gnuradio] / usrp2 / host / lib / copiers.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2008 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 along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <usrp2/copiers.h>
26 #include <gruel/inet.h>
27 #include <gr_math.h>
28 #include <math.h>
29 #include <stdexcept>
30 #include <assert.h>
31 #include <string.h>
32
33 // FIXME need gruel::not_implemented
34
35 namespace usrp2 {
36
37   /*
38    * N.B., in all of these, uint32_t *items is NOT 32-bit aligned!
39    * FIXME Needs fix for non-x86 machines.
40    */
41
42   /*
43    * ----------------------------------------------------------------
44    * Copy and convert from USRP2 wire format to host format
45    * ----------------------------------------------------------------
46    */
47   void 
48   copy_u2_16sc_to_host_16sc(size_t nitems,
49                             const uint32_t *items,
50                             std::complex<int16_t> *host_items)
51   {
52 #ifdef WORDS_BIGENDIAN
53
54     assert(sizeof(items[0]) == sizeof(host_items[0]));
55     memcpy(host_items, items, nitems * sizeof(items[0]));
56
57 #else
58
59     // FIXME SIMD welcome here
60
61     for (size_t i = 0; i < nitems; i++){
62       uint32_t t = ntohx(items[i]);
63       //printf("%9d\n", items[i]);
64       host_items[i] = std::complex<int16_t>((t >> 16), t & 0xffff);
65     }
66
67 #endif
68   }
69
70
71   /*
72    * endian swap if required and map [-32768, 32767] -> [1.0, +1.0)
73    */
74   void 
75   copy_u2_16sc_to_host_32fc(size_t nitems,
76                             const uint32_t *items,
77                             std::complex<float> *host_items)
78   {
79     for (size_t i = 0; i < nitems; i++){
80       uint32_t t = ntohx(items[i]);
81       int16_t re = (t >> 16) & 0xffff;
82       int16_t im = (t & 0xffff);
83       host_items[i] = std::complex<float>(re * 1.0/32768, im * 1.0/32768);
84     }
85   }
86
87   /*
88    * ----------------------------------------------------------------
89    * Copy and convert from host format to USRP2 wire format
90    * ----------------------------------------------------------------
91    */
92   void 
93   copy_host_16sc_to_u2_16sc(size_t nitems,
94                             const std::complex<int16_t> *host_items,
95                             uint32_t *items)
96   {
97 #ifdef WORDS_BIGENDIAN
98
99     assert(sizeof(items[0]) == sizeof(host_items[0]));
100     memcpy(items, host_items, nitems * sizeof(items[0]));
101
102 #else
103
104     // FIXME SIMD welcome here
105
106     for (size_t i = 0; i < nitems; i++){
107       items[i] = htonl((host_items[i].real() << 16) | (host_items[i].imag() & 0xffff));
108     }
109
110 #endif
111   }
112
113
114   static inline int16_t
115   clip_and_scale(float x)
116   {
117     return static_cast<int16_t>(rintf(gr_branchless_clip(x, 1.0) * 32767.0));
118   }
119
120   void 
121   copy_host_32fc_to_u2_16sc(size_t nitems,
122                             const std::complex<float> *host_items,
123                             uint32_t *items)
124   {
125     for (size_t i = 0; i < nitems; i++){
126       int16_t re = clip_and_scale(host_items[i].real());
127       int16_t im = clip_and_scale(host_items[i].imag());
128       
129       items[i] = htonl((re << 16) | (im & 0xffff));
130     }
131   }
132
133 }