mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-31 04:50:29 -04:00 
			
		
		
		
	DATV: various fixes and enhancements to ldpc_tool handling. Implements #804
This commit is contained in:
		
							parent
							
								
									233f512f9c
								
							
						
					
					
						commit
						d73f093dab
					
				| @ -54,7 +54,7 @@ DATVDemodSink::DATVDemodSink() : | ||||
| { | ||||
|     //*************** DATV PARAMETERS  ***************
 | ||||
|     m_blnInitialized=false; | ||||
|     CleanUpDATVFramework(false); | ||||
|     ResetDATVFrameworkPointers(); | ||||
|     m_objVideoStream = new DATVideostream(); | ||||
|     m_objRFFilter = new fftfilt(-256000.0 / 1024000.0, 256000.0 / 1024000.0, m_rfFilterFftLength); | ||||
| } | ||||
| @ -81,7 +81,7 @@ DATVDemodSink::~DATVDemodSink() | ||||
|         m_objRenderThread->wait(2000); | ||||
|     } | ||||
| 
 | ||||
|     CleanUpDATVFramework(true); | ||||
|     CleanUpDATVFramework(); | ||||
| 
 | ||||
|     delete m_objRFFilter; | ||||
| } | ||||
| @ -154,7 +154,6 @@ bool DATVDemodSink::videoDecodeOK() | ||||
| 
 | ||||
| bool DATVDemodSink::PlayVideo(bool blnStartStop) | ||||
| { | ||||
| 
 | ||||
|     if (m_objVideoStream == nullptr) { | ||||
|         return false; | ||||
|     } | ||||
| @ -195,9 +194,7 @@ bool DATVDemodSink::PlayVideo(bool blnStartStop) | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void DATVDemodSink::CleanUpDATVFramework(bool blnRelease) | ||||
| { | ||||
|     if (blnRelease == true) | ||||
| void DATVDemodSink::CleanUpDATVFramework() | ||||
| { | ||||
|     if (m_objScheduler != nullptr) | ||||
|     { | ||||
| @ -229,6 +226,9 @@ void DATVDemodSink::CleanUpDATVFramework(bool blnRelease) | ||||
|     if (r_cnr != nullptr) { | ||||
|         delete r_cnr; | ||||
|     } | ||||
|     if (r_cnrGauge != nullptr) { | ||||
|         delete r_cnrGauge; | ||||
|     } | ||||
| 
 | ||||
|     //FILTERING
 | ||||
|     if (r_resample != nullptr) { | ||||
| @ -260,6 +260,9 @@ void DATVDemodSink::CleanUpDATVFramework(bool blnRelease) | ||||
|     if (p_mer != nullptr) { | ||||
|         delete p_mer; | ||||
|     } | ||||
|     if (r_merGauge != nullptr) { | ||||
|         delete r_merGauge; | ||||
|     } | ||||
|     if (p_sampled != nullptr) { | ||||
|         delete p_sampled; | ||||
|     } | ||||
| @ -351,10 +354,7 @@ void DATVDemodSink::CleanUpDATVFramework(bool blnRelease) | ||||
|         delete r_derand; | ||||
|     } | ||||
| 
 | ||||
|         //OUTPUT : To remove
 | ||||
|         if (r_stdout != nullptr) { | ||||
|             delete r_stdout; | ||||
|         } | ||||
|     //OUTPUT
 | ||||
|     if (r_videoplayer != nullptr) { | ||||
|         delete r_videoplayer; | ||||
|     } | ||||
| @ -363,12 +363,6 @@ void DATVDemodSink::CleanUpDATVFramework(bool blnRelease) | ||||
|     if (r_scope_symbols != nullptr) { | ||||
|         delete r_scope_symbols; | ||||
|     } | ||||
|         if (r_merGauge != nullptr) { | ||||
|             delete r_merGauge; | ||||
|         } | ||||
|         if (r_cnrGauge != nullptr) { | ||||
|             delete r_cnrGauge; | ||||
|         } | ||||
| 
 | ||||
|     // INPUT
 | ||||
|     if (p_rawiq != nullptr) { | ||||
| @ -381,76 +375,67 @@ void DATVDemodSink::CleanUpDATVFramework(bool blnRelease) | ||||
| 
 | ||||
|     //DVB-S2
 | ||||
| 
 | ||||
|         if(p_slots_dvbs2  != nullptr) | ||||
|         { | ||||
|     if (p_slots_dvbs2  != nullptr) { | ||||
|         delete (leansdr::pipebuf< leansdr::plslot<leansdr::llr_ss> >*) p_slots_dvbs2; | ||||
|     } | ||||
| 
 | ||||
|         if(p_cstln  != nullptr) | ||||
|         { | ||||
|     if (p_cstln  != nullptr) { | ||||
|         delete p_cstln; | ||||
|     } | ||||
| 
 | ||||
|         if(p_cstln_pls != nullptr) | ||||
|         { | ||||
|     if (p_cstln_pls != nullptr) { | ||||
|         delete p_cstln_pls; | ||||
|     } | ||||
| 
 | ||||
|         if(p_framelock != nullptr) | ||||
|         { | ||||
|     if (p_framelock != nullptr) { | ||||
|         delete p_framelock; | ||||
|     } | ||||
| 
 | ||||
|         if(m_objDemodulatorDVBS2 != nullptr) | ||||
|         { | ||||
|     if (m_objDemodulatorDVBS2 != nullptr) { | ||||
|         delete (leansdr::s2_frame_receiver<leansdr::f32, leansdr::llr_ss>*) m_objDemodulatorDVBS2; | ||||
|     } | ||||
| 
 | ||||
|         if(p_fecframes != nullptr) | ||||
|         { | ||||
|     if (p_fecframes != nullptr) { | ||||
|         delete (leansdr::pipebuf< leansdr::fecframe<leansdr::hard_sb> >*) p_fecframes; | ||||
|     } | ||||
| 
 | ||||
|         if(p_bbframes != nullptr) | ||||
|         { | ||||
|     if (p_bbframes != nullptr) { | ||||
|         delete (leansdr::pipebuf<leansdr::bbframe>*) p_bbframes; | ||||
|     } | ||||
| 
 | ||||
|         if(p_s2_deinterleaver != nullptr) | ||||
|         { | ||||
|     if (p_s2_deinterleaver != nullptr) { | ||||
|         delete (leansdr::s2_deinterleaver<leansdr::llr_ss,leansdr::hard_sb>*) p_s2_deinterleaver; | ||||
|     } | ||||
| 
 | ||||
|         if(r_fecdec != nullptr) | ||||
|         { | ||||
|     if (r_fecdec != nullptr) { | ||||
|         delete (leansdr::s2_fecdec<bool, leansdr::hard_sb>*) r_fecdec; | ||||
|     } | ||||
| 
 | ||||
| #ifdef LINUX | ||||
|         if(r_fecdecsoft != nullptr) | ||||
|         { | ||||
|     if (r_fecdecsoft != nullptr) { | ||||
|         delete (leansdr::s2_fecdec_soft<leansdr::llr_t,leansdr::llr_sb>*) r_fecdecsoft; | ||||
|     } | ||||
|         if(r_fecdechelper != nullptr) | ||||
|         { | ||||
| 
 | ||||
|     if (r_fecdechelper != nullptr) { | ||||
|         delete (leansdr::s2_fecdec_helper<leansdr::llr_t,leansdr::llr_sb>*) r_fecdechelper; | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|         if(p_deframer != nullptr) | ||||
|         { | ||||
|     if (p_deframer != nullptr) { | ||||
|         delete (leansdr::s2_deframer*) p_deframer; | ||||
|     } | ||||
| 
 | ||||
|         if(r_scope_symbols_dvbs2 != nullptr) | ||||
|         { | ||||
|     if (r_scope_symbols_dvbs2 != nullptr) { | ||||
|         delete r_scope_symbols_dvbs2; | ||||
|     } | ||||
|     } // blnRelease
 | ||||
| 
 | ||||
|     m_objScheduler=nullptr; | ||||
|     ResetDATVFrameworkPointers(); | ||||
| } | ||||
| 
 | ||||
| void DATVDemodSink::ResetDATVFrameworkPointers() | ||||
| { | ||||
|     // INPUT
 | ||||
|     m_objScheduler = nullptr; | ||||
| 
 | ||||
|     p_rawiq = nullptr; | ||||
|     p_rawiq_writer = nullptr; | ||||
| @ -468,6 +453,7 @@ void DATVDemodSink::CleanUpDATVFramework(bool blnRelease) | ||||
|     // CNR ESTIMATION
 | ||||
|     p_cnr = nullptr; | ||||
|     r_cnr = nullptr; | ||||
|     r_cnrGauge = nullptr; | ||||
| 
 | ||||
|     //FILTERING
 | ||||
|     r_resample = nullptr; | ||||
| @ -484,6 +470,7 @@ void DATVDemodSink::CleanUpDATVFramework(bool blnRelease) | ||||
|     p_freq = nullptr; | ||||
|     p_ss = nullptr; | ||||
|     p_mer = nullptr; | ||||
|     r_merGauge = nullptr; | ||||
|     p_sampled = nullptr; | ||||
| 
 | ||||
|     //DECIMATION
 | ||||
| @ -509,7 +496,6 @@ void DATVDemodSink::CleanUpDATVFramework(bool blnRelease) | ||||
|     p_locktime = nullptr; | ||||
|     r_sync_mpeg = nullptr; | ||||
| 
 | ||||
| 
 | ||||
|     // DEINTERLEAVING
 | ||||
|     p_rspackets = nullptr; | ||||
|     r_deinter = nullptr; | ||||
| @ -519,26 +505,19 @@ void DATVDemodSink::CleanUpDATVFramework(bool blnRelease) | ||||
|     p_rtspackets = nullptr; | ||||
|     r_rsdec = nullptr; | ||||
| 
 | ||||
| 
 | ||||
|     //BER ESTIMATION
 | ||||
|     p_vber = nullptr; | ||||
|     r_vber  = nullptr; | ||||
| 
 | ||||
| 
 | ||||
|     // DERANDOMIZATION
 | ||||
|     p_tspackets = nullptr; | ||||
|     r_derand = nullptr; | ||||
| 
 | ||||
| 
 | ||||
|     //OUTPUT : To remove void *
 | ||||
|     r_stdout = nullptr; | ||||
|     r_videoplayer = nullptr; | ||||
| 
 | ||||
| 
 | ||||
|     //CONSTELLATION
 | ||||
|     r_scope_symbols = nullptr; | ||||
|     r_merGauge = nullptr; | ||||
|     r_cnrGauge = nullptr; | ||||
| 
 | ||||
|     //DVB-S2
 | ||||
|     p_slots_dvbs2 = nullptr; | ||||
| @ -550,8 +529,10 @@ void DATVDemodSink::CleanUpDATVFramework(bool blnRelease) | ||||
|     p_bbframes = nullptr; | ||||
|     p_s2_deinterleaver = nullptr; | ||||
|     r_fecdec = nullptr; | ||||
| #ifdef LINUX | ||||
|     r_fecdecsoft = nullptr; | ||||
|     r_fecdechelper = nullptr; | ||||
| #endif | ||||
|     p_deframer = nullptr; | ||||
|     r_scope_symbols_dvbs2 = nullptr; | ||||
| } | ||||
| @ -560,7 +541,7 @@ void DATVDemodSink::InitDATVFramework() | ||||
| { | ||||
|     m_blnDVBInitialized = false; | ||||
|     m_lngReadIQ = 0; | ||||
|     CleanUpDATVFramework(false); | ||||
|     CleanUpDATVFramework(); | ||||
| 
 | ||||
|     qDebug()  << "DATVDemodSink::InitDATVFramework:" | ||||
|         <<  " Standard: " << m_settings.m_standard | ||||
| @ -675,7 +656,6 @@ void DATVDemodSink::InitDATVFramework() | ||||
|         p_preprocessed = p_autonotched; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     // FREQUENCY CORRECTION
 | ||||
| 
 | ||||
|     //******** -> if ( m_objCfg.Fderot>0 )
 | ||||
| @ -696,7 +676,6 @@ void DATVDemodSink::InitDATVFramework() | ||||
| 
 | ||||
|     //******** -> if ( m_objCfg.resample )
 | ||||
| 
 | ||||
| 
 | ||||
|     // DECIMATION
 | ||||
|     // (Unless already done in resampler)
 | ||||
| 
 | ||||
| @ -704,7 +683,6 @@ void DATVDemodSink::InitDATVFramework() | ||||
| 
 | ||||
|     //Resampling FS
 | ||||
| 
 | ||||
| 
 | ||||
|     // Generic constellation receiver
 | ||||
| 
 | ||||
|     p_symbols = new leansdr::pipebuf<leansdr::eucl_ss>(m_objScheduler, "PSK soft-symbols", BUF_SYMBOLS); | ||||
| @ -898,7 +876,7 @@ void DATVDemodSink::InitDATVS2Framework() | ||||
| 
 | ||||
|     m_blnDVBInitialized = false; | ||||
|     m_lngReadIQ = 0; | ||||
|     CleanUpDATVFramework(true); | ||||
|     CleanUpDATVFramework(); | ||||
| 
 | ||||
|     qDebug()  << "DATVDemodSink::InitDATVS2Framework:" | ||||
|         <<  " Standard: " << m_settings.m_standard | ||||
| @ -1026,7 +1004,6 @@ void DATVDemodSink::InitDATVS2Framework() | ||||
| 
 | ||||
|     //******** -> if ( m_objCfg.resample )
 | ||||
| 
 | ||||
| 
 | ||||
|     // DECIMATION
 | ||||
|     // (Unless already done in resampler)
 | ||||
| 
 | ||||
| @ -1034,7 +1011,6 @@ void DATVDemodSink::InitDATVS2Framework() | ||||
| 
 | ||||
|     //Resampling FS
 | ||||
| 
 | ||||
| 
 | ||||
|     // Generic constellation receiver
 | ||||
| 
 | ||||
|     p_freq = new leansdr::pipebuf<leansdr::f32> (m_objScheduler, "freq", BUF_SLOW); | ||||
| @ -1086,15 +1062,13 @@ void DATVDemodSink::InitDATVS2Framework() | ||||
|         p_cstln, | ||||
|         /* p_cstln_pls */ nullptr, | ||||
|         /*p_iqsymbols*/ nullptr, | ||||
|                         /* p_framelock */nullptr); | ||||
|         /* p_framelock */nullptr | ||||
|     ); | ||||
| 
 | ||||
|     objDemodulatorDVBS2 = (leansdr::s2_frame_receiver<leansdr::f32, leansdr::llr_ss> *) m_objDemodulatorDVBS2; | ||||
| 
 | ||||
| 
 | ||||
|     objDemodulatorDVBS2->omega0 = m_objCfg.Fs/m_objCfg.Fm; | ||||
|     //objDemodulatorDVBS2->mu=1;
 | ||||
| 
 | ||||
| 
 | ||||
|     m_objCfg.Ftune=0.0f; | ||||
|     objDemodulatorDVBS2->Ftune = m_objCfg.Ftune / m_objCfg.Fm; | ||||
| 
 | ||||
| @ -1102,12 +1076,8 @@ void DATVDemodSink::InitDATVS2Framework() | ||||
|   demod.strongpls = cfg.strongpls; | ||||
| */ | ||||
| 
 | ||||
|     //objDemodulatorDVBS2->Fm = m_objCfg.Fm; deprecated
 | ||||
|     objDemodulatorDVBS2->meas_decimation = decimation(m_objCfg.Fs, m_objCfg.Finfo); | ||||
| 
 | ||||
|     objDemodulatorDVBS2->strongpls = false; | ||||
| 
 | ||||
| 
 | ||||
|     objDemodulatorDVBS2->cstln = make_dvbs2_constellation(m_objCfg.constellation, m_objCfg.fec); | ||||
|     m_cstlnSetByModcod = false; | ||||
| 
 | ||||
| @ -1116,7 +1086,6 @@ void DATVDemodSink::InitDATVS2Framework() | ||||
|     if (m_objRegisteredTVScreen) | ||||
|     { | ||||
|         qDebug("DATVDemodSink::InitDATVS2Framework: Register DVBS 2 TVSCREEN"); | ||||
| 
 | ||||
|         m_objRegisteredTVScreen->resizeTVScreen(256,256); | ||||
|         r_scope_symbols_dvbs2 = new leansdr::datvdvbs2constellation<leansdr::f32>(m_objScheduler, *p_cstln /* *p_sampled */ /* *p_cstln */, -128,128, nullptr, m_objRegisteredTVScreen); | ||||
|         r_scope_symbols_dvbs2->decimation = 1; | ||||
| @ -1249,13 +1218,11 @@ void DATVDemodSink::InitDATVS2Framework() | ||||
|     p_lock = new leansdr::pipebuf<int> (m_objScheduler, "lock", BUF_SLOW); | ||||
|     p_locktime = new leansdr::pipebuf<leansdr::u32> (m_objScheduler, "locktime", BUF_S2PACKETS); | ||||
|     p_tspackets = new leansdr::pipebuf<leansdr::tspacket>(m_objScheduler, "TS packets", BUF_S2PACKETS); | ||||
| 
 | ||||
|     p_deframer = new leansdr::s2_deframer(m_objScheduler,*(leansdr::pipebuf<leansdr::bbframe> *) p_bbframes, *p_tspackets, p_lock, p_locktime); | ||||
| 
 | ||||
| /*
 | ||||
|  if ( cfg.fd_gse >= 0 ) deframer.fd_gse = cfg.fd_gse; | ||||
| */ | ||||
|     //**********************************************
 | ||||
| 
 | ||||
|     // OUTPUT
 | ||||
|     r_videoplayer = new leansdr::datvvideoplayer<leansdr::tspacket>(m_objScheduler, *p_tspackets, m_objVideoStream, &m_udpStream); | ||||
| @ -1268,7 +1235,6 @@ void DATVDemodSink::feed(const SampleVector::const_iterator& begin, const Sample | ||||
|     float fltI; | ||||
|     float fltQ; | ||||
|     leansdr::cf32 objIQ; | ||||
|     //Complex objC;
 | ||||
|     fftfilt::cmplx *objRF; | ||||
|     int intRFOut; | ||||
|     double magSq; | ||||
| @ -1276,7 +1242,6 @@ void DATVDemodSink::feed(const SampleVector::const_iterator& begin, const Sample | ||||
|     int lngWritable=0; | ||||
| 
 | ||||
|     //********** Bis repetita : Let's rock and roll buddy ! **********
 | ||||
| 
 | ||||
| #ifdef EXTENDED_DIRECT_SAMPLE | ||||
| 
 | ||||
|     qint16 * ptrBuffer; | ||||
| @ -1306,10 +1271,7 @@ void DATVDemodSink::feed(const SampleVector::const_iterator& begin, const Sample | ||||
|         fltQ = it->imag(); | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
|         //********** demodulation **********
 | ||||
| 
 | ||||
| 
 | ||||
|         if (m_blnNeedConfigUpdate) | ||||
|         { | ||||
|             qDebug("DATVDemodSink::feed: Settings applied. Standard : %d...", m_settings.m_standard); | ||||
| @ -1327,13 +1289,9 @@ void DATVDemodSink::feed(const SampleVector::const_iterator& begin, const Sample | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         //********** iq stream ****************
 | ||||
| 
 | ||||
|         Complex objC(fltI,fltQ); | ||||
| 
 | ||||
|         objC *= m_objNCO.nextIQ(); | ||||
| 
 | ||||
|         intRFOut = m_objRFFilter->runFilt(objC, &objRF); // filter RF before demod
 | ||||
| 
 | ||||
|         for (int intI = 0 ; intI < intRFOut; intI++) | ||||
|  | ||||
| @ -142,7 +142,8 @@ private: | ||||
| 
 | ||||
|     inline int decimation(float Fin, float Fout) { int d = Fin / Fout; return std::max(d, 1); } | ||||
| 
 | ||||
|     void CleanUpDATVFramework(bool blnRelease); | ||||
|     void CleanUpDATVFramework(); | ||||
|     void ResetDATVFrameworkPointers(); | ||||
|     void InitDATVFramework(); | ||||
|     void InitDATVS2Framework(); | ||||
| 
 | ||||
| @ -274,7 +275,6 @@ private: | ||||
| 
 | ||||
| 
 | ||||
|     //OUTPUT
 | ||||
|     leansdr::file_writer<leansdr::tspacket> *r_stdout; | ||||
|     leansdr::datvvideoplayer<leansdr::tspacket> *r_videoplayer; | ||||
| 
 | ||||
|     //CONSTELLATION
 | ||||
|  | ||||
| @ -255,7 +255,7 @@ bool DATVideoRender::PreprocessStream() | ||||
|     MetaData.Program = ""; | ||||
|     MetaData.Stream = ""; | ||||
| 
 | ||||
|     if (m_formatCtx->programs) | ||||
|     if (m_formatCtx->programs && m_formatCtx->programs[m_videoStreamIndex]) | ||||
|     { | ||||
|         buffer = nullptr; | ||||
|         av_dict_get_string(m_formatCtx->programs[m_videoStreamIndex]->metadata, &buffer, ':', '\n'); | ||||
|  | ||||
| @ -181,8 +181,8 @@ int main(int argc, char **argv) | ||||
| 
 | ||||
| 			if (num_decodes == 20) | ||||
| 			{ | ||||
| 				fprintf(stderr, "ldpc_tool: trials: %d%% max: %d%% at converging to a code word\n", | ||||
| 					(trials_count*100)/(num_decodes*max_trials), (max_count*100)/num_decodes); | ||||
| 				fprintf(stderr, "ldpc_tool: trials: %d%% max: %d%% at converging to a code word (max trials: %d)\n", | ||||
| 					(trials_count*100)/(num_decodes*max_trials), (max_count*100)/num_decodes, max_trials); | ||||
| 				trials_count = 0; | ||||
| 				max_count = 0; | ||||
| 				num_decodes = 0; | ||||
|  | ||||
| @ -111,13 +111,16 @@ static const int DVBS_G2 = 0133; | ||||
| template <typename Tbyte, Tbyte BYTE_ERASED> | ||||
| struct deconvol_sync : runnable | ||||
| { | ||||
|     deconvol_sync(scheduler *sch, | ||||
|     deconvol_sync( | ||||
|         scheduler *sch, | ||||
|         pipebuf<eucl_ss> &_in, | ||||
|         pipebuf<Tbyte> &_out, | ||||
|         uint32_t gX, | ||||
|         uint32_t gY, | ||||
|         uint32_t pX, | ||||
|                   uint32_t pY) : runnable(sch, "deconvol_sync"), | ||||
|         uint32_t pY | ||||
|     ) : | ||||
|         runnable(sch, "deconvol_sync"), | ||||
|         fastlock(false), | ||||
|         in(_in), | ||||
|         out(_out, SIZE_RSPACKET), | ||||
| @ -151,6 +154,14 @@ struct deconvol_sync : runnable | ||||
|         locked = &syncs[0]; | ||||
|     } | ||||
| 
 | ||||
|     ~deconvol_sync() | ||||
|     { | ||||
|         delete[] deconv2; | ||||
|         delete[] deconv; | ||||
|         delete[] punct; | ||||
|         delete[] conv; | ||||
|     } | ||||
| 
 | ||||
|     typedef uint64_t signal_t; | ||||
|     typedef uint64_t iq_t; | ||||
| 
 | ||||
| @ -582,7 +593,8 @@ struct deconvol_sync : runnable | ||||
| 
 | ||||
| typedef deconvol_sync<u8, 0> deconvol_sync_simple; | ||||
| 
 | ||||
| deconvol_sync_simple *make_deconvol_sync_simple(scheduler *sch, | ||||
| deconvol_sync_simple *make_deconvol_sync_simple( | ||||
|     scheduler *sch, | ||||
|     pipebuf<eucl_ss> &_in, | ||||
|     pipebuf<u8> &_out, | ||||
|     enum code_rate rate); | ||||
| @ -665,11 +677,14 @@ struct dvb_convol : runnable | ||||
|     typedef u8 uncoded_byte; | ||||
|     typedef u8 hardsymbol; | ||||
| 
 | ||||
|     dvb_convol(scheduler *sch, | ||||
|     dvb_convol( | ||||
|         scheduler *sch, | ||||
|         pipebuf<uncoded_byte> &_in, | ||||
|         pipebuf<hardsymbol> &_out, | ||||
|         code_rate fec, | ||||
|                int bits_per_symbol) : runnable(sch, "dvb_convol"), | ||||
|         int bits_per_symbol | ||||
|     ) : | ||||
|         runnable(sch, "dvb_convol"), | ||||
|         in(_in), | ||||
|         out(_out, 64) // BPSK 7/8: 7 bytes in, 64 symbols out
 | ||||
|     { | ||||
| @ -719,9 +734,12 @@ struct dvb_deconvol_sync : runnable | ||||
|     int resync_period; | ||||
|     static const int chunk_size = 64; // At least 2*sizeof(Thist)/8
 | ||||
| 
 | ||||
|     dvb_deconvol_sync(scheduler *sch, | ||||
|     dvb_deconvol_sync( | ||||
|         scheduler *sch, | ||||
|         pipebuf<Tin> &_in, | ||||
|                       pipebuf<decoded_byte> &_out) : runnable(sch, "deconvol_sync_multipoly"), | ||||
|         pipebuf<decoded_byte> &_out | ||||
|     ) : | ||||
|         runnable(sch, "deconvol_sync_multipoly"), | ||||
|         resync_period(32), | ||||
|         in(_in), | ||||
|         out(_out, chunk_size), | ||||
| @ -736,7 +754,7 @@ struct dvb_deconvol_sync : runnable | ||||
|         while (in.readable() >= chunk_size * 8 && out.writable() >= chunk_size) | ||||
|         { | ||||
|             int errors_best = 1 << 30; | ||||
|             sync_t *best = NULL; | ||||
|             sync_t *best = nullptr; | ||||
| 
 | ||||
|             for (sync_t *s = syncs; s < syncs + NSYNCS; ++s) | ||||
|             { | ||||
| @ -833,12 +851,15 @@ struct mpeg_sync : runnable | ||||
|     bool fastlock; | ||||
|     int resync_period; | ||||
| 
 | ||||
|     mpeg_sync(scheduler *sch, | ||||
|     mpeg_sync( | ||||
|         scheduler *sch, | ||||
|         pipebuf<Tbyte> &_in, | ||||
|         pipebuf<Tbyte> &_out, | ||||
|         deconvol_sync<Tbyte, 0> *_deconv, | ||||
|               pipebuf<int> *_state_out = NULL, | ||||
|               pipebuf<unsigned long> *_locktime_out = NULL) : runnable(sch, "sync_detect"), | ||||
|         pipebuf<int> *_state_out = nullptr, | ||||
|         pipebuf<unsigned long> *_locktime_out = nullptr | ||||
|     ) : | ||||
|         runnable(sch, "sync_detect"), | ||||
|         scan_syncs(8), | ||||
|         want_syncs(4), | ||||
|         lock_timeout(4), | ||||
| @ -854,8 +875,18 @@ struct mpeg_sync : runnable | ||||
|         next_sync_count(0), | ||||
|         report_state(true) | ||||
|     { | ||||
|         state_out = _state_out ? new pipewriter<int>(*_state_out) : NULL; | ||||
|         locktime_out = _locktime_out ? new pipewriter<unsigned long>(*_locktime_out) : NULL; | ||||
|         state_out = _state_out ? new pipewriter<int>(*_state_out) : nullptr; | ||||
|         locktime_out = _locktime_out ? new pipewriter<unsigned long>(*_locktime_out) : nullptr; | ||||
|     } | ||||
| 
 | ||||
|     ~mpeg_sync() | ||||
|     { | ||||
|         if (state_out) { | ||||
|             delete state_out; | ||||
|         } | ||||
|         if (locktime_out) { | ||||
|             delete locktime_out; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void run() | ||||
| @ -1096,9 +1127,12 @@ struct rspacket | ||||
| 
 | ||||
| struct interleaver : runnable | ||||
| { | ||||
|     interleaver(scheduler *sch, | ||||
|     interleaver( | ||||
|         scheduler *sch, | ||||
|         pipebuf<rspacket<u8>> &_in, | ||||
|                 pipebuf<u8> &_out) : runnable(sch, "interleaver"), | ||||
|         pipebuf<u8> &_out | ||||
|     ) : | ||||
|         runnable(sch, "interleaver"), | ||||
|         in(_in), | ||||
|         out(_out, SIZE_RSPACKET) | ||||
|     { | ||||
| @ -1112,8 +1146,7 @@ struct interleaver : runnable | ||||
|             u8 *pout = out.wr(); | ||||
|             int delay = 0; | ||||
| 
 | ||||
|             for (int i = 0; i < SIZE_RSPACKET; ++i, ++pout, delay = (delay + 1) % 12) | ||||
|             { | ||||
|             for (int i = 0; i < SIZE_RSPACKET; ++i, ++pout, delay = (delay + 1) % 12) { | ||||
|                 *pout = pin[11 - delay].data[i]; | ||||
|             } | ||||
| 
 | ||||
| @ -1133,9 +1166,12 @@ struct interleaver : runnable | ||||
| template <typename Tbyte> | ||||
| struct deinterleaver : runnable | ||||
| { | ||||
|     deinterleaver(scheduler *sch, | ||||
|     deinterleaver( | ||||
|         scheduler *sch, | ||||
|         pipebuf<Tbyte> &_in, | ||||
|                   pipebuf<rspacket<Tbyte>> &_out) : runnable(sch, "deinterleaver"), | ||||
|         pipebuf<rspacket<Tbyte>> &_out | ||||
|     ) : | ||||
|         runnable(sch, "deinterleaver"), | ||||
|         in(_in), | ||||
|         out(_out) | ||||
|     { | ||||
| @ -1148,8 +1184,7 @@ struct deinterleaver : runnable | ||||
|             Tbyte *pin = in.rd() + 17 * 11 * 12, *pend = pin + SIZE_RSPACKET; | ||||
|             Tbyte *pout = out.wr()->data; | ||||
| 
 | ||||
|             for (int delay = 17 * 11; pin < pend; ++pin, ++pout, delay = (delay - 17 + 17 * 12) % (17 * 12)) | ||||
|             { | ||||
|             for (int delay = 17 * 11; pin < pend; ++pin, ++pout, delay = (delay - 17 + 17 * 12) % (17 * 12)) { | ||||
|                 *pout = pin[-delay * 12]; | ||||
|             } | ||||
| 
 | ||||
| @ -1175,9 +1210,12 @@ struct tspacket | ||||
| 
 | ||||
| struct rs_encoder : runnable | ||||
| { | ||||
|     rs_encoder(scheduler *sch, | ||||
|     rs_encoder( | ||||
|         scheduler *sch, | ||||
|         pipebuf<tspacket> &_in, | ||||
|                pipebuf<rspacket<u8>> &_out) : runnable(sch, "RS encoder"), | ||||
|         pipebuf<rspacket<u8>> &_out | ||||
|     ) : | ||||
|         runnable(sch, "RS encoder"), | ||||
|         in(_in), | ||||
|         out(_out) | ||||
|     { | ||||
| @ -1213,16 +1251,29 @@ struct rs_decoder : runnable | ||||
| { | ||||
|     rs_engine rs; | ||||
| 
 | ||||
|     rs_decoder(scheduler *sch, | ||||
|     rs_decoder( | ||||
|         scheduler *sch, | ||||
|         pipebuf<rspacket<Tbyte>> &_in, | ||||
|         pipebuf<tspacket> &_out, | ||||
|                pipebuf<int> *_bitcount = NULL, | ||||
|                pipebuf<int> *_errcount = NULL) : runnable(sch, "RS decoder"), | ||||
|         pipebuf<int> *_bitcount = nullptr, | ||||
|         pipebuf<int> *_errcount = nullptr | ||||
|     ) : | ||||
|         runnable(sch, "RS decoder"), | ||||
|         in(_in), | ||||
|         out(_out) | ||||
|     { | ||||
|         bitcount = _bitcount ? new pipewriter<int>(*_bitcount) : NULL; | ||||
|         errcount = _errcount ? new pipewriter<int>(*_errcount) : NULL; | ||||
|         bitcount = _bitcount ? new pipewriter<int>(*_bitcount) : nullptr; | ||||
|         errcount = _errcount ? new pipewriter<int>(*_errcount) : nullptr; | ||||
|     } | ||||
| 
 | ||||
|     ~rs_decoder() | ||||
|     { | ||||
|         if (bitcount) { | ||||
|             delete bitcount; | ||||
|         } | ||||
|         if (errcount) { | ||||
|             delete errcount; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void run() | ||||
| @ -1307,9 +1358,12 @@ struct rs_decoder : runnable | ||||
| 
 | ||||
| struct randomizer : runnable | ||||
| { | ||||
|     randomizer(scheduler *sch, | ||||
|     randomizer( | ||||
|         scheduler *sch, | ||||
|         pipebuf<tspacket> &_in, | ||||
|                pipebuf<tspacket> &_out) : runnable(sch, "derandomizer"), | ||||
|         pipebuf<tspacket> &_out | ||||
|     ) : | ||||
|         runnable(sch, "derandomizer"), | ||||
|         in(_in), | ||||
|         out(_out) | ||||
|     { | ||||
| @ -1367,9 +1421,12 @@ struct randomizer : runnable | ||||
| 
 | ||||
| struct derandomizer : runnable | ||||
| { | ||||
|     derandomizer(scheduler *sch, | ||||
|     derandomizer( | ||||
|         scheduler *sch, | ||||
|         pipebuf<tspacket> &_in, | ||||
|                  pipebuf<tspacket> &_out) : runnable(sch, "derandomizer"), | ||||
|         pipebuf<tspacket> &_out | ||||
|     ) : | ||||
|         runnable(sch, "derandomizer"), | ||||
|         in(_in), | ||||
|         out(_out) | ||||
|     { | ||||
| @ -1525,11 +1582,14 @@ struct viterbi_sync : runnable | ||||
|   public: | ||||
|     int resync_period; | ||||
| 
 | ||||
|     viterbi_sync(scheduler *sch, | ||||
|     viterbi_sync( | ||||
|         scheduler *sch, | ||||
|         pipebuf<eucl_ss> &_in, | ||||
|         pipebuf<unsigned char> &_out, | ||||
|         cstln_lut<eucl_ss, 256> *_cstln, | ||||
|                  code_rate cr) : runnable(sch, "viterbi_sync"), | ||||
|         code_rate cr | ||||
|     ) : | ||||
|         runnable(sch, "viterbi_sync"), | ||||
|         in(_in), | ||||
|         out(_out, chunk_size), | ||||
|         cstln(_cstln), | ||||
| @ -1659,6 +1719,11 @@ struct viterbi_sync : runnable | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     ~viterbi_sync() | ||||
|     { | ||||
|         delete syncs; | ||||
|     } | ||||
| 
 | ||||
|     TCS *init_map(bool conj, float angle) | ||||
|     { | ||||
|         // Each constellation has its own pattern for labels.
 | ||||
|  | ||||
| @ -299,11 +299,14 @@ const modcod_info *check_modcod(int m) | ||||
| template <typename T> | ||||
| struct s2_frame_transmitter : runnable | ||||
| { | ||||
|     s2_frame_transmitter(scheduler *sch, | ||||
|     s2_frame_transmitter( | ||||
|         scheduler *sch, | ||||
|         pipebuf<plslot<hard_ss>> &_in, | ||||
|                          pipebuf<complex<T>> &_out) | ||||
|         : runnable(sch, "S2 frame transmitter"), | ||||
|           in(_in), out(_out, modcod_info::MAX_SYMBOLS_PER_FRAME) | ||||
|         pipebuf<complex<T>> &_out | ||||
|     ) : | ||||
|         runnable(sch, "S2 frame transmitter"), | ||||
|         in(_in), | ||||
|         out(_out, modcod_info::MAX_SYMBOLS_PER_FRAME) | ||||
|     { | ||||
|         float amp = cstln_amp / sqrtf(2); | ||||
|         qsymbols[0].re = +amp; | ||||
| @ -437,15 +440,36 @@ static int pl_errors = 0, pl_symbols = 0; | ||||
| template <typename T, typename SOFTSYMB> | ||||
| struct s2_frame_receiver : runnable | ||||
| { | ||||
|     enum { | ||||
|         COARSE_FREQ, | ||||
|         FRAME_SEARCH, | ||||
|         FRAME_LOCKED, | ||||
|     } state; | ||||
| 
 | ||||
|     sampler_interface<T> *sampler; | ||||
|     int meas_decimation; | ||||
|     float Ftune; // Tuning bias in cycles per symbol
 | ||||
|     float Fm;    // Baud rate in Hz, for debug messages only. TBD remove.
 | ||||
|     bool strongpls; | ||||
|     float min_freqw16, max_freqw16; | ||||
| 
 | ||||
|     // State during COARSE_FREQ
 | ||||
|     complex<float> diffcorr; | ||||
|     int coarse_count; | ||||
| 
 | ||||
|     // State during FRAME_SEARCH and FRAME_LOCKED
 | ||||
|     float freqw16; // Carrier frequency initialized by COARSE_FREQ
 | ||||
|     float phase16; // Estimated phase of carrier at next symbol
 | ||||
| 
 | ||||
|     float mu;    // Time to next symbol, in samples
 | ||||
|     float omega0; // Samples per symbol
 | ||||
| 
 | ||||
|     static const int MAX_SYMBOLS_PER_FRAME = | ||||
|         (1 + modcod_info::MAX_SLOTS_PER_FRAME) * plslot<hard_ss>::LENGTH + | ||||
|         ((modcod_info::MAX_SLOTS_PER_FRAME - 1) / 16) * pilot_length; | ||||
|     s2_frame_receiver(scheduler *sch, | ||||
| 
 | ||||
|     s2_frame_receiver( | ||||
|         scheduler *sch, | ||||
|         sampler_interface<T> *_sampler, | ||||
|         pipebuf<complex<T>> &_in, | ||||
|         pipebuf<plslot<SOFTSYMB>> &_out, | ||||
| @ -455,8 +479,9 @@ struct s2_frame_receiver : runnable | ||||
|         pipebuf<complex<float>> *_cstln_out = nullptr, | ||||
|         pipebuf<complex<float>> *_cstln_pls_out = nullptr, | ||||
|         pipebuf<complex<float>> *_symbols_out = nullptr, | ||||
|                       pipebuf<int> *_state_out = nullptr) | ||||
|         : runnable(sch, "S2 frame receiver"), | ||||
|         pipebuf<int> *_state_out = nullptr | ||||
|     ) : | ||||
|         runnable(sch, "S2 frame receiver"), | ||||
|         sampler(_sampler), | ||||
|         meas_decimation(1048576), | ||||
|         Ftune(0), Fm(0), | ||||
| @ -489,25 +514,10 @@ struct s2_frame_receiver : runnable | ||||
| #endif | ||||
|     } | ||||
| 
 | ||||
|     enum | ||||
|     ~s2_frame_receiver() | ||||
|     { | ||||
|         COARSE_FREQ, | ||||
|         FRAME_SEARCH, | ||||
|         FRAME_LOCKED, | ||||
|     } state; | ||||
| 
 | ||||
|     float min_freqw16, max_freqw16; | ||||
| 
 | ||||
|     // State during COARSE_FREQ
 | ||||
|     complex<float> diffcorr; | ||||
|     int coarse_count; | ||||
| 
 | ||||
|     // State during FRAME_SEARCH and FRAME_LOCKED
 | ||||
|     float freqw16; // Carrier frequency initialized by COARSE_FREQ
 | ||||
|     float phase16; // Estimated phase of carrier at next symbol
 | ||||
| 
 | ||||
|     float mu;    // Time to next symbol, in samples
 | ||||
|     float omega0; // Samples per symbol
 | ||||
|         delete qpsk; | ||||
|     } | ||||
| 
 | ||||
|     void run() | ||||
|     { | ||||
| @ -1237,11 +1247,14 @@ struct fecframe | ||||
| 
 | ||||
| struct s2_interleaver : runnable | ||||
| { | ||||
|     s2_interleaver(scheduler *sch, | ||||
|     s2_interleaver( | ||||
|         scheduler *sch, | ||||
|         pipebuf<fecframe<hard_sb>> &_in, | ||||
|                    pipebuf<plslot<hard_ss>> &_out) | ||||
|         : runnable(sch, "S2 interleaver"), | ||||
|           in(_in), out(_out, 1 + 360) | ||||
|         pipebuf<plslot<hard_ss>> &_out | ||||
|     ) : | ||||
|         runnable(sch, "S2 interleaver"), | ||||
|         in(_in), | ||||
|         out(_out, 1 + 360) | ||||
|     { | ||||
|     } | ||||
|     void run() | ||||
| @ -1566,13 +1579,17 @@ struct s2_interleaver : runnable | ||||
| template <typename SOFTSYMB, typename SOFTBYTE> | ||||
| struct s2_deinterleaver : runnable | ||||
| { | ||||
|     s2_deinterleaver(scheduler *sch, | ||||
|     s2_deinterleaver( | ||||
|         scheduler *sch, | ||||
|         pipebuf<plslot<SOFTSYMB>> &_in, | ||||
|                      pipebuf<fecframe<SOFTBYTE>> &_out) | ||||
|         : runnable(sch, "S2 deinterleaver"), | ||||
|           in(_in), out(_out) | ||||
|         pipebuf<fecframe<SOFTBYTE>> &_out | ||||
|     ) : | ||||
|         runnable(sch, "S2 deinterleaver"), | ||||
|         in(_in), | ||||
|         out(_out) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     void run() | ||||
|     { | ||||
|         while (in.readable() >= 1 && out.writable() >= 1) | ||||
| @ -2044,10 +2061,14 @@ struct s2_bch_engines | ||||
| struct s2_fecenc : runnable | ||||
| { | ||||
|     typedef ldpc_engine<bool, hard_sb, 8, uint16_t> s2_ldpc_engine; | ||||
|     s2_fecenc(scheduler *sch, | ||||
|               pipebuf<bbframe> &_in, pipebuf<fecframe<hard_sb>> &_out) | ||||
|         : runnable(sch, "S2 fecenc"), | ||||
|           in(_in), out(_out) | ||||
|     s2_fecenc( | ||||
|         scheduler *sch, | ||||
|         pipebuf<bbframe> &_in, | ||||
|         pipebuf<fecframe<hard_sb>> &_out | ||||
|     ) : | ||||
|         runnable(sch, "S2 fecenc"), | ||||
|         in(_in), | ||||
|         out(_out) | ||||
|     { | ||||
|         if (sch->debug) | ||||
|             s2ldpc.print_node_stats(); | ||||
| @ -2097,13 +2118,16 @@ template <typename SOFTBIT, typename SOFTBYTE> | ||||
| struct s2_fecdec : runnable | ||||
| { | ||||
|     int bitflips; | ||||
|     s2_fecdec(scheduler *sch, | ||||
|     s2_fecdec( | ||||
|         scheduler *sch, | ||||
|         pipebuf<fecframe<SOFTBYTE>> &_in, pipebuf<bbframe> &_out, | ||||
|         pipebuf<int> *_bitcount = nullptr, | ||||
|               pipebuf<int> *_errcount = nullptr) | ||||
|         : runnable(sch, "S2 fecdec"), | ||||
|         pipebuf<int> *_errcount = nullptr | ||||
|     ) : | ||||
|         runnable(sch, "S2 fecdec"), | ||||
|         bitflips(0), | ||||
|           in(_in), out(_out), | ||||
|         in(_in), | ||||
|         out(_out), | ||||
|         bitcount(opt_writer(_bitcount, 1)), | ||||
|         errcount(opt_writer(_errcount, 1)) | ||||
|     { | ||||
| @ -2186,16 +2210,19 @@ struct s2_fecdec : runnable | ||||
| template <typename SOFTBIT, typename SOFTBYTE> | ||||
| struct s2_fecdec_soft : runnable | ||||
| { | ||||
|     s2_fecdec_soft(scheduler *sch, | ||||
|     s2_fecdec_soft( | ||||
|         scheduler *sch, | ||||
|         pipebuf<fecframe<SOFTBYTE>> &_in, | ||||
|         pipebuf<bbframe> &_out, | ||||
|         int _modcod, | ||||
|         bool _shortframes = true, | ||||
|         int _max_trials = 25, | ||||
|         pipebuf<int> *_bitcount = nullptr, | ||||
|                    pipebuf<int> *_errcount = nullptr) | ||||
|         : runnable(sch, "S2 fecdec soft"), | ||||
|           in(_in), out(_out), | ||||
|         pipebuf<int> *_errcount = nullptr | ||||
|     ) : | ||||
|         runnable(sch, "S2 fecdec soft"), | ||||
|         in(_in), | ||||
|         out(_out), | ||||
|         modcod(_modcod < 0 ? 0 : _modcod > 31 ? 31 : _modcod), | ||||
|         shortframes(_shortframes ? 1 : 0), | ||||
|         max_trials(_max_trials), | ||||
| @ -2357,18 +2384,21 @@ struct s2_fecdec_helper : runnable | ||||
|     bool must_buffer; | ||||
|     int max_trials; | ||||
| 
 | ||||
|     s2_fecdec_helper(scheduler *sch, | ||||
|     s2_fecdec_helper( | ||||
|         scheduler *sch, | ||||
|         pipebuf<fecframe<SOFTBYTE>> &_in, | ||||
|         pipebuf<bbframe> &_out, | ||||
|         const char *_command, | ||||
|         pipebuf<int> *_bitcount = nullptr, | ||||
|                      pipebuf<int> *_errcount = nullptr) | ||||
|         : runnable(sch, "S2 fecdec io"), | ||||
|         pipebuf<int> *_errcount = nullptr | ||||
|     ) : | ||||
|         runnable(sch, "S2 fecdec io"), | ||||
|         batch_size(16), | ||||
|         nhelpers(1), | ||||
|         must_buffer(false), | ||||
|         max_trials(8), | ||||
|           in(_in), out(_out), | ||||
|         in(_in), | ||||
|         out(_out), | ||||
|         bitcount(opt_writer(_bitcount, 1)), | ||||
|         errcount(opt_writer(_errcount, 1)) | ||||
|     { | ||||
| @ -2459,6 +2489,7 @@ struct s2_fecdec_helper : runnable | ||||
|                 lseek(h->fd_tx, 0, SEEK_SET); // allow new writes on this worker
 | ||||
|                 continue; // next worker
 | ||||
|             } | ||||
| 
 | ||||
|             if (nw < 0) | ||||
|                 fatal("write(LDPC helper"); | ||||
|             else if (nw != iosize) | ||||
| @ -2524,9 +2555,9 @@ struct s2_fecdec_helper : runnable | ||||
|                             int cs; | ||||
|                             waitpid(h->pid, &cs, 0); | ||||
|                         } | ||||
|                         // reset pipes
 | ||||
|                         lseek(h->fd_tx, 0, SEEK_SET); | ||||
|                         lseek(h->fd_rx, 0, SEEK_SET); | ||||
|                         // close pipes
 | ||||
|                         close(h->fd_tx); | ||||
|                         close(h->fd_rx); | ||||
|                     } | ||||
| 
 | ||||
|                     delete p->procs; | ||||
| @ -2638,7 +2669,7 @@ struct s2_fecdec_helper : runnable | ||||
|         } | ||||
|         else if (nr != iosize) | ||||
|         { | ||||
|             fprintf(stderr, "s2_fecdec_helper::receive_frame: %d bytes read vs %d", nr, iosize); | ||||
|             fprintf(stderr, "s2_fecdec_helper::receive_frame: %d bytes read vs %d\n", nr, iosize); | ||||
|         } | ||||
| 
 | ||||
|         --job->h->b_out; | ||||
| @ -2700,9 +2731,15 @@ struct s2_framer : runnable | ||||
| { | ||||
|     uint8_t rolloff_code; // 0=0.35, 1=0.25, 2=0.20, 3=reserved
 | ||||
|     s2_pls pls; | ||||
|     s2_framer(scheduler *sch, pipebuf<tspacket> &_in, pipebuf<bbframe> &_out) | ||||
|         : runnable(sch, "S2 framer"), | ||||
|           in(_in), out(_out) | ||||
| 
 | ||||
|     s2_framer( | ||||
|         scheduler *sch, | ||||
|         pipebuf<tspacket> &_in, | ||||
|         pipebuf<bbframe> &_out | ||||
|     ) : | ||||
|         runnable(sch, "S2 framer"), | ||||
|         in(_in), | ||||
|         out(_out) | ||||
|     { | ||||
|         pls.modcod = 4; | ||||
|         pls.sf = false; | ||||
| @ -2782,12 +2819,17 @@ struct s2_framer : runnable | ||||
| 
 | ||||
| struct s2_deframer : runnable | ||||
| { | ||||
|     s2_deframer(scheduler *sch, pipebuf<bbframe> &_in, pipebuf<tspacket> &_out, | ||||
|     s2_deframer( | ||||
|         scheduler *sch, | ||||
|         pipebuf<bbframe> &_in, | ||||
|         pipebuf<tspacket> &_out, | ||||
|         pipebuf<int> *_state_out = nullptr, | ||||
|                 pipebuf<unsigned long> *_locktime_out = nullptr) | ||||
|         : runnable(sch, "S2 deframer"), | ||||
|         pipebuf<unsigned long> *_locktime_out = nullptr | ||||
|     ) : | ||||
|         runnable(sch, "S2 deframer"), | ||||
|         missing(-1), | ||||
|           in(_in), out(_out, MAX_TS_PER_BBFRAME), | ||||
|         in(_in), | ||||
|         out(_out, MAX_TS_PER_BBFRAME), | ||||
|         current_state(false), | ||||
|         state_out(opt_writer(_state_out, 2)), | ||||
|         report_state(true), | ||||
|  | ||||
| @ -107,7 +107,7 @@ struct runnable_common | ||||
| 
 | ||||
| struct window_placement | ||||
| { | ||||
|     const char *name; // NULL to terminate
 | ||||
|     const char *name; // nullptr to terminate
 | ||||
|     int x, y, w, h; | ||||
| }; | ||||
| 
 | ||||
| @ -120,9 +120,10 @@ struct scheduler | ||||
|     window_placement *windows; | ||||
|     bool verbose, debug, debug2; | ||||
| 
 | ||||
|     scheduler() : npipes(0), | ||||
|     scheduler() : | ||||
|         npipes(0), | ||||
|         nrunnables(0), | ||||
|                   windows(NULL), | ||||
|         windows(nullptr), | ||||
|         verbose(false), | ||||
|         debug(false), | ||||
|         debug2(false) | ||||
| @ -208,22 +209,28 @@ struct pipebuf : pipebuf_common | ||||
|     T *wr; | ||||
|     T *end; | ||||
| 
 | ||||
|     int sizeofT() | ||||
|     { | ||||
|         return sizeof(T); | ||||
|     } | ||||
| 
 | ||||
|     pipebuf(scheduler *sch, const char *name, unsigned long size) : pipebuf_common(name), | ||||
|                                                                     buf(new T[size]), | ||||
|                                                                     nrd(0), wr(buf), | ||||
|                                                                     end(buf + size), | ||||
|     pipebuf(scheduler *sch, const char *name, unsigned long size) : | ||||
|         pipebuf_common(name), | ||||
|         nrd(0), | ||||
|         min_write(1), | ||||
|         total_written(0), | ||||
|         total_read(0) | ||||
|     { | ||||
|         buf = new T[size]; | ||||
|         wr = buf; | ||||
|         end = buf + size; | ||||
|         sch->add_pipe(this); | ||||
|     } | ||||
| 
 | ||||
|     ~pipebuf() | ||||
|     { | ||||
|         delete[] buf; | ||||
|     } | ||||
| 
 | ||||
|     int sizeofT() { | ||||
|         return sizeof(T); | ||||
|     } | ||||
| 
 | ||||
|     int add_reader() | ||||
|     { | ||||
|         if (nrd == MAX_READERS) | ||||
| @ -307,9 +314,8 @@ struct pipewriter | ||||
| 
 | ||||
|     void written(unsigned long n) | ||||
|     { | ||||
|         if (buf.wr + n > buf.end) | ||||
|         { | ||||
|             fprintf(stderr, "Bug: overflow to %s\n", buf.name); | ||||
|         if (buf.wr + n > buf.end) { | ||||
|             fprintf(stderr, "pipewriter::written: bug: overflow to %s\n", buf.name); | ||||
|         } | ||||
| 
 | ||||
|         buf.wr += n; | ||||
| @ -328,13 +334,13 @@ struct pipewriter | ||||
| template <typename T> | ||||
| pipewriter<T> *opt_writer(pipebuf<T> *buf, unsigned long min_write = 1) | ||||
| { | ||||
|     return buf ? new pipewriter<T>(*buf, min_write) : NULL; | ||||
|     return buf ? new pipewriter<T>(*buf, min_write) : nullptr; | ||||
| } | ||||
| 
 | ||||
| template <typename T> | ||||
| bool opt_writable(pipewriter<T> *p, int n = 1) | ||||
| { | ||||
|     return (p == NULL) || p->writable() >= n; | ||||
|     return (p == nullptr) || p->writable() >= n; | ||||
| } | ||||
| 
 | ||||
| template <typename T> | ||||
|  | ||||
| @ -48,11 +48,14 @@ struct auto_notch : runnable | ||||
|     int decimation; | ||||
|     float k; | ||||
| 
 | ||||
|     auto_notch(scheduler *sch, | ||||
|     auto_notch( | ||||
|         scheduler *sch, | ||||
|         pipebuf<complex<T>> &_in, | ||||
|         pipebuf<complex<T>> &_out, | ||||
|         int _nslots, | ||||
|                T _agc_rms_setpoint) : runnable(sch, "auto_notch"), | ||||
|         T _agc_rms_setpoint | ||||
|     ) : | ||||
|         runnable(sch, "auto_notch"), | ||||
|         decimation(1024 * 4096), | ||||
|         k(0.002), // k(0.01)
 | ||||
|         fft(4096), | ||||
| @ -74,6 +77,10 @@ struct auto_notch : runnable | ||||
| 
 | ||||
|     ~auto_notch() | ||||
|     { | ||||
|         for (int s = 0; s < nslots; ++s) { | ||||
|             delete[] __slots[s].expj; | ||||
|         } | ||||
| 
 | ||||
|         delete[] __slots; | ||||
|     } | ||||
| 
 | ||||
| @ -226,7 +233,11 @@ struct ss_estimator : runnable | ||||
|     unsigned long window_size; // Samples per estimation
 | ||||
|     unsigned long decimation;  // Output rate
 | ||||
| 
 | ||||
|     ss_estimator(scheduler *sch, pipebuf<complex<T>> &_in, pipebuf<T> &_out) : runnable(sch, "SS estimator"), | ||||
|     ss_estimator( | ||||
|         scheduler *sch, | ||||
|         pipebuf<complex<T>> &_in, pipebuf<T> &_out | ||||
|     ) : | ||||
|         runnable(sch, "SS estimator"), | ||||
|         window_size(1024), | ||||
|         decimation(1024), | ||||
|         in(_in), | ||||
| @ -268,11 +279,14 @@ struct ss_amp_estimator : runnable | ||||
|     unsigned long window_size; // Samples per estimation
 | ||||
|     unsigned long decimation;  // Output rate
 | ||||
| 
 | ||||
|     ss_amp_estimator(scheduler *sch, | ||||
|     ss_amp_estimator( | ||||
|         scheduler *sch, | ||||
|         pipebuf<complex<T>> &_in, | ||||
|         pipebuf<T> &_out_ss, | ||||
|         pipebuf<T> &_out_ampmin, | ||||
|                      pipebuf<T> &_out_ampmax) : runnable(sch, "SS estimator"), | ||||
|         pipebuf<T> &_out_ampmax | ||||
|     ) : | ||||
|         runnable(sch, "SS estimator"), | ||||
|         window_size(1024), | ||||
|         decimation(1024), | ||||
|         in(_in), | ||||
| @ -332,9 +346,12 @@ struct simple_agc : runnable | ||||
|     float estimated; // Input power
 | ||||
|     static const int chunk_size = 128; | ||||
| 
 | ||||
|     simple_agc(scheduler *sch, | ||||
|     simple_agc( | ||||
|         scheduler *sch, | ||||
|         pipebuf<complex<T>> &_in, | ||||
|                pipebuf<complex<T>> &_out) : runnable(sch, "AGC"), | ||||
|         pipebuf<complex<T>> &_out | ||||
|     ) : | ||||
|         runnable(sch, "AGC"), | ||||
|         out_rms(1), | ||||
|         bw(0.001), | ||||
|         estimated(0), | ||||
| @ -484,12 +501,16 @@ struct cstln_base | ||||
| template <typename SOFTSYMB, int R> | ||||
| struct cstln_lut : cstln_base | ||||
| { | ||||
|     cstln_lut(cstln_base::predef type, | ||||
|     cstln_lut( | ||||
|         cstln_base::predef type, | ||||
|         float mer = 10, | ||||
|         float gamma1 = 0, | ||||
|         float gamma2 = 0, | ||||
|               float gamma3 = 0) | ||||
|         float gamma3 = 0 | ||||
|     ) | ||||
|     { | ||||
|         symbols = nullptr; | ||||
| 
 | ||||
|         switch (type) | ||||
|         { | ||||
|         case BPSK: | ||||
| @ -679,6 +700,13 @@ struct cstln_lut : cstln_base | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     ~cstln_lut() | ||||
|     { | ||||
|         if (symbols) { | ||||
|             delete[] symbols; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     struct result | ||||
|     { | ||||
|         SOFTSYMB ss; | ||||
| @ -958,15 +986,21 @@ struct linear_sampler : sampler_interface<T> | ||||
| template <typename T, typename Tc> | ||||
| struct fir_sampler : sampler_interface<T> | ||||
| { | ||||
|     fir_sampler(int _ncoeffs, Tc *_coeffs, int _subsampling = 1) : ncoeffs(_ncoeffs), | ||||
|     fir_sampler(int _ncoeffs, Tc *_coeffs, int _subsampling = 1) : | ||||
|         ncoeffs(_ncoeffs), | ||||
|         coeffs(_coeffs), | ||||
|         subsampling(_subsampling), | ||||
|                                                                    shifted_coeffs(new complex<T>[ncoeffs]), | ||||
|         update_freq_phase(0) | ||||
|     { | ||||
|         shifted_coeffs = new complex<T>[ncoeffs]; | ||||
|         do_update_freq(0); // In case application never calls update_freq()
 | ||||
|     } | ||||
| 
 | ||||
|     ~fir_sampler() | ||||
|     { | ||||
|         delete[] shifted_coeffs; | ||||
|     } | ||||
| 
 | ||||
|     int readahead() | ||||
|     { | ||||
|         return ncoeffs - 1; | ||||
| @ -1050,16 +1084,19 @@ struct cstln_receiver : runnable | ||||
|     static const unsigned int chunk_size = 128; | ||||
|     float kest; | ||||
| 
 | ||||
|     cstln_receiver(scheduler *sch, | ||||
|     cstln_receiver( | ||||
|         scheduler *sch, | ||||
|         sampler_interface<T> *_sampler, | ||||
|         pipebuf<complex<T>> &_in, | ||||
|         pipebuf<SOFTSYMB> &_out, | ||||
|                    pipebuf<float> *_freq_out = NULL, | ||||
|                    pipebuf<float> *_ss_out = NULL, | ||||
|                    pipebuf<float> *_mer_out = NULL, | ||||
|                    pipebuf<cf32> *_cstln_out = NULL) : runnable(sch, "Constellation receiver"), | ||||
|         pipebuf<float> *_freq_out = nullptr, | ||||
|         pipebuf<float> *_ss_out = nullptr, | ||||
|         pipebuf<float> *_mer_out = nullptr, | ||||
|         pipebuf<cf32> *_cstln_out = nullptr | ||||
|     ) : | ||||
|         runnable(sch, "Constellation receiver"), | ||||
|         sampler(_sampler), | ||||
|                                                        cstln(NULL), | ||||
|         cstln(nullptr), | ||||
|         meas_decimation(1048576), | ||||
|         pll_adjustment(1.0), | ||||
|         allow_drift(false), | ||||
| @ -1076,10 +1113,10 @@ struct cstln_receiver : runnable | ||||
|     { | ||||
|         set_omega(1); | ||||
|         set_freq(0); | ||||
|         freq_out = _freq_out ? new pipewriter<float>(*_freq_out) : NULL; | ||||
|         ss_out = _ss_out ? new pipewriter<float>(*_ss_out) : NULL; | ||||
|         mer_out = _mer_out ? new pipewriter<float>(*_mer_out) : NULL; | ||||
|         cstln_out = _cstln_out ? new pipewriter<cf32>(*_cstln_out) : NULL; | ||||
|         freq_out = _freq_out ? new pipewriter<float>(*_freq_out) : nullptr; | ||||
|         ss_out = _ss_out ? new pipewriter<float>(*_ss_out) : nullptr; | ||||
|         mer_out = _mer_out ? new pipewriter<float>(*_mer_out) : nullptr; | ||||
|         cstln_out = _cstln_out ? new pipewriter<cf32>(*_cstln_out) : nullptr; | ||||
| 
 | ||||
|         for (int i = 0; i < 3; i++) | ||||
|         { | ||||
| @ -1088,6 +1125,22 @@ struct cstln_receiver : runnable | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     ~cstln_receiver() | ||||
|     { | ||||
|         if (freq_out) { | ||||
|             delete freq_out; | ||||
|         } | ||||
|         if (ss_out) { | ||||
|             delete ss_out; | ||||
|         } | ||||
|         if (mer_out) { | ||||
|             delete mer_out; | ||||
|         } | ||||
|         if (cstln_out) { | ||||
|             delete cstln_out; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void set_omega(float _omega, float tol = 10e-6) | ||||
|     { | ||||
|         omega = _omega; | ||||
| @ -1170,7 +1223,7 @@ struct cstln_receiver : runnable | ||||
|             // These are scoped outside the loop for SS and MER estimation.
 | ||||
|             complex<float> sg{0.0f, 0.0f}; // Symbol before AGC;
 | ||||
|             complex<float> s;  // For MER estimation and constellation viewer
 | ||||
|             complex<signed char> *cstln_point = NULL; | ||||
|             complex<signed char> *cstln_point = nullptr; | ||||
| 
 | ||||
|             while (pin < pend) | ||||
|             { | ||||
| @ -1292,8 +1345,7 @@ struct cstln_receiver : runnable | ||||
|                 if (ss_out) | ||||
|                     ss_out->write(sqrtf(est_insp)); | ||||
|                 if (mer_out) | ||||
|                     mer_out->write( | ||||
|                         est_ep ? 10 * logf(est_sp / est_ep) / logf(10) : 0); | ||||
|                     mer_out->write(est_ep ? 10 * log10f(est_sp / est_ep) : 0); | ||||
|             } | ||||
| 
 | ||||
|         } // Work to do
 | ||||
| @ -1342,11 +1394,14 @@ struct fast_qpsk_receiver : runnable | ||||
|     bool allow_drift; // Follow carrier beyond safe limits
 | ||||
|     static const unsigned int chunk_size = 128; | ||||
| 
 | ||||
|     fast_qpsk_receiver(scheduler *sch, | ||||
|     fast_qpsk_receiver( | ||||
|         scheduler *sch, | ||||
|         pipebuf<complex<T>> &_in, | ||||
|         pipebuf<hardsymbol> &_out, | ||||
|                        pipebuf<float> *_freq_out = NULL, | ||||
|                        pipebuf<complex<T>> *_cstln_out = NULL) : runnable(sch, "Fast QPSK receiver"), | ||||
|         pipebuf<float> *_freq_out = nullptr, | ||||
|         pipebuf<complex<T>> *_cstln_out = nullptr | ||||
|     ) : | ||||
|         runnable(sch, "Fast QPSK receiver"), | ||||
|         meas_decimation(1048576), | ||||
|         pll_adjustment(1.0), | ||||
|         allow_drift(false), | ||||
| @ -1358,12 +1413,22 @@ struct fast_qpsk_receiver : runnable | ||||
|     { | ||||
|         set_omega(1); | ||||
|         set_freq(0); | ||||
|         freq_out = _freq_out ? new pipewriter<float>(*_freq_out) : NULL; | ||||
|         cstln_out = _cstln_out ? new pipewriter<complex<T>>(*_cstln_out) : NULL; | ||||
|         freq_out = _freq_out ? new pipewriter<float>(*_freq_out) : nullptr; | ||||
|         cstln_out = _cstln_out ? new pipewriter<complex<T>>(*_cstln_out) : nullptr; | ||||
|         memset(hist, 0, sizeof(hist)); | ||||
|         init_lookup_tables(); | ||||
|     } | ||||
| 
 | ||||
|     ~fast_qpsk_receiver() | ||||
|     { | ||||
|         if (freq_out) { | ||||
|             delete freq_out; | ||||
|         } | ||||
|         if (cstln_out) { | ||||
|             delete cstln_out; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void set_omega(float _omega, float tol = 10e-6) | ||||
|     { | ||||
|         omega = _omega; | ||||
| @ -1621,12 +1686,15 @@ struct cstln_transmitter : runnable | ||||
| { | ||||
|     cstln_lut<hard_ss, 256> *cstln; | ||||
| 
 | ||||
|     cstln_transmitter(scheduler *sch, | ||||
|     cstln_transmitter( | ||||
|         scheduler *sch, | ||||
|         pipebuf<u8> &_in, | ||||
|                       pipebuf<complex<Tout>> &_out) : runnable(sch, "cstln_transmitter"), | ||||
|         pipebuf<complex<Tout>> &_out | ||||
|     ) : | ||||
|         runnable(sch, "cstln_transmitter"), | ||||
|         in(_in), | ||||
|         out(_out), | ||||
|                                                       cstln(0) | ||||
|         cstln(nullptr) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
| @ -1663,10 +1731,13 @@ struct cstln_transmitter : runnable | ||||
| template <typename T> | ||||
| struct rotator : runnable | ||||
| { | ||||
|     rotator(scheduler *sch, | ||||
|     rotator( | ||||
|         scheduler *sch, | ||||
|         pipebuf<complex<T>> &_in, | ||||
|         pipebuf<complex<T>> &_out, | ||||
|             float freq) : runnable(sch, "rotator"), | ||||
|         float freq | ||||
|     ) : | ||||
|         runnable(sch, "rotator"), | ||||
|         in(_in), | ||||
|         out(_out), | ||||
|         index(0) | ||||
| @ -1721,29 +1792,34 @@ struct rotator : runnable | ||||
| template <typename T> | ||||
| struct cnr_fft : runnable | ||||
| { | ||||
|     cnr_fft(scheduler *sch, | ||||
|     cnr_fft( | ||||
|         scheduler *sch, | ||||
|         pipebuf<complex<T>> &_in, | ||||
|         pipebuf<float> &_out, | ||||
|             float _bandwidth, int nfft = 4096) : runnable(sch, "cnr_fft"), | ||||
|         float _bandwidth, int nfft = 4096 | ||||
|     ) : | ||||
|         runnable(sch, "cnr_fft"), | ||||
|         bandwidth(_bandwidth), | ||||
|                                                  freq_tap(NULL), | ||||
|         freq_tap(nullptr), | ||||
|         tap_multiplier(1), | ||||
|         decimation(1048576), | ||||
|         kavg(0.1), | ||||
|         in(_in), | ||||
|         out(_out), | ||||
|         fft(nfft), | ||||
|                                                  avgpower(NULL), | ||||
|         avgpower(nullptr), | ||||
|         phase(0) | ||||
|     { | ||||
|         if (bandwidth > 0.25) | ||||
|             fail("CNR estimator requires Fsampling > 4x Fsignal"); | ||||
|     } | ||||
| 
 | ||||
|     float bandwidth; | ||||
|     float *freq_tap, tap_multiplier; | ||||
|     int decimation; | ||||
|     float kavg; | ||||
|     ~cnr_fft() | ||||
|     { | ||||
|         if (avgpower) { | ||||
|             delete[] avgpower; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void run() | ||||
|     { | ||||
| @ -1761,6 +1837,11 @@ struct cnr_fft : runnable | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     float bandwidth; | ||||
|     float *freq_tap, tap_multiplier; | ||||
|     int decimation; | ||||
|     float kavg; | ||||
| 
 | ||||
|   private: | ||||
|     void do_cnr() | ||||
|     { | ||||
| @ -1826,22 +1907,32 @@ struct cnr_fft : runnable | ||||
| template <typename T, int NFFT> | ||||
| struct spectrum : runnable | ||||
| { | ||||
|     spectrum(scheduler *sch, | ||||
|     int decimation; | ||||
|     float kavg; | ||||
|     int decim; | ||||
| 
 | ||||
|     spectrum( | ||||
|         scheduler *sch, | ||||
|         pipebuf<complex<T>> &_in, | ||||
|              pipebuf<float[NFFT]> &_out) : runnable(sch, "spectrum"), | ||||
|         pipebuf<float[NFFT]> &_out | ||||
|     ) : | ||||
|         runnable(sch, "spectrum"), | ||||
|         decimation(1048576), | ||||
|         kavg(0.1), | ||||
|         decim(1), in(_in), | ||||
|         out(_out), | ||||
|         fft(NFFT), | ||||
|                                            avgpower(NULL), | ||||
|         avgpower(nullptr), | ||||
|         phase(0) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     int decimation; | ||||
|     float kavg; | ||||
|     int decim; | ||||
|     ~spectrum() | ||||
|     { | ||||
|         if (avgpower) { | ||||
|             delete avgpower; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void run() | ||||
|     { | ||||
|  | ||||
| @ -124,6 +124,7 @@ template <typename TUS, | ||||
|           typename TPM> | ||||
| struct viterbi_dec_interface | ||||
| { | ||||
|     virtual ~viterbi_dec_interface() {} | ||||
|     virtual TUS update(TBM *costs, TPM *quality = NULL) = 0; | ||||
|     virtual TUS update(TCS s, TBM cost, TPM *quality = NULL) = 0; | ||||
| }; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user