| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  | #include "SDRPostThread.h"
 | 
					
						
							|  |  |  | #include "CubicSDRDefs.h"
 | 
					
						
							|  |  |  | #include <vector>
 | 
					
						
							|  |  |  | #include "CubicSDR.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SDRPostThread::SDRPostThread() : | 
					
						
							| 
									
										
										
										
											2014-12-11 19:07:21 -05:00
										 |  |  |         iqDataInQueue(NULL), iqDataOutQueue(NULL), iqVisualQueue(NULL), terminated(false), dcFilter(NULL), sample_rate(SRATE) { | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SDRPostThread::~SDRPostThread() { | 
					
						
							| 
									
										
										
										
											2014-12-11 19:07:21 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void SDRPostThread::bindDemodulator(DemodulatorInstance *demod) { | 
					
						
							|  |  |  |     demodulators.push_back(demod); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void SDRPostThread::removeDemodulator(DemodulatorInstance *demod) { | 
					
						
							|  |  |  |     if (!demod) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::vector<DemodulatorInstance *>::iterator i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     i = std::find(demodulators.begin(), demodulators.end(), demod); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (i != demodulators.end()) { | 
					
						
							|  |  |  |         demodulators.erase(i); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void SDRPostThread::setIQDataInQueue(SDRThreadIQDataQueue* iqDataQueue) { | 
					
						
							|  |  |  |     iqDataInQueue = iqDataQueue; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | void SDRPostThread::setIQDataOutQueue(SDRThreadIQDataQueue* iqDataQueue) { | 
					
						
							|  |  |  |     iqDataOutQueue = iqDataQueue; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | void SDRPostThread::setIQVisualQueue(SDRThreadIQDataQueue *iqVisQueue) { | 
					
						
							|  |  |  |     iqVisualQueue = iqVisQueue; | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void SDRPostThread::threadMain() { | 
					
						
							|  |  |  |     int n_read; | 
					
						
							|  |  |  |     double seconds = 0.0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-18 20:11:25 -05:00
										 |  |  | #ifdef __APPLE__
 | 
					
						
							|  |  |  |     pthread_t tID = pthread_self();  // ID of this thread
 | 
					
						
							|  |  |  |     int priority = sched_get_priority_max( SCHED_FIFO) - 1; | 
					
						
							| 
									
										
										
										
											2014-12-22 19:43:56 -05:00
										 |  |  |     sched_param prio = {priority}; // scheduling priority of thread
 | 
					
						
							| 
									
										
										
										
											2014-12-18 20:11:25 -05:00
										 |  |  |     pthread_setschedparam(tID, SCHED_FIFO, &prio); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-12-16 20:33:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  |     dcFilter = iirfilt_crcf_create_dc_blocker(0.0005); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     liquid_float_complex x, y; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-30 17:11:29 -05:00
										 |  |  |     std::cout << "SDR post-processing thread started.." << std::endl; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  |     while (!terminated) { | 
					
						
							|  |  |  |         SDRThreadIQData data_in; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         iqDataInQueue.load()->pop(data_in); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-22 19:43:56 -05:00
										 |  |  |         if (data_in.data && data_in.data->size()) { | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  |             SDRThreadIQData dataOut; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             dataOut.frequency = data_in.frequency; | 
					
						
							|  |  |  |             dataOut.bandwidth = data_in.bandwidth; | 
					
						
							|  |  |  |             dataOut.data = data_in.data; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-22 19:43:56 -05:00
										 |  |  |             for (int i = 0, iMax = dataOut.data->size() / 2; i < iMax; i++) { | 
					
						
							|  |  |  |                 x.real = (float) (*dataOut.data)[i * 2] / 127.0; | 
					
						
							|  |  |  |                 x.imag = (float) (*dataOut.data)[i * 2 + 1] / 127.0; | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 iirfilt_crcf_execute(dcFilter, x, &y); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-22 19:43:56 -05:00
										 |  |  |                 (*dataOut.data)[i * 2] = (signed char) floor(y.real * 127.0); | 
					
						
							|  |  |  |                 (*dataOut.data)[i * 2 + 1] = (signed char) floor(y.imag * 127.0); | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (iqDataOutQueue != NULL) { | 
					
						
							|  |  |  |                 iqDataOutQueue.load()->push(dataOut); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-22 19:43:56 -05:00
										 |  |  |             if (iqVisualQueue != NULL && iqVisualQueue.load()->empty()) { | 
					
						
							|  |  |  |                 SDRThreadIQData visualDataOut; | 
					
						
							|  |  |  |                 visualDataOut.data = new std::vector<signed char>; | 
					
						
							|  |  |  |                 visualDataOut.data->assign(dataOut.data->begin(), dataOut.data->begin() + (FFT_SIZE * 2)); | 
					
						
							|  |  |  |                 iqVisualQueue.load()->push(visualDataOut); | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-22 19:43:56 -05:00
										 |  |  |             std::atomic<int> *c = new std::atomic<int>; | 
					
						
							|  |  |  |             c->store(demodulators.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             bool demodActive = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  |             if (demodulators.size()) { | 
					
						
							| 
									
										
										
										
											2014-12-11 20:50:58 -05:00
										 |  |  |                 DemodulatorThreadIQData dummyDataOut; | 
					
						
							|  |  |  |                 dummyDataOut.frequency = data_in.frequency; | 
					
						
							|  |  |  |                 dummyDataOut.bandwidth = data_in.bandwidth; | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  |                 DemodulatorThreadIQData demodDataOut; | 
					
						
							|  |  |  |                 demodDataOut.frequency = data_in.frequency; | 
					
						
							|  |  |  |                 demodDataOut.bandwidth = data_in.bandwidth; | 
					
						
							| 
									
										
										
										
											2014-12-22 19:43:56 -05:00
										 |  |  |                 demodDataOut.setRefCount(c); | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  |                 demodDataOut.data = data_in.data; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-18 20:11:25 -05:00
										 |  |  |                 std::vector<DemodulatorInstance *>::iterator i; | 
					
						
							|  |  |  |                 for (i = demodulators.begin(); i != demodulators.end(); i++) { | 
					
						
							|  |  |  |                     DemodulatorInstance *demod = *i; | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  |                     DemodulatorThreadInputQueue *demodQueue = demod->threadQueueDemod; | 
					
						
							| 
									
										
										
										
											2014-12-11 20:50:58 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-18 20:11:25 -05:00
										 |  |  |                     if (demod->getParams().frequency != data_in.frequency | 
					
						
							|  |  |  |                             && abs(data_in.frequency - demod->getParams().frequency) > (int) ((float) ((float) SRATE / 2.0) * 1.15)) { | 
					
						
							|  |  |  |                         if (demod->isActive()) { | 
					
						
							|  |  |  |                             demod->setActive(false); | 
					
						
							| 
									
										
										
										
											2014-12-11 20:50:58 -05:00
										 |  |  |                             demodQueue->push(dummyDataOut); | 
					
						
							| 
									
										
										
										
											2014-12-22 19:43:56 -05:00
										 |  |  |                             c->store(c->load() - 1); | 
					
						
							| 
									
										
										
										
											2014-12-11 20:50:58 -05:00
										 |  |  |                             continue; | 
					
						
							|  |  |  |                         } | 
					
						
							| 
									
										
										
										
											2014-12-18 20:11:25 -05:00
										 |  |  |                     } else if (!demod->isActive()) { | 
					
						
							|  |  |  |                         demod->setActive(true); | 
					
						
							| 
									
										
										
										
											2014-12-11 20:50:58 -05:00
										 |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  |                     demodQueue->push(demodDataOut); | 
					
						
							| 
									
										
										
										
											2014-12-22 19:43:56 -05:00
										 |  |  |                     demodActive = true; | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2014-12-22 19:43:56 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (!demodActive) { | 
					
						
							|  |  |  |                 delete dataOut.data; | 
					
						
							|  |  |  |                 delete c; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-30 17:11:29 -05:00
										 |  |  |     std::cout << "SDR post-processing thread done." << std::endl; | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void SDRPostThread::terminate() { | 
					
						
							|  |  |  |     terminated = true; | 
					
						
							| 
									
										
										
										
											2014-11-30 17:11:29 -05:00
										 |  |  |     SDRThreadIQData dummy; | 
					
						
							|  |  |  |     iqDataInQueue.load()->push(dummy); | 
					
						
							| 
									
										
										
										
											2014-11-29 13:58:20 -05:00
										 |  |  | } |