2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								///////////////////////////////////////////////////////////////////////////////////
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Copyright (C) 2016 Edouard Griffiths, F4EXB                                   //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                                                                               //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// This program is free software; you can redistribute it and/or modify          //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// it under the terms of the GNU General Public License as published by          //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// the Free Software Foundation as version 3 of the License, or                  //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                                                                               //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// This program is distributed in the hope that it will be useful,               //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// GNU General Public License V3 for more details.                               //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                                                                               //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// You should have received a copy of the GNU General Public License             //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								///////////////////////////////////////////////////////////////////////////////////
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <QDebug> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <cassert> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <cstring> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <cmath> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <lz4.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "sdrdaemonfecbuffer.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								const  int  SDRdaemonFECBuffer : : m_sampleSize  =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								const  int  SDRdaemonFECBuffer : : m_iqSampleSize  =  2  *  m_sampleSize ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								SDRdaemonFECBuffer : : SDRdaemonFECBuffer ( uint32_t  throttlems )  : 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_frameHead ( 0 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-06 00:43:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_decoderIndexHead ( nbDecoderSlots / 2 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_curNbBlocks ( 0 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-18 00:39:35 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_minNbBlocks ( 256 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_curNbRecovery ( 0 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-18 00:39:35 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_maxNbRecovery ( 0 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_framesDecoded ( true ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_throttlemsNominal ( throttlems ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_readIndex ( 0 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_readBuffer ( 0 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_readSize ( 0 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-13 03:31:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_bufferLenSec ( 0.0f ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										m_nbReads ( 0 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										m_nbWrites ( 0 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										m_balCorrection ( 0 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									    m_balCorrLimit ( 0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									m_currentMeta . init ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-21 21:49:27 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									m_framesNbBytes  =  nbDecoderSlots  *  sizeof ( BufferFrame ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									m_wrDeltaEstimate  =  m_framesNbBytes  /  2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-13 03:31:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									m_readNbBytes  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-23 01:31:40 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_paramsCM256 . BlockBytes  =  sizeof ( ProtectedBlock ) ;  // never changes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_paramsCM256 . OriginalCount  =  m_nbOriginalBlocks ;   // never changes
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-23 19:59:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! m_cm256 . isInitialized ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_cm256_OK  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-23 19:59:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        qDebug ( )  < <  " SDRdaemonFECBuffer::SDRdaemonFECBuffer: cannot initialize CM256 library " ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_cm256_OK  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								SDRdaemonFECBuffer : : ~ SDRdaemonFECBuffer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( m_readBuffer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										delete [ ]  m_readBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  SDRdaemonFECBuffer : : initDecodeAllSlots ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    for  ( int  i  =  0 ;  i  <  nbDecoderSlots ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_decoderSlots [ i ] . m_blockCount  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_decoderSlots [ i ] . m_originalCount  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_decoderSlots [ i ] . m_recoveryCount  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_decoderSlots [ i ] . m_decoded  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-23 00:58:07 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_decoderSlots [ i ] . m_metaRetrieved  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        memset ( ( void  * )  m_decoderSlots [ i ] . m_originalBlocks ,  0 ,  m_nbOriginalBlocks  *  sizeof ( ProtectedBlock ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        memset ( ( void  * )  m_decoderSlots [ i ] . m_recoveryBlocks ,  0 ,  m_nbOriginalBlocks  *  sizeof ( ProtectedBlock ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  SDRdaemonFECBuffer : : initDecodeSlot ( int  slotIndex ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // collect stats before voiding the slot
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-18 00:39:35 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_curNbBlocks  =  m_decoderSlots [ slotIndex ] . m_blockCount ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_curNbRecovery  =  m_decoderSlots [ slotIndex ] . m_recoveryCount ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_avgNbBlocks ( m_curNbBlocks ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_avgNbRecovery ( m_curNbRecovery ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-18 00:39:35 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_framesDecoded  =  m_framesDecoded  & &  m_decoderSlots [ slotIndex ] . m_decoded ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( m_curNbBlocks  <  m_minNbBlocks )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_minNbBlocks  =  m_curNbBlocks ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( m_curNbRecovery  >  m_maxNbRecovery )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_maxNbRecovery  =  m_curNbRecovery ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // void the slot
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-18 00:39:35 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_decoderSlots [ slotIndex ] . m_blockCount  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_decoderSlots [ slotIndex ] . m_originalCount  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_decoderSlots [ slotIndex ] . m_recoveryCount  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_decoderSlots [ slotIndex ] . m_decoded  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_decoderSlots [ slotIndex ] . m_metaRetrieved  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    memset ( ( void  * )  m_decoderSlots [ slotIndex ] . m_originalBlocks ,  0 ,  m_nbOriginalBlocks  *  sizeof ( ProtectedBlock ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    memset ( ( void  * )  m_decoderSlots [ slotIndex ] . m_recoveryBlocks ,  0 ,  m_nbOriginalBlocks  *  sizeof ( ProtectedBlock ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  SDRdaemonFECBuffer : : initReadIndex ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-06 00:43:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_readIndex  =  ( ( m_decoderIndexHead  +  ( nbDecoderSlots / 2 ) )  %  nbDecoderSlots )  *  sizeof ( BufferFrame ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_wrDeltaEstimate  =  m_framesNbBytes  /  2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-13 03:31:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_nbReads  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_nbWrites  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  SDRdaemonFECBuffer : : rwCorrectionEstimate ( int  slotIndex ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( m_nbReads  > =  40 )  // check every ~1s as tick is ~50ms
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  targetPivotSlot  =  ( slotIndex  +  ( nbDecoderSlots / 2 ) )   %  nbDecoderSlots ;  // slot at half buffer opposite of current write slot
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  targetPivotIndex  =  targetPivotSlot  *  sizeof ( BufferFrame ) ;              // buffer index corresponding to start of above slot
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  normalizedReadIndex  =  ( m_readIndex  <  targetPivotIndex  ?  m_readIndex  +  nbDecoderSlots  *  sizeof ( BufferFrame )  :   m_readIndex ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												-  ( targetPivotSlot  *  sizeof ( BufferFrame ) ) ;  // normalize read index so it is positive and zero at start of pivot slot
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  dBytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        int  rwDelta  =  ( m_nbReads  *  m_readNbBytes )  -  ( m_nbWrites  *  sizeof ( BufferFrame ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( normalizedReadIndex  <  ( nbDecoderSlots /  2 )  *  sizeof ( BufferFrame ) )  // read leads
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											dBytes  =  -  normalizedReadIndex  -  rwDelta ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										else  // read lags
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											dBytes  =  ( nbDecoderSlots  *  sizeof ( BufferFrame ) )  -  normalizedReadIndex  -  rwDelta ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_balCorrection  =  ( m_balCorrection  /  4 )  +  ( dBytes  /  ( int )  ( m_iqSampleSize  *  m_nbReads ) ) ;  // correction is in number of samples. Alpha = 0.25
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( m_balCorrection  <  - m_balCorrLimit )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            m_balCorrection  =  - m_balCorrLimit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else  if  ( m_balCorrection  >  m_balCorrLimit )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            m_balCorrection  =  m_balCorrLimit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        float  rwRatio  =  ( float )  ( m_nbWrites  *  sizeof ( BufferFrame ) )  /  ( float )   ( m_nbReads  *  m_readNbBytes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-15 19:44:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//        qDebug() << "SDRdaemonFECBuffer::rwCorrectionEstimate: "
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                << " m_nbReads: " << m_nbReads
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                << " m_nbWrites: " << m_nbWrites
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                << " rwDelta: " << rwDelta
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                << " targetPivotSlot: " << targetPivotSlot
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                << " targetPivotIndex: " << targetPivotIndex
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                << " m_readIndex: " << m_readIndex
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                << " normalizedReadIndex: " << normalizedReadIndex
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                << " dBytes: " << dBytes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                << " m_balCorrection: " << m_balCorrection;
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-13 03:31:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										//m_balCorrection = dBytes / (int) (m_iqSampleSize * m_nbReads);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									    m_nbReads  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									    m_nbWrites  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-06 02:54:01 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  SDRdaemonFECBuffer : : checkSlotData ( int  slotIndex ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 08:52:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    int  pseudoWriteIndex  =  slotIndex  *  sizeof ( BufferFrame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m_wrDeltaEstimate  =  pseudoWriteIndex  -  m_readIndex ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-13 03:31:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_nbWrites + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 08:52:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-06 02:54:01 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! m_decoderSlots [ slotIndex ] . m_decoded ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        qDebug ( )  < <  " SDRdaemonFECBuffer::checkSlotData: incomplete frame: " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                < <  "  m_blockCount:  "  < <  m_decoderSlots [ slotIndex ] . m_blockCount 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                < <  "  m_recoveryCount:  "  < <  m_decoderSlots [ slotIndex ] . m_recoveryCount ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // copy retrieved data to main buffer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    memcpy ( ( void  * )  & m_frames [ slotIndex ] . m_blocks [ 0 ] ,  ( const  void  * )  & m_decoderSlots [ slotIndex ] . m_originalBlocks [ 1 ] ,  ( m_nbOriginalBlocks  -  1 ) * sizeof ( ProtectedBlock ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  SDRdaemonFECBuffer : : writeData ( char  * array ,  uint32_t  length ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    SuperBlock  * superBlock  =  ( SuperBlock  * )  array ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  frameIndex  =  superBlock - > header . frameIndex ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  decoderIndex  =  frameIndex  %  nbDecoderSlots ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // frame break
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( m_frameHead  = =  - 1 )  // initial state
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_decoderIndexHead  =  decoderIndex ;  // new decoder slot head
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_frameHead  =  frameIndex ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        initReadIndex ( ) ;  // reset read index
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        initDecodeAllSlots ( ) ;  // initialize all slots
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  if  ( m_frameHead  ! =  frameIndex )  // frame break => new frame starts
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_decoderIndexHead  =  decoderIndex ;  // new decoder slot head
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_frameHead  =  frameIndex ;           // new frame head
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        checkSlotData ( decoderIndex ) ;        // check slot before re-init
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        rwCorrectionEstimate ( decoderIndex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        initDecodeSlot ( decoderIndex ) ;       // collect stats and re-initialize current slot
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-15 19:44:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // Block processing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( m_decoderSlots [ decoderIndex ] . m_blockCount  <  m_nbOriginalBlocks )  // not enough blocks to decode -> store data
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        int  blockIndex  =  superBlock - > header . blockIndex ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        int  blockCount  =  m_decoderSlots [ decoderIndex ] . m_blockCount ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        int  recoveryCount  =  m_decoderSlots [ decoderIndex ] . m_recoveryCount ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks [ blockCount ] . Index  =  blockIndex ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( blockIndex  = =  0 )  // first block with meta
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            m_decoderSlots [ decoderIndex ] . m_metaRetrieved  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( blockIndex  <  m_nbOriginalBlocks )  // original data
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            m_decoderSlots [ decoderIndex ] . m_originalBlocks [ blockIndex ]  =  superBlock - > protectedBlock ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks [ blockCount ] . Block  =  ( void  * )  & m_decoderSlots [ decoderIndex ] . m_originalBlocks [ blockIndex ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            m_decoderSlots [ decoderIndex ] . m_originalCount + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        else  // recovery data
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ recoveryCount ]  =  superBlock - > protectedBlock ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks [ blockCount ] . Block  =  ( void  * )  & m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ recoveryCount ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            m_decoderSlots [ decoderIndex ] . m_recoveryCount + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-15 19:44:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_decoderSlots [ decoderIndex ] . m_blockCount + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( m_decoderSlots [ decoderIndex ] . m_blockCount  = =  m_nbOriginalBlocks )  // ready to decode
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_decoderSlots [ decoderIndex ] . m_decoded  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( m_cm256_OK  & &  ( m_decoderSlots [ decoderIndex ] . m_recoveryCount  >  0 ) )  // recovery data used => need to decode FEC
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-15 19:44:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            m_paramsCM256 . BlockBytes  =  sizeof ( ProtectedBlock ) ;  // never changes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            m_paramsCM256 . OriginalCount  =  m_nbOriginalBlocks ;   // never changes
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-15 19:44:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( m_decoderSlots [ decoderIndex ] . m_metaRetrieved )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                m_paramsCM256 . RecoveryCount  =  m_currentMeta . m_nbFECBlocks ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                m_paramsCM256 . RecoveryCount  =  m_decoderSlots [ decoderIndex ] . m_recoveryCount ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-23 19:59:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( m_cm256 . cm256_decode ( m_paramsCM256 ,  m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks ) )  // CM256 decode
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                qDebug ( )  < <  " SDRdaemonFECBuffer::writeData: decode CM256 error: " 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                        < <  "  m_originalCount:  "  < <  m_decoderSlots [ decoderIndex ] . m_originalCount 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                        < <  "  m_recoveryCount:  "  < <  m_decoderSlots [ decoderIndex ] . m_recoveryCount ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            else 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                qDebug ( )  < <  " SDRdaemonFECBuffer::writeData: decode CM256 success: " 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                        < <  "  m_originalCount:  "  < <  m_decoderSlots [ decoderIndex ] . m_originalCount 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                        < <  "  m_recoveryCount:  "  < <  m_decoderSlots [ decoderIndex ] . m_recoveryCount ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                for  ( int  ir  =  0 ;  ir  <  m_decoderSlots [ decoderIndex ] . m_recoveryCount ;  ir + + )  // restore missing blocks
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    int  recoveryIndex  =  m_nbOriginalBlocks  -  m_decoderSlots [ decoderIndex ] . m_recoveryCount  +  ir ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    int  blockIndex  =  m_decoderSlots [ decoderIndex ] . m_cm256DescriptorBlocks [ recoveryIndex ] . Index ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    if  ( blockIndex  = =  0 )  // first block with meta
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                        m_decoderSlots [ decoderIndex ] . m_metaRetrieved  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-20 08:54:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    qDebug ( )  < <  " SDRdaemonFECBuffer::writeData: recovered block # "  < <  blockIndex 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                            < <  "  i[0]:  "  < <  m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ ir ] . samples [ 0 ] . i 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                            < <  "  q[0]:  "  < <  m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ ir ] . samples [ 0 ] . q 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                            < <  "  i[1]:  "  < <  m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ ir ] . samples [ 1 ] . i 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                            < <  "  q[1]:  "  < <  m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ ir ] . samples [ 1 ] . q 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                            < <  "  i[2]:  "  < <  m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ ir ] . samples [ 2 ] . i 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                            < <  "  q[2]:  "  < <  m_decoderSlots [ decoderIndex ] . m_recoveryBlocks [ ir ] . samples [ 2 ] . q ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                }  // restore missing blocks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            }  // CM256 decode
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        }  // revovery
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-17 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( m_decoderSlots [ decoderIndex ] . m_metaRetrieved )  // block zero with its meta data has been received
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            MetaDataFEC  * metaData  =  ( MetaDataFEC  * )  & m_decoderSlots [ decoderIndex ] . m_originalBlocks [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( ! ( * metaData  = =  m_currentMeta ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                int  sampleRate  =   metaData - > m_sampleRate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                if  ( sampleRate  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    m_bufferLenSec  =  ( float )  m_framesNbBytes  /  ( float )  ( sampleRate  *  m_iqSampleSize ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    m_balCorrLimit  =  sampleRate  /  1000 ;  // +/- 1 ms correction max per read
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    m_readNbBytes  =  ( sampleRate  *  m_iqSampleSize )  /  20 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                printMeta ( " SDRdaemonFECBuffer::writeData: new meta " ,  metaData ) ;  // print for change other than timestamp
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            m_currentMeta  =  * metaData ;  // renew current meta
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  // check block 0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  // decode
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:36:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  SDRdaemonFECBuffer : : writeData0 ( char  * array ,  uint32_t  length ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//    assert(length == m_udpPayloadSize);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    bool dataAvailable = false;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    SuperBlock *superBlock = (SuperBlock *) array;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    int frameIndex = superBlock->header.frameIndex;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    int decoderIndex = frameIndex % nbDecoderSlots;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    int blockIndex = superBlock->header.blockIndex;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////    qDebug() << "SDRdaemonFECBuffer::writeData:"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////            << " frameIndex: " << frameIndex
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////            << " decoderIndex: " << decoderIndex
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////            << " blockIndex: " << blockIndex;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    if (m_frameHead == -1) // initial state
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        m_decoderIndexHead = decoderIndex; // new decoder slot head
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        m_frameHead = frameIndex;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        initReadIndex(); // reset read index
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        initDecodeAllSlots(); // initialize all slots
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    else
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        int frameDelta = m_frameHead - frameIndex;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        if (frameDelta < 0)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            if (-frameDelta < nbDecoderSlots) // new frame head not too new
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                //qDebug() << "SDRdaemonFECBuffer::writeData: new frame head (1): " << frameIndex << ":" << frameDelta << ":" << decoderIndex;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                m_decoderIndexHead = decoderIndex; // new decoder slot head
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                m_frameHead = frameIndex;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                checkSlotData(decoderIndex);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                dataAvailable = true;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                initDecodeSlot(decoderIndex); // collect stats and re-initialize current slot
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            else if (-frameDelta <= 65536 - nbDecoderSlots) // loss of sync start over
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                //qDebug() << "SDRdaemonFECBuffer::writeData: loss of sync start over (1)" << frameIndex << ":" << frameDelta << ":" << decoderIndex;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                m_decoderIndexHead = decoderIndex; // new decoder slot head
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                m_frameHead = frameIndex;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                initReadIndex(); // reset read index
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                initDecodeAllSlots(); // re-initialize all slots
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        else
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:54:23 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//        {
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//            if (frameDelta > 65536 - nbDecoderSlots) // new frame head not too new
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:54:23 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//            {
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//                //qDebug() << "SDRdaemonFECBuffer::writeData: new frame head (2): " << frameIndex << ":" << frameDelta << ":" << decoderIndex;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                m_decoderIndexHead = decoderIndex; // new decoder slot head
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                m_frameHead = frameIndex;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                checkSlotData(decoderIndex);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                dataAvailable = true;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                initDecodeSlot(decoderIndex); // collect stats and re-initialize current slot
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            else if (frameDelta >= nbDecoderSlots) // loss of sync start over
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                //qDebug() << "SDRdaemonFECBuffer::writeData: loss of sync start over (2)" << frameIndex << ":" << frameDelta << ":" << decoderIndex;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                m_decoderIndexHead = decoderIndex; // new decoder slot head
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                m_frameHead = frameIndex;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                initReadIndex(); // reset read index
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                initDecodeAllSlots(); // re-initialize all slots
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    }
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:54:23 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//    // decoderIndex should now be correctly set
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    int blockHead = m_decoderSlots[decoderIndex].m_blockCount;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    int recoveryHead = m_decoderSlots[decoderIndex].m_recoveryCount;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    if (blockHead < m_nbOriginalBlocks) // not enough blocks to decode -> store data
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        if (blockIndex == 0) // first block with meta
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////            ProtectedBlockZero *blockZero = (ProtectedBlockZero *) &superBlock->protectedBlock;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////            m_decoderSlots[decoderIndex].m_blockZero = *blockZero;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            m_decoderSlots[decoderIndex].m_cm256DescriptorBlocks[blockHead].Block = (void *) &m_decoderSlots[decoderIndex].m_blockZero;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            m_decoderSlots[decoderIndex].m_metaRetrieved = true;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        else if (blockIndex < m_nbOriginalBlocks) // normal block
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            m_frames[decoderIndex].m_blocks[blockIndex - 1] = superBlock->protectedBlock;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            m_decoderSlots[decoderIndex].m_cm256DescriptorBlocks[blockHead].Block = (void *) &m_frames[decoderIndex].m_blocks[blockIndex - 1];
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        else // redundancy block
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            m_decoderSlots[decoderIndex].m_recoveryBlocks[recoveryHead] = superBlock->protectedBlock;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            m_decoderSlots[decoderIndex].m_cm256DescriptorBlocks[blockHead].Block = (void *) &m_decoderSlots[decoderIndex].m_recoveryBlocks[recoveryHead];
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            m_decoderSlots[decoderIndex].m_recoveryCount++;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        }
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:54:23 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//        m_decoderSlots[decoderIndex].m_cm256DescriptorBlocks[blockHead].Index = blockIndex;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        m_decoderSlots[decoderIndex].m_blockCount++;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    else if (!m_decoderSlots[decoderIndex].m_decoded) // ready to decode
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        if (m_decoderSlots[decoderIndex].m_recoveryCount > 0) // recovery data used
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            if (m_decoderSlots[decoderIndex].m_metaRetrieved) // block zero with its meta data has been received
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////                m_paramsCM256.RecoveryCount = m_decoderSlots[decoderIndex].m_blockZero.m_metaData.m_nbFECBlocks;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            else
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                m_paramsCM256.RecoveryCount = m_currentMeta.m_nbFECBlocks; // take last stored value for number of FEC blocks
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:54:23 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//            }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//            if (cm256_decode(m_paramsCM256, m_decoderSlots[decoderIndex].m_cm256DescriptorBlocks)) // failure to decode
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                qDebug() << "SDRdaemonFECBuffer::writeData: CM256 decode error:"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                        << " BlockBytes: " << m_paramsCM256.BlockBytes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                        << " OriginalCount: " << m_paramsCM256.OriginalCount
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                        << " RecoveryCount: " << m_paramsCM256.RecoveryCount
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                        << " m_recoveryCount: " << m_decoderSlots[decoderIndex].m_recoveryCount;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            else // success to decode
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                int nbOriginalBlocks = m_decoderSlots[decoderIndex].m_blockCount - m_decoderSlots[decoderIndex].m_recoveryCount;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                qDebug() << "SDRdaemonFECBuffer::writeData: CM256 decode success:"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                        << " nbOriginalBlocks: " << nbOriginalBlocks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                        << " m_recoveryCount: " << m_decoderSlots[decoderIndex].m_recoveryCount;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                for (int ir = 0; ir < m_decoderSlots[decoderIndex].m_recoveryCount; ir++) // recover lost blocks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                    int blockIndex = m_decoderSlots[decoderIndex].m_cm256DescriptorBlocks[nbOriginalBlocks+ir].Index;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                    if (blockIndex == 0)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                    {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////                        ProtectedBlockZero *recoveredBlockZero = (ProtectedBlockZero *) &m_decoderSlots[decoderIndex].m_recoveryBlocks[ir];
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////                        printMeta("SDRdaemonFECBuffer::writeData: recovered meta", &recoveredBlockZero->m_metaData);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                        // FEC does not work
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////                        m_decoderSlots[decoderIndex].m_blockZero.m_metaData = recoveredBlockZero->m_metaData;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////                        m_decoderSlots[decoderIndex].m_metaRetrieved = true;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                    }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                    else
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                    {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                        m_frames[decoderIndex].m_blocks[blockIndex - 1] =  m_decoderSlots[decoderIndex].m_recoveryBlocks[ir];
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                    }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                    qDebug() << "SDRdaemonFECBuffer::writeData:"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                            << " recovered block #" << blockIndex
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                            << " i[0]: " << m_decoderSlots[decoderIndex].m_recoveryBlocks[ir].samples[0].i
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                            << " q[0]: " << m_decoderSlots[decoderIndex].m_recoveryBlocks[ir].samples[0].q;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//                }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//            }
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 02:54:23 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//        }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 03:49:47 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								//        //printMeta("SDRdaemonFECBuffer::writeData", &m_decoderSlots[decoderIndex].m_blockZero.m_metaData);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////        if (m_decoderSlots[decoderIndex].m_metaRetrieved) // meta data has been retrieved (direct or recovery)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////        {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////            if (!(m_decoderSlots[decoderIndex].m_blockZero.m_metaData == m_currentMeta))
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////            {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////                int sampleRate =  m_decoderSlots[decoderIndex].m_blockZero.m_metaData.m_sampleRate;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////                if (sampleRate > 0) {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////                    m_bufferLenSec = (float) m_framesNbBytes / (float) sampleRate;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////                }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////                printMeta("SDRdaemonFECBuffer::writeData: new meta", &m_decoderSlots[decoderIndex].m_blockZero.m_metaData); // print for change other than timestamp
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////            }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////            m_currentMeta = m_decoderSlots[decoderIndex].m_blockZero.m_metaData; // renew current meta
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////        }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								////
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//        m_decoderSlots[decoderIndex].m_decoded = true;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//    }
 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								uint8_t  * SDRdaemonFECBuffer : : readData ( int32_t  length ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    uint8_t  * buffer  =  ( uint8_t  * )  m_frames ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    uint32_t  readIndex  =  m_readIndex ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-13 03:31:19 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    m_nbReads + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( m_readIndex  +  length  <  m_framesNbBytes )  // ends before buffer bound
 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_readIndex  + =  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  & buffer [ readIndex ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    else  if  ( m_readIndex  +  length  = =  m_framesNbBytes )  // ends at buffer bound
 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        m_readIndex  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  & buffer [ readIndex ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    else  // ends after buffer bound
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( length  >  m_readSize )  // reallocate composition buffer if necessary
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( m_readBuffer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                delete [ ]  m_readBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            m_readBuffer  =  new  uint8_t [ length ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            m_readSize  =  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        std : : memcpy ( ( void  * )  m_readBuffer ,  ( const  void  * )  & buffer [ m_readIndex ] ,  m_framesNbBytes  -  m_readIndex ) ;  // copy end of buffer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        length  - =  m_framesNbBytes  -  m_readIndex ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        std : : memcpy ( ( void  * )  & m_readBuffer [ m_framesNbBytes  -  m_readIndex ] ,  ( const  void  * )  buffer ,  length ) ;  // copy start of buffer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m_readIndex  =  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  m_readBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  SDRdaemonFECBuffer : : printMeta ( const  QString &  header ,  MetaDataFEC  * metaData ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									qDebug ( )  < <  header  < <  " :  " 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-20 00:45:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            < <  " | "  < <  metaData - > m_centerFrequency 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            < <  " : "  < <  metaData - > m_sampleRate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            < <  " : "  < <  ( int )  ( metaData - > m_sampleBytes  &  0xF ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            < <  " : "  < <  ( int )  metaData - > m_sampleBits 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            < <  " : "  < <  ( int )  metaData - > m_nbOriginalBlocks 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            < <  " : "  < <  ( int )  metaData - > m_nbFECBlocks 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            < <  " | "  < <  metaData - > m_tv_sec 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            < <  " : "  < <  metaData - > m_tv_usec 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            < <  " | " ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-19 09:56:49 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								}