├── .gitignore
├── .gitmodules
├── CMakeLists.txt
├── LICENSE
├── README.md
├── beamformclient
├── heatmap2d.cpp
└── heatmap2d2.cpp
├── deps
├── electronics
├── README
├── adapter.zip
├── coupler.zip
├── coupler2.jpg
├── example_clock.png
└── example_noisegen_kicad502.zip
├── examplecfg
├── URA21.cfg
├── ac.cfg
└── four.cfg
├── include
├── ccoherent.h
├── cconfigfile.h
├── ccontrol.h
├── cdsp.h
├── common.h
├── console.h
├── cpacketize.h
├── cpacketizer.h
├── crefnoise.h
└── csdrdevice.h
├── install_on_rpi
├── matlabclient
├── CZMQSDR.m
├── compiling.txt
├── functions
│ ├── D2Dtoepos.m
│ ├── DA2D.m
│ ├── darray.m
│ ├── pmusic.m
│ └── pmusicplot.m
├── matsave.cc
├── measurement_script.m
├── noiseswitch.m
├── notes.m
├── phasecorrectionplot.m
├── seqnum_and_correlation.m
├── testchannels.m
├── testclient.m
├── zmqsdr.c
├── zmqsdr.cc
└── zmqsdr.mexa64
├── refnoisefirmware
├── CMakeLists.txt
├── Makefile
├── bootloader.c
├── enter_dfu.sh
├── fw.c
├── resetusb.sh
├── stm32-blueboot.ld
├── stm32-bluebootld.ld
├── stm32-bluepill.ld
├── stm32-bluepilldfu.ld
└── usbdfu.c
└── src
├── CMakeLists.txt
├── ccoherent.cc
├── ccontrol.cc
├── cdsp.cc
├── common.cc
├── console.cc
├── cpacketizer.cc
├── crtlsdr.cc
├── csdrdevice.cc
└── main.cc
/.gitignore:
--------------------------------------------------------------------------------
1 | #ignore build
2 | build/
3 | *.mat
4 | *.out
5 | *.zip
6 | *.m~
7 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "refnoisefirmware/libopencm3"]
2 | path = refnoisefirmware/libopencm3
3 | url = https://github.com/libopencm3/libopencm3
4 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 2.6)
2 |
3 |
4 | option(RASPBERRYPI "RPI" OFF)
5 | if (RASPBERRYPI)
6 | add_definitions(-DRASPBERRYPI)
7 | endif(RASPBERRYPI)
8 |
9 | #set(CMAKE_CXX_STANDARD 17)
10 | set(CMAKE_CXX_FLAGS "-O3") #-Wl,-Bdynamic
11 |
12 | include_directories(${PROJECT_SOURCE_DIR}/include)
13 | add_subdirectory(src)
14 |
15 |
16 |
17 | #SET_TARGET_PROPERTIES(coherentrtlsdr PROPERTIES LINK_FLAGS -lrtlsdr)
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # things have moved forward, KrakenSDR is now fully controllable by the new (unpublished) ThorSDR code.
2 | Licencing may change to the MIT license, but this is still under consideration. SoapySDR support is
3 | also under consideration,
4 |
5 |
6 | # project development starting again, already in june,
7 | Changes are being made and the ThorSDR code seems quite stable at the moment.
8 | Also, we are considering to add soapysdr support in the future. Note that
9 | this driver will also support other reference noise switching calibration systems. e.g. KrakenSDR
10 |
11 |
12 | ***10.8.2022 PROJECT DEVELOPEMENT HALTED, WE'LL NEED TO FIND SOMEONE TO CONTINUE THE WORK WITH OUR RECEIVER PROTO.
13 |
14 | Perhaps this should be someday converted into a GNU Radio OOT module as a signal source, but I do not have the time
15 | until I finish my PhD.
16 | ***
17 |
18 | # coherent-rtlsdr, reworked synchronization algorithm
19 |
20 | Mostly the same requirements as in my previous coherentsdr proof-of-concept. One added dependency, GNU Readline, for the shell. Some unworking features: adding and deleting receivers during runtime, application does not always exit cleanly.
21 |
22 | Matlab client included. A system object interfacing to a .c MEX implementation (matlab c++ interfacing seems to be too slow). This is not built automatically by cmake, instead it has to be compiled manually (instructions in the folder).
23 |
24 | Required for compiling:
25 |
26 | :zmq: - the zero message queue:
27 | sudo apt-get install libzmq3-dev
28 |
29 | :fftw3f: - fastest fourier transform in the west:
30 | sudo apt-get install fftw3-dev
31 |
32 | :volk: - vector optimized library of kernels:
33 | sudo apt-get install volk
34 |
35 | :librtlsdr: -Tejeez/Keenerds experimental librtlsdr fork:
36 | git://github.com/tejeez/rtl-sdr
37 |
38 | +GNU Readline
39 |
40 | Requires common 28.8 MHz clock & reference signal (noise) for synchronization. Some examples in the electronics folder, but this is still missing the coupler module PCB files.
41 |
42 | Currently may return a receive matrix where data on some channels are from a previous sample buffer. This seems to happen under heavy CPU load, at least on limited platforms (testing on RockPI 4 with 21 signal channels). This can be noticed by observing discontinuous channel sequence number (readcnt). Occasionally, all channels skip a buffer in unison, i.e. 8192 sample gap in reception. Perhaps I may need to add some buffering to the packetizer singleton. Under construction.
43 |
44 | UPDATE 2.2.2021: We have concentrated on experiments with the receiver and presented a paper at EUSIPCO2020. "Phase-coherent multichannel SDR - Sparse arraybeamforming" can be found at: https://aaltodoc.aalto.fi/handle/123456789/102361
45 |
46 | Please cite this as: Laakso , M , Rajamäki , R , Wichman , R & Koivunen , V 2020 , Phase-coherent multichannel SDR - Sparse array beamforming . in 28th European Signal Processing Conference, EUSIPCO 2020 - Proceedings . , 9287664 , European Signal Processing Conference , EURASIP , pp. 1856-1860 , European Signal Processing Conference , Amsterdam , Netherlands , 24/08/2020 . https://doi.org/10.23919/Eusipco47968.2020.9287664
47 |
48 | The next paper, in which we utilize deep neural networks on data captured with coherent-rtlsdr to do near-field localization (with surprisingly accurate results), was presented at VTC2021 Helsinki. The article is titled "Near-field localization using machine learning: An empirical study" and it can be accessed at: https://aaltodoc.aalto.fi/handle/123456789/102361
49 |
50 | Please cite as: Laakso , M & Wichman , R 2021 , Near-field localization using machine learning: An empirical study . in 2021 IEEE 93rd Vehicular Technology Conference, VTC 2021-Spring - Proceedings . , 9449002 , IEEE Vehicular Technology Conference , vol. 2021-April
51 |
52 | Added the reference noise controller firmware, shamelessly edited from libopencm3 examples. This uses the 2$ STM32F103C8T6 (a.k.a bluepill) board to control 2 GPIOS for switching operating voltage for the noise amplifiers & case fan (yes, last summer I had problems with the amplifiers overheating while taking measurements during a sunny day). DFU upgradeable with dfu-util once flashed (hack, but works).
53 |
54 |
--------------------------------------------------------------------------------
/beamformclient/heatmap2d.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | coherent-rtlsdr
3 |
4 | This program is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | coherent-rtlsdr is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with coherent-rtlsdr. If not, see .
16 | */
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include "gnuplot-iostream.h"
23 | #include
24 | #include
25 |
26 | #include "Eigen/Dense"
27 | #include "Eigen/KroneckerProduct"
28 | #include
29 | #include
30 | //#include "mat.h"
31 |
32 | using namespace std;
33 | using namespace Eigen;
34 |
35 |
36 | #define NSENSOR 18
37 |
38 | typedef Matrix,Dynamic,Dynamic> MatrixType;
39 | typedef Map MapType;
40 | typedef Map MapTypeConst;
41 | typedef Matrix,NSENSOR,1> ColVecType;
42 |
43 | typedef Matrix,1,NSENSOR> RowVecType;
44 |
45 | typedef Matrix,Dynamic,1> ColVecTypeD; //try the dynamic.
46 |
47 | typedef std::pair Point;
48 |
49 | typedef std::vector Point2d;
50 |
51 | const complex j(0, 1);
52 | const float pi = std::acos(-1);
53 |
54 | //g++ mattoeigen.cpp -lmat -lmx -lutil -lboost_iostreams -lboost_system -lboost_filesystem -I ~/source/eigen-3.3.7/Eigen/ -I /usr/local/MATLAB/R2019b/extern/include/ -L /usr/local/MATLAB/R2019b/bin/glnxa64/ -I ~/source/gnuplot-iostream/ -Wl,-rpath=/usr/local/MATLAB/R2019b/bin/glnxa64/
55 |
56 | // with the unsupported Kronecker product patched in do:
57 |
58 | //g++ mattoeigen.cpp -lzmq -lutil -lboost_iostreams -lboost_system -lboost_filesystem -I ~/source/eigen-3.3.7/ -I ~/source/tmp/eigen/unsupported/ -I ~/source/gnuplot-iostream/
59 |
60 | //Find noise subspace from Covariance matrix Rxx, assuming K signals. Use SVD.
61 | Matrix,Dynamic,Dynamic> noisesubspace(Matrix,Dynamic,Dynamic> Rxx, int K){
62 | int M = Rxx.cols();
63 | BDCSVD,Dynamic,Dynamic>> B=Rxx.bdcSvd(ComputeFullU|ComputeFullV);
64 | Matrix,Dynamic,Dynamic> U = B.matrixU();
65 | Matrix,Dynamic,Dynamic> Un = U.rightCols(M-K);
66 | Matrix,1,Dynamic> S = B.singularValues();
67 | //cout << "singularvalues: " << S << endl;
68 | return Un;
69 | }
70 |
71 | //Noise subspace with Eigendecomp. This cannot be used as such, because the eigenvectors&vals are unordered.
72 | MatrixType noisesubspaceeig(MatrixType Rxx, int K){
73 | SelfAdjointEigenSolver es;
74 | es.compute(Rxx);
75 | //cout << "The eigenvalues of Rxx are: " << es.eigenvalues().transpose() << endl;
76 | //cout << "The matrix of eigenvectors, V, is:" << endl << es.eigenvectors() << endl << endl;
77 | return es.eigenvectors();
78 | }
79 |
80 | //steering vector, for direction phi(rad)
81 | ColVecType s_vec(float phi){
82 | ColVecType A;
83 |
84 | float d = (1.225*1.24)/3.0f; //element distance, wavelengths
85 | //d = 0.5f; //exp(2j*pi*d*cos(pi))
86 |
87 | for (int i=0;i,Dynamic,Dynamic> Un, Matrix,Dynamic,1> a)
123 | {
124 | //complex denom = ((Un.adjoint()*a).norm());
125 | complex denom = (Un.adjoint()*a).squaredNorm();
126 | complex res = a.squaredNorm()/denom;
127 | return (res*conj(res)).real();
128 | //complex denom = a.adjoint()*Un*Un.adjoint()*a;
129 | //return (1.0f/denom).real();
130 | }
131 |
132 | /*
133 | Matrix,Dynamic,Dynamic> DA(Matrix,Dynamic,Dynamic>){
134 | Matrix<,Dynamic,Dynamic> res;
135 | res.resize();
136 | }*/
137 |
138 | Matrix pmusic2dvec(Matrix,Dynamic,Dynamic> Un,float d, int Mx, int My, int Cx, int Cy){
139 | Matrix res(Cx,Cy);
140 | for(int cx=0;cx pmusicvec(Matrix,Dynamic,Dynamic> Un, int N) //N+1 points between 0 to PI
151 | {
152 | Matrix res;
153 | res.resize(N,1);
154 |
155 | for(int n=0;n(msg.data());
177 | uint32_t gseq = *((uint32_t *) s8bit);
178 | uint32_t cols = *(((uint32_t *) s8bit)+1);
179 | uint32_t rows = *(((uint32_t *) s8bit)+2);
180 | //cols = NSENSOR; //only the first antennas.
181 |
182 | cout << "Allocating a " << to_string(rows) << " X " << to_string(cols) << " matrix" << endl;
183 |
184 | MatrixType Xall(rows,cols); //MapType Xall(matptr,rows,cols);
185 | Xall.resize(rows,cols);
186 |
187 | Gnuplot gp;
188 |
189 | //gp << "set zrange [-1:1]\n";
190 | gp << "set hidden3d nooffset\n";
191 | gp << "set style fill transparent solid 0.65\n";
192 | //gp << "set view map\n";
193 |
194 | vector data;
195 |
196 | vector data2d;
197 |
198 | int nrep = 10000;
199 |
200 | for (int nn=0; nn(msg.data());
203 | //convert samples to complex float:
204 | //cout << "converting data\n" << endl;
205 | if (nn%1==0){
206 | float s = 1/127.0f;
207 | for(uint32_t c=0;c(float(s8bit[c*(rows<<1) + ri++]),float(s8bit[c*(rows<<1) + ri]));
210 | }
211 |
212 |
213 | //cout << "subtracting mean\n" << endl;
214 | MatrixType X = Xall.rightCols(cols-1); //.leftCols(NSENSOR);
215 | X.rowwise()-=X.colwise().mean(); //subtract col mean
216 |
217 | //cout << "Computing noise subspace\n" << endl;
218 | MatrixType Rxx = (1/float(rows))*(X.adjoint()*X);
219 | MatrixType Un = noisesubspace(Rxx,1);
220 |
221 | //cout << "Computing music\n" << endl;
222 |
223 | //Matrix pm = pmusicvec(Un,100);
224 |
225 | float d = (1.225*1.24)/3.0f;
226 | Matrix pm = pmusic2dvec(Un,d,6,3,100, 100);
227 |
228 | //pm.col(50) = pmusicvec(Un,100);
229 |
230 | auto g = pm.maxCoeff();
231 | //cout << g << endl;
232 | pm *= 1/g;
233 |
234 | std::vector > > pts(100);
235 | for (int nx=0;nx<100;nx++){
236 | pts[nx].resize(100);
237 | for (int ny=0;ny<100;ny++){
238 | pts[nx][ny].resize(3);
239 | pts[nx][ny][0] = -90 + float(nx)*1.8f;
240 | pts[nx][ny][1] = -90 + float(ny)*1.8f;
241 | pts[nx][ny][2] = 20.0f*log10(pm(nx,ny)); //2.0f;
242 |
243 | }
244 | }
245 | gp.clear();
246 | gp << "set yrange [-90:90]\n";
247 | gp << "set xrange [-90:90]\n";
248 | gp << "set cbrange [-18:0]\n";
249 | gp << "set zrange [-18:1]\n";
250 | //gp << "set view map\n";
251 | gp << "splot '-' with pm3d title 'Pm'\n";
252 | gp.send2d(pts);
253 | gp.flush();
254 | //gp << gp.binFile2d(pts, "record") << "with lines title 'vec vec vec'";
255 |
256 | /*
257 | for(int n=0;n<101;n++){
258 | //data.push_back(Point(180.0f/pi*float(n)/10.0f,pm(n)));
259 | data.push_back(Point(float(n),10.0f*log10(pm(n))));
260 | }
261 |
262 | //cout << "Dim X:" << X.rows() << "," << X.cols() << endl;
263 | gp.clear();
264 | gp << "unset border\n";
265 | //gp << "set yrange[0:10]\n";
266 | gp << "set yrange[-20:1]\n";
267 | gp << "plot '-' with lines title 'Pm'\n";
268 | gp.send1d(data);
269 | gp.flush();
270 |
271 | data.clear();*/
272 | }
273 | /*
274 | //WORKING MUSIC
275 | for (int phi=0;phi<1800;phi++){
276 | ColVecType A = s_vec(pi*float(phi)/1800.0f);
277 | //cout << A.transpose() << endl;
278 | data.push_back(Point(float(phi),10*log10(pmusic(Un,A))));
279 | }
280 | */
281 | }
282 |
283 | }
284 |
285 | //Map X(NULL);
286 | //new (&A) Map(get_matrix_pointer(i));
287 | //new (&X) Map,Dynamic,Dynamic>>(outptr,dims[0],dims[1]);
288 | //&XMap >(array)
289 |
--------------------------------------------------------------------------------
/beamformclient/heatmap2d2.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | coherent-rtlsdr
3 |
4 | This program is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | coherent-rtlsdr is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with coherent-rtlsdr. If not, see .
16 | */
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include "gnuplot-iostream.h"
23 | #include
24 | #include
25 |
26 | #include "Eigen/Dense"
27 | #include "Eigen/KroneckerProduct"
28 | #include
29 | #include
30 | #include
31 | #include
32 |
33 | #include "../include/cdsp.h"
34 | #include
35 |
36 | #include "mat.h"
37 |
38 | using namespace std;
39 | using namespace Eigen;
40 |
41 | #define MX 7
42 | #define MY 3
43 | #define NSENSOR MX*MY
44 |
45 |
46 | typedef Matrix,Dynamic,Dynamic> MatrixType;
47 | typedef Map MapType;
48 | typedef Map MapTypeConst;
49 | typedef Matrix,NSENSOR,1> ColVecType;
50 |
51 | typedef Matrix,1,NSENSOR> RowVecType;
52 |
53 | typedef Matrix,Dynamic,1> ColVecTypeD; //try the dynamic.
54 |
55 | typedef std::pair Point;
56 |
57 | typedef std::vector Point2d;
58 |
59 | const complex j(0, 1);
60 | const float pi = std::acos(-1);
61 |
62 | //g++ mattoeigen.cpp -lmat -lmx -lutil -lboost_iostreams -lboost_system -lboost_filesystem -I ~/source/eigen-3.3.7/Eigen/ -I /usr/local/MATLAB/R2019b/extern/include/ -L /usr/local/MATLAB/R2019b/bin/glnxa64/ -I ~/source/gnuplot-iostream/ -Wl,-rpath=/usr/local/MATLAB/R2019b/bin/glnxa64/
63 |
64 | // with the unsupported Kronecker product patched in do:
65 |
66 | //g++ heatmap2d2.cpp -lmx -lmat -lvolk -lpthread -lzmq -lutil -lboost_iostreams -lboost_system -lboost_filesystem -I ~/source/eigen-3.3.7/ -I ~/source/tmp/eigen/unsupported/ -I ~/source/gnuplot-iostream/ -I /usr/local/MATLAB/R2019b/extern/include/ -L /usr/local/MATLAB/R2019b/bin/glnxa64/ -Wl,-rpath=/usr/local/MATLAB/R2019b/bin/glnxa64/
67 |
68 | //Find noise subspace from Covariance matrix Rxx, assuming K signals. Use SVD.
69 | Matrix,Dynamic,Dynamic> noisesubspace(Matrix,Dynamic,Dynamic> Rxx, int K){
70 | int M = Rxx.cols();
71 | BDCSVD,Dynamic,Dynamic>> B=Rxx.bdcSvd(ComputeFullU|ComputeFullV);
72 | Matrix,Dynamic,Dynamic> U = B.matrixU();
73 | Matrix,Dynamic,Dynamic> Un = U.rightCols(M-K);
74 | Matrix,1,Dynamic> S = B.singularValues();
75 | //cout << "singularvalues: " << S << endl;
76 | return Un;
77 | }
78 |
79 | //Noise subspace with Eigendecomp. This cannot be used as such, because the eigenvectors&vals are unordered.
80 | MatrixType noisesubspaceeig(MatrixType Rxx, int K){
81 | SelfAdjointEigenSolver es;
82 | es.compute(Rxx);
83 | //cout << "The eigenvalues of Rxx are: " << es.eigenvalues().transpose() << endl;
84 | //cout << "The matrix of eigenvectors, V, is:" << endl << es.eigenvectors() << endl << endl;
85 | return es.eigenvectors();
86 | }
87 |
88 | //steering vector, for direction phi(rad)
89 | ColVecType s_vec(float phi){
90 | ColVecType A;
91 |
92 | float d = (1.225*1.24)/3.0f; //element distance, wavelengths
93 | //d = 0.5f; //exp(2j*pi*d*cos(pi))
94 |
95 | for (int i=0;i,Dynamic,Dynamic> Un, Matrix,Dynamic,1> a)
117 | {
118 | //complex denom = ((Un.adjoint()*a).norm());
119 | complex denom = (Un.adjoint()*a).squaredNorm();
120 | complex res = a.squaredNorm()/denom;
121 | return (res*conj(res)).real();
122 | //complex denom = a.adjoint()*Un*Un.adjoint()*a;
123 | //return (1.0f/denom).real();
124 | }
125 |
126 | /*
127 | Matrix,Dynamic,Dynamic> DA(Matrix,Dynamic,Dynamic>){
128 | Matrix<,Dynamic,Dynamic> res;
129 | res.resize();
130 | }*/
131 |
132 | Matrix pmusic2dvec(Matrix,Dynamic,Dynamic> Un,float d, int Mx, int My, int Cx, int Cy){
133 | Matrix res(Cx,Cy);
134 | for(int cx=0;cx pmusicvec(Matrix,Dynamic,Dynamic> Un, int N) //N+1 points between 0 to PI
145 | {
146 | Matrix res;
147 | res.resize(N,1);
148 |
149 | for(int n=0;n *dbuf0;
157 | complex *dbuf1;
158 | bool exit_all;
159 | uint32_t gseq;
160 | std::mutex g_i_mutex;
161 |
162 | struct cdims{
163 | uint32_t cols;
164 | uint32_t rows;
165 | cdims(uint32_t r_,uint32_t c_):rows(r_), cols(c_){};
166 | };
167 |
168 | void plotthread(cdims *dims){
169 |
170 | uint32_t cols = dims->cols;
171 | uint32_t rows = dims->rows;
172 |
173 | Gnuplot gp;
174 | gp << "set hidden3d nooffset\n";
175 | gp << "set style fill transparent solid 0.65\n";
176 |
177 | //preallocate 2d vector container for gnuplotc++ interface:
178 | std::vector > > pts(100);
179 | for (int nx=0;nx<100;nx++){
180 | pts[nx].resize(100);
181 | for (int ny=0;ny<100;ny++){
182 | pts[nx][ny].resize(3);
183 | }
184 | }
185 | MapType Xall(dbuf0,rows,cols);
186 | MapType Xall2(dbuf1,rows,cols);
187 |
188 | while (!exit_all){
189 | MatrixType X = Xall.rightCols(cols-1);
190 | X.rowwise()-=X.colwise().mean();
191 |
192 | {
193 | const std::lock_guard lock(g_i_mutex);
194 | std::swap(dbuf0,dbuf1);
195 | std::swap(Xall,Xall2);
196 | }
197 |
198 | // covariance matrix estimate & noise subspace via SVD
199 | MatrixType Rxx = (1/float(rows))*(X.adjoint()*X);
200 | MatrixType Un = noisesubspace(Rxx,1);
201 |
202 | float d = (1.225*1.24)/3.0f;
203 | Matrix pm = pmusic2dvec(Un,d,MX,MY,100, 100);
204 |
205 | //normalize
206 | auto g = pm.maxCoeff();
207 | pm *= 1/g;
208 | for (int nx=0;nx<100;nx++){
209 | for (int ny=0;ny<100;ny++){
210 | pts[nx][ny][0] = -90 + float(nx)*1.8f;
211 | pts[nx][ny][1] = -90 + float(ny)*1.8f;
212 | pts[nx][ny][2] = 20.0f*log10(pm(nx,ny)); //2.0f;
213 |
214 | }
215 | }
216 | gp.clear();
217 | gp << "set yrange [-90:90]\n";
218 | gp << "set xrange [-90:90]\n";
219 | gp << "set cbrange [-20:0]\n";
220 | gp << "set zrange [-20:1]\n";
221 | //gp << "set view map\n";
222 | gp << "splot '-' with pm3d title 'Pm " << to_string(gseq)<<"'\n";
223 | gp.send2d(pts);
224 | gp.flush();
225 | }
226 |
227 | }
228 |
229 | void matsave(int8_t *s8bit, uint32_t r, uint32_t c, string fname){
230 | // get the time as string
231 | time_t t = time(NULL);
232 | struct tm *tm = localtime(&t);
233 | char s[64];
234 | strftime(s, sizeof(s), "%c", tm);
235 |
236 | cout << "Creating file " << fname << endl;
237 | MATFile *pmat = matOpen(fname.data(),"w");
238 |
239 | mxArray *pa1 = mxCreateNumericMatrix(r,c,mxSINGLE_CLASS,mxCOMPLEX);
240 | mxArray *pa2 = mxCreateString(s);
241 |
242 | //get the pointer to our matlab matrix and convert from i8
243 | float* outptr = (float *) mxGetComplexSingles(pa1);
244 | volk_8i_s32f_convert_32f((float *) outptr, s8bit,127.0f,2*r*c);
245 |
246 | matPutVariable(pmat, "x", pa1);
247 | matPutVariable(pmat, "time", pa2);
248 | mxDestroyArray(pa1);
249 | mxDestroyArray(pa2);
250 |
251 | matClose(pmat);
252 | }
253 |
254 |
255 | void usage(void)
256 | {
257 | fprintf(stderr,
258 | "\n URA beamform & Matlab .mat save:\n"
259 | "\t[-a receiver address, e.g. tcp://localhost:5555\n"
260 | "\t[-c frame count, 0 = inf]\n"
261 | "\t[-f filename to save, if given sets framecount = 1]\n");
262 | exit(1);
263 | }
264 |
265 | int main(int argc, char **argv) {
266 |
267 | //set defaults & parse command line
268 | string addr = "tcp://localhost:5555";
269 | string fname;
270 | int totalframes = 1;
271 |
272 | int opt;
273 | while ((opt = getopt(argc, argv, "a:c:f:h")) != -1) {
274 | switch (opt) {
275 | case 'a':
276 | addr = string(optarg);
277 | break;
278 | case 'c':
279 | totalframes = (int) atoi(optarg);
280 | break;
281 | case 'f':
282 | fname = string(optarg);
283 | totalframes = 1;
284 | break;
285 | case 'h':
286 | default:
287 | usage();
288 | break;
289 | }
290 | }
291 |
292 |
293 | //set up zmq and retrieve one frame to determine dimensions
294 | zmq::context_t ctx(1);
295 | zmq::socket_t sock(ctx, ZMQ_SUB);
296 | sock.setsockopt(ZMQ_SUBSCRIBE, "", 0);
297 | sock.connect(addr.data());
298 |
299 | zmq::message_t msg;
300 | sock.recv (&msg);
301 |
302 | int8_t *s8bit = static_cast(msg.data());
303 | gseq = *((uint32_t *) s8bit);
304 | uint32_t cols = *(((uint32_t *) s8bit)+1);
305 | uint32_t rows = *(((uint32_t *) s8bit)+2);
306 | //cols = NSENSOR; //only the first antennas.
307 |
308 | cout << "Allocating a " << to_string(rows) << " X " << to_string(cols) << " matrix" << endl;
309 |
310 | //raw data buffer for incoming sample conversion:
311 | dbuf0 = new complex [rows*cols];
312 | dbuf1 = new complex [rows*cols];
313 | volk_8i_s32f_convert_32f((float *) dbuf0, s8bit,127.0f,rows*cols*2);
314 |
315 | exit_all = false;
316 | cdims dim(rows,cols);
317 | std::thread plotthrd(plotthread,&dim);
318 |
319 |
320 | //main loop simply receives data and converts to 32-bit float
321 | for (int n=0;n(msg.data());
324 | gseq = *((uint32_t *) s8bit);
325 | s8bit +=16+sizeof(uint32_t)*cols;
326 | //convert samples to complex float, use a scoped lock in case plotthread is switching buffers.
327 | {
328 | //cdsp::convtofloat(dbuf, s8bit, rows*cols*2); //maybe someday include this in cmake such that we can use this...
329 | const std::lock_guard lock(g_i_mutex);
330 | volk_8i_s32f_convert_32f((float *) dbuf0, s8bit,127.0f,rows*cols*2);
331 | }
332 | }
333 |
334 | // save the file as matlab mat. we'll have to reconvert from int8 since
335 | // plotthrd might have swapped buffers
336 | if (!fname.empty()){
337 | exit_all = true;
338 | matsave(s8bit,rows,cols,fname);
339 | }
340 |
341 |
342 | plotthrd.join();
343 |
344 | delete[] dbuf0;
345 | delete[] dbuf1;
346 | }
--------------------------------------------------------------------------------
/deps:
--------------------------------------------------------------------------------
1 | dep ZMQ:
2 | libzmq3-dev
3 |
--------------------------------------------------------------------------------
/electronics/README:
--------------------------------------------------------------------------------
1 | Examples on some of the electronics needed for this project will be added here.
2 | All of the schematics are not available in electronic form.
3 |
4 | At least the reference noise switching circuit & firmware is still missing.
5 | In our setup, this is implemented with the 2$ STM32F103C8T6 (a.k.a "Blue Pill") µC.
6 | This was (audaciously) edited from a CDCACM-device example code in libopencm3 examples
7 | to respond to a certain character ('X', could be anything and even include more functionality
8 | - too busy to do anything more) to control a GPIO pin. That is, the USB-enabled µC maps to
9 | a modem device, e.g. /dev/ttyACM0 (add your user to the dialout group for access), which you
10 | then send characters to enable/disable a high-side power switch, which drives the noise amps.
11 | One could also include a udev rule to command your host computer to not treat it as a modem, but
12 | it works fine without it after the initial AT-command garbage stops. Our setup also includes an
13 | indicator led (+a driver circuit) to observe the reference noise state.
14 |
15 |
16 | Brief descriptions:
17 |
18 | example_noisegen:
19 | Kicad project for 3+1 output reference noise generator. Drives 3 couplers,
20 | one directionally coupled for reference dongle. Separate power connectors
21 | for the MMIC amplifier chain and Zener diode. Optional enable signal for
22 | diode current (bypassed in prototype build). Our design switches the noise
23 | by disabling the operating voltage on the MMIC amps.
24 |
25 | The output connectors should be changed to MCX, currently they are MMCX.
26 | Also, an updated PCB version for 8 outputs with 'almost proper' Wilkinson power dividers
27 | is half done, but still somewhat unfinished for being uploaded here (as if anything
28 | here is finished/mature). Currently, I'm burdened with writing articles.
29 |
30 | clock_generator:
31 | The clock generator (no complete schematic for this currently), is a buffered
32 | Pierce-type oscillator. Uses 74HC04 and 74HC14 (Schmidt trigger) inverters. See
33 | example_clock. The Schmidt trigger (for reducing noise) is not strictly necessary
34 | and could be replaced by 74HC04, or alternatively a single Schmidt trigger followed
35 | by 74HC04 buffers.
36 |
37 |
38 | coupler module for 7 receivers:
39 | The reference noise is distributed to the receivers via directional coupling.
40 | Check the .jpg for the idea: here the top PCB is a D-Link USB hub.
41 |
42 | Published with permission from Tejeez: coupler.zip & adapter.zip contain the
43 | plotted gerber files for a 7-element coupler PCB assembly. You will also need
44 | a suitable 7-port HUB, some SMD caps & resistors, inductor and MCX & angled
45 | BNC connectors. Also, pin header connectors between adapter and coupler boards.
46 | A crude BOM and component values:
47 |
48 | P1,P3,P5,P7,P9,P11,P13 : MCX STRAIGHT PLUG (Farnell 1831741)
49 | P2,P4,P6,P8,P10,P12,P14: ANGLED BNC (Tyco electronics)
50 |
51 | R1-R8: 51 Ohm, 1206? (need to verify footprint size)
52 | C1-C7: 1nF 1206
53 | L1: 220 nH (Farnell 2470315: this inductor is too small,
54 | painful to solder, get one with larger footprint)
55 |
56 | C8-C9: 22pF, 1nF
57 |
58 | C11-C18: (caps to chassis GND) are not strictly necessary.
59 |
60 | P22: 15 X 2 pin header (2.54mm pitch, straight) connects to adapter
61 |
62 | adapter:
63 | C10: 1uF, 0805 (in adapter board, power source filter)
64 | 15 X 2 pin connector (straight, 2.54mm)
65 | micro-USB B connector
66 |
67 | To improve robustness, RF-switch ICs could be used instead of directional coupling
68 | to perform this function. A strong signal from the antennas on the frequency of
69 | interest might interfere with the synchronization in the current coupling approach.
70 |
71 |
--------------------------------------------------------------------------------
/electronics/adapter.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mlaaks/coherent-rtlsdr/1c861ad2828f0cbcac7f56fc094f1272bc7ee787/electronics/adapter.zip
--------------------------------------------------------------------------------
/electronics/coupler.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mlaaks/coherent-rtlsdr/1c861ad2828f0cbcac7f56fc094f1272bc7ee787/electronics/coupler.zip
--------------------------------------------------------------------------------
/electronics/coupler2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mlaaks/coherent-rtlsdr/1c861ad2828f0cbcac7f56fc094f1272bc7ee787/electronics/coupler2.jpg
--------------------------------------------------------------------------------
/electronics/example_clock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mlaaks/coherent-rtlsdr/1c861ad2828f0cbcac7f56fc094f1272bc7ee787/electronics/example_clock.png
--------------------------------------------------------------------------------
/electronics/example_noisegen_kicad502.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mlaaks/coherent-rtlsdr/1c861ad2828f0cbcac7f56fc094f1272bc7ee787/electronics/example_noisegen_kicad502.zip
--------------------------------------------------------------------------------
/examplecfg/URA21.cfg:
--------------------------------------------------------------------------------
1 | #optional config file for receiver configuration, iterate the dongles in order specified below
2 | #format is: number of channel (R or 0 for ref) : 'serial str'
3 | #use this to change the order and number of channels in the rx-matrix
4 | #configurable gains etc. for each channel could be implemented some day.
5 | R :'M REF'
6 | 1 :'M 0'
7 | 2 :'M 1'
8 | 3 :'M 2'
9 | 4 :'M 3'
10 | 5 :'M 4'
11 | 6 :'M 5'
12 | 7 :'M 6'
13 | 8 :'M 7'
14 | 9 :'M 8'
15 | 10:'M 9'
16 | 11:'M 10'
17 | 12:'M 11'
18 | 13:'M 12'
19 | 14:'M 13'
20 | 15:'M 14'
21 | 16:'M 15'
22 | 17:'M 16'
23 | 18:'M 17'
24 | 19:'M 18'
25 | 20:'M 19'
26 | 21:'M 20'
27 |
--------------------------------------------------------------------------------
/examplecfg/ac.cfg:
--------------------------------------------------------------------------------
1 | #optional config file for receiver configuration, iterate the dongles in order specified below
2 | #format is: number of channel (R or 0 for ref) : 'serial str'
3 | #use this to change the order and number of channels in the rx-matrix
4 | #configurable gains etc. for each channel could be implemented some day.
5 | R :'M REF'
6 | 1 :'M 0'
7 | 2 :'M 1'
8 | 3 :'M 2'
9 | 4 :'M 3'
10 | 5 :'M 4'
11 | 6 :'M 5'
12 | 7 :'M 6'
13 | 8 :'M 7'
14 | 9 :'M 8'
15 | 10:'M 9'
16 | 11:'M 10'
17 | 12:'M 11'
18 | 13:'M 12'
19 | 14:'M 13'
20 | 15:'M 14'
21 | 16:'M 15'
22 | 17:'M 16'
23 | 18:'M 17'
24 |
--------------------------------------------------------------------------------
/examplecfg/four.cfg:
--------------------------------------------------------------------------------
1 | #optional config file for receiver configuration, iterate the dongles in order specified below
2 | #format is: number of channel (R or 0 for ref) : 'serial str'
3 | #use this to change the order and number of channels in the rx-matrix
4 | #configurable gains etc. for each channel could be implemented some day.
5 | R :'M REF'
6 | 1 :'M 1'
7 | 2 :'M 2'
8 | 3 :'M 3'
9 |
--------------------------------------------------------------------------------
/include/ccoherent.h:
--------------------------------------------------------------------------------
1 | /*
2 | coherent-rtlsdr
3 |
4 | This program is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | coherent-rtlsdr is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with coherent-rtlsd. If not, see .
16 | */
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | #include "csdrdevice.h"
24 | #include "cpacketizer.h"
25 | #include "common.h"
26 | #include "cdsp.h"
27 | #include "crefnoise.h"
28 |
29 | using tmpcomplextype_ = std::complex; //this can be done, but is it worth it?
30 | using fftff_complex = tmpcomplextype_;
31 |
32 |
33 | class ccoherent{
34 | private:
35 | std::thread thread;
36 | static void threadf(ccoherent *);
37 |
38 | //std::vector *devices; //CHANGED
39 | lvector *devices;
40 | crefsdr *refdev;
41 |
42 | cpacketize *packetize;
43 |
44 | fft_scheme fftscheme,ifftscheme;
45 | std::complex *sifft, *sfft; //was fftwf_complex
46 | std::complex *sfloat, *sconv;
47 | float *smagsqr;
48 |
49 | int nfft;
50 | int blocksize;
51 |
52 | int mb; // RASPBERRYPI MAILBOX for gpu.
53 |
54 | std::vector lagqueue;
55 | crefnoise *refnoise;
56 | public:
57 |
58 | std::atomic do_exit;
59 | //ccoherent(crefsdr*,std::vector *, cpacketize *); //CHANGED
60 | //ccoherent(crefsdr*,lvector *, cpacketize *);
61 | ccoherent(crefsdr*,lvector *,crefnoise*, int nfft);
62 | ~ccoherent();
63 | void start();
64 | void request_exit();
65 | void join();
66 |
67 | size_t lagqueuesize();
68 |
69 | void clearlagqueue();
70 | void queuelag(csdrdevice *d);
71 | void queuelag(csdrdevice *d,bool refc);
72 | void computelag();
73 | };
74 |
--------------------------------------------------------------------------------
/include/cconfigfile.h:
--------------------------------------------------------------------------------
1 | /*
2 | coherent-rtlsdr
3 |
4 | This program is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | coherent-rtlsdr is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with coherent-rtlsdr. If not, see .
16 | */
17 |
18 | #include
19 | #include
20 | #include
21 |
22 | using namespace std;
23 |
24 |
25 | struct sdrdefs {
26 | uint32_t devindex;
27 | string serial;
28 | };
29 |
30 | class cconfigfile{
31 | public:
32 | static std::vector readconfig(string fname) {
33 | string ln;
34 | ifstream cfgfile(fname);
35 | std::vector v;
36 |
37 | while(getline(cfgfile,ln)){
38 | sdrdefs d;
39 | if (ln[0]=='#')
40 | continue;
41 | else{
42 | std::size_t st,end;
43 | std::string::size_type sz;
44 | string ids = ln.substr(0,2);
45 |
46 | if ((ids[0]=='R')||(ids[1]=='R'))
47 | d.devindex = 0;
48 | else
49 | d.devindex = std::stoi(ids,&sz);
50 |
51 | st = ln.find(":");
52 | st = ln.find("'",st+1);
53 | end= ln.find("'",st+1);
54 | d.serial = ln.substr(st+1,end-st-1);
55 | v.push_back(d);
56 | }
57 |
58 | }
59 | cfgfile.close();
60 | return v;
61 | }
62 |
63 | static string get_refname(std::vector vdefs){
64 | string ret;
65 | for(auto n : vdefs) {
66 | if (n.devindex==0){
67 | ret=n.serial;
68 | break;
69 | }
70 | }
71 | return ret;
72 | }
73 |
74 | };
75 |
--------------------------------------------------------------------------------
/include/ccontrol.h:
--------------------------------------------------------------------------------
1 | /*
2 | coherent-rtlsdr
3 |
4 | This program is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | coherent-rtlsdr is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with coherent-rtlsdr. If not, see .
16 | */
17 | #ifndef CCONTROLH
18 | #define CCONTROLH
19 |
20 | #include
21 | #include
22 | #include "csdrdevice.h"
23 |
24 | //forward declaration, these classes have a circular dependency
25 | class ccontrol;
26 | class csdrdevice;
27 |
28 | class ccontrol{
29 | private:
30 | std::thread thread;
31 | static void threadf(ccontrol *);
32 |
33 | csdrdevice *dev;
34 | public:
35 | std::atomic do_exit;
36 |
37 | void start();
38 | void request_exit();
39 | void join();
40 | ccontrol(csdrdevice *device){
41 | dev=device;
42 | do_exit = false;
43 | }
44 |
45 | ~ccontrol(){
46 | if (thread.joinable()) thread.join();
47 | }
48 |
49 | };
50 |
51 | #endif
52 |
53 |
--------------------------------------------------------------------------------
/include/cdsp.h:
--------------------------------------------------------------------------------
1 | /*
2 | coherent-rtlsdr
3 |
4 | This program is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | coherent-rtlsdr is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with coherent-rtlsdr. If not, see .
16 | */
17 |
18 | #ifndef CDSPH
19 | #define CDSPH
20 | //#include "common.h"
21 | #include
22 |
23 | #ifdef RASPBERRYPI
24 | extern "C"{
25 | #include "gpu_fft.h"
26 | #include "mailbox.h"
27 | typedef struct GPU_FFT *fft_scheme;
28 | }
29 | #else
30 | #include
31 | typedef fftwf_plan fft_scheme;
32 | #endif
33 |
34 | class cbuffer;
35 |
36 | class cdsp{
37 | public:
38 | //static void convtosigned(const cbuffer in, const cbuffer out, int n);
39 | //static void convtosigned(const uint8_t*in, const cbuffer out, int n);
40 | static void convtosigned(const uint8_t*in, const uint8_t *out, int n);
41 | static const float* convtofloat(const float *out, const int8_t *s8bit, int n);
42 |
43 | static const std::complex* convto8bit(std::complex *out,std::complex*in, int n);
44 |
45 | static const std::complex* convtofloat(const std::complex *out, const int8_t *s8bit, int n);
46 |
47 | static const std::complex* scalarmul(const std::complex *out,const std::complex *in,const std::complex scalar_in, int n);
48 |
49 | static const std::complex conj_dotproduct(const std::complex *a,const std::complex *b, int n);
50 | //static const std::complex* convtofloat(const float *out, const int8_t *s8bit, int n);
51 |
52 | static const float rms(const float *in, int n);
53 | static const float rms(const std::complex *in,int n);
54 |
55 | static const float PAPR(const std::complex *s,const std::complex *ref, int n);
56 |
57 | static const float crestfactor(const float *in,float peak, int n);
58 | static const float crestfactor(const float *in, int n);
59 |
60 | static const float* magsquared(float *out,const std::complex *in,int n);
61 |
62 | static const std::complex* conjugatemul(std::complex*out, std::complex *in1, std::complex *in2, int n);
63 |
64 | static const std::complex* fft(std::complex*out, std::complex *in,fft_scheme *scheme);
65 | static const std::complex* fft(fft_scheme *scheme);
66 |
67 | static const uint32_t indexofmax(float *in,int n);
68 | static const uint32_t indexofmax(float *out,std::complex *in,int n);
69 | //static const std::complex* ifft(std::complex*out, std::complex *in);
70 |
71 | };
72 |
73 | #endif
74 |
--------------------------------------------------------------------------------
/include/common.h:
--------------------------------------------------------------------------------
1 | /*
2 | coherent-rtlsdr
3 |
4 | This program is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | coherent-rtlsdr is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with coherent-rtlsdr. If not, see .
16 | */
17 |
18 | #ifndef COMMONH
19 | #define COMMONH
20 |
21 | #include
22 | #include
23 | #include "cdsp.h"
24 |
25 | #include
26 | #include
27 | #include //memset
28 | #include
29 |
30 | #define USELIBRTLSDRBUFS
31 |
32 | const float sync_threshold=0.005;
33 |
34 | #define TWO_POW(n) ((double)(1ULL<<(n)))
35 |
36 | template int sgn(T val) {
37 | return (T(0) < val) - (val < T(0));
38 | }
39 |
40 | //a circular pointer array:
41 | class cbuffer{
42 | public:
43 | int8_t **ptr;
44 | uint32_t *readcnt;
45 | uint64_t *timestamp;
46 | uint32_t L;
47 | uint32_t N;
48 |
49 | uint32_t wp;
50 | uint32_t rp;
51 |
52 | cbuffer(uint32_t n, uint32_t l){
53 | ptr = new int8_t* [n];
54 | readcnt = new uint32_t [n];
55 | timestamp = new uint64_t [n];
56 |
57 |
58 |
59 | wp = 0;
60 | rp = 0;
61 | N=n;
62 | L=l;
63 |
64 | int alignment = volk_get_alignment();
65 | for (int i=0;i lock{mtx};
162 | if (--cnt == 0) {
163 | cv.notify_all();
164 | } else {
165 | cv.wait(lock, [this] { return cnt == 0; });
166 | }
167 | }
168 | };
169 |
170 | /*template ::value_type>>
171 | vector(InputIterator, InputIterator, Allocator = Allocator())
172 | -> vector::value_type, Allocator>;
173 | template struct hash>;
174 | */
175 |
176 |
177 | //template bool operator!=(const vector& x, const vector& y
178 |
179 | //template class lvector;
180 |
181 | using namespace std;
182 | template
183 | class lvector{
184 | private:
185 | // using vector_t = std::vector;
186 | std::vector q;
187 | //T a;
188 | //std::condition_variable cv;
189 | public:
190 | mutable std::mutex m;
191 | //std::mutex m;
192 | explicit lvector(): q(){
193 | }
194 | lvector(T obj): q(obj){
195 | }
196 |
197 | void push_back(const T& v){
198 | std::lock_guard lock(m);
199 | q.push_back(v);
200 | };
201 | void pop_back(){
202 | std::lock_guard lock(m);
203 | q.pop_back();
204 | };
205 |
206 |
207 |
208 | //typedef std::iterator::iterator> iterator;
209 | using iterator = typename std::vector::iterator;
210 | // using iterator = vector_t::iterator;
211 | // using const_iterator = vector_t::const_iterator;
212 | //std::iterator> begin(){
213 | //std::iterator > begin(){
214 |
215 | void lock(){
216 | m.lock();
217 | };
218 | void unlock(){
219 | m.unlock();
220 | };
221 | void erase(iterator it){
222 | std::lock_guard lock(m);
223 | q.erase(it);
224 | }
225 |
226 | const iterator begin(){
227 | return q.begin();
228 | }
229 |
230 |
231 | const iterator end(){
232 | return q.end();
233 | }
234 | T& back(){
235 | return q.back();
236 | }
237 |
238 |
239 | size_t size() const{
240 | return q.size();
241 | };
242 |
243 | T& operator[](std::size_t idx) { /*std::unique_lock lock(m); */ return q[idx]; }
244 | const T& operator[](std::size_t idx) const { /*std::unique_lock lock(m); */ return q[idx]; }
245 | bool operator!=(const T& a){ return !(a == q);}
246 | };
247 |
248 |
249 | template
250 | class lqueue{
251 | private:
252 | std::queue q;
253 | std::condition_variable cv;
254 | std::mutex m;
255 | public:
256 | lqueue(): q(){
257 | }
258 | lqueue(T obj): q(obj){
259 | }
260 |
261 | void push(const T & v){
262 | std::lock_guard lock(m);
263 | q.push(v);
264 | cv.notify_one();
265 | };
266 |
267 | T& front(){
268 | // std::unique_lock lock(m);
269 | // cv.wait(lock, [this]{return (q.size() > 0);});
270 | return q.front();
271 | };
272 | T pop(){
273 | {
274 | std::unique_lock lock(m);
275 | cv.wait(lock, [this]{return (q.size()>0);});
276 | }
277 | T v =q.front(); // was T& v, reference got bad after certain number of chars when T=std::string
278 |
279 | //std::cout << "we have: "<< v << std::endl;
280 | q.pop();
281 | return v;
282 | };
283 |
284 | size_t size() const{
285 | return q.size();
286 | };
287 | };
288 |
289 | bool is_zeros(uint32_t *p,int n);
290 |
291 | #endif
--------------------------------------------------------------------------------
/include/console.h:
--------------------------------------------------------------------------------
1 | /*
2 | coherent-rtlsdr
3 |
4 | This program is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | coherent-rtlsdr is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with coherent-rtlsdr. If not, see .
16 | */
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include