kopia lustrzana https://github.com/f4exb/sdrangel
				
				
				
			
		
			
				
	
	
		
			173 wiersze
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			173 wiersze
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
| ///////////////////////////////////////////////////////////////////////////////////////
 | |
| // Copyright (C) 2021 Jon Beniston, M7RCE <jon@beniston.com>                         //
 | |
| //                                                                                   //
 | |
| // 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                      //
 | |
| // (at your option) any later version.                                               //
 | |
| //                                                                                   //
 | |
| // 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 "memory.h"
 | |
| #include "DVBS2.h"
 | |
| 
 | |
| //
 | |
| // called at the end of a frame
 | |
| //
 | |
| void  DVBS2::end_of_frame_actions(void)
 | |
| {
 | |
|     if( m_s2_config_updated )
 | |
|     {
 | |
|         modulator_configuration();
 | |
|         m_s2_config_updated = 0;
 | |
|     }
 | |
| }
 | |
| 
 | |
| int DVBS2::is_valid( int mod, int coderate )
 | |
| {
 | |
|     if( mod == M_QPSK )
 | |
|     {
 | |
|         if(coderate == CR_1_4)  return 0;
 | |
|         if(coderate == CR_1_3)  return 0;
 | |
|         if(coderate == CR_2_5)  return 0;
 | |
|         if(coderate == CR_1_2)  return 0;
 | |
|         if(coderate == CR_3_5)  return 0;
 | |
|         if(coderate == CR_2_3)  return 0;
 | |
|         if(coderate == CR_3_4)  return 0;
 | |
|         if(coderate == CR_4_5)  return 0;
 | |
|         if(coderate == CR_5_6)  return 0;
 | |
|         if(coderate == CR_8_9)  return 0;
 | |
|         if(coderate == CR_9_10) return 0;
 | |
|     }
 | |
|     if( mod == M_8PSK )
 | |
|     {
 | |
|         if(coderate == CR_3_5)  return 0;
 | |
|         if(coderate == CR_2_3)  return 0;
 | |
|         if(coderate == CR_3_4)  return 0;
 | |
|         if(coderate == CR_5_6)  return 0;
 | |
|         if(coderate == CR_8_9)  return 0;
 | |
|         if(coderate == CR_9_10) return 0;
 | |
|     }
 | |
|     if( mod == M_16APSK )
 | |
|     {
 | |
|         if(coderate == CR_2_3)  return 0;
 | |
|         if(coderate == CR_3_4)  return 0;
 | |
|         if(coderate == CR_4_5)  return 0;
 | |
|         if(coderate == CR_5_6)  return 0;
 | |
|         if(coderate == CR_8_9)  return 0;
 | |
|         if(coderate == CR_9_10) return 0;
 | |
|     }
 | |
|     if( mod == M_32APSK )
 | |
|     {
 | |
|         if(coderate == CR_3_4)  return 0;
 | |
|         if(coderate == CR_4_5)  return 0;
 | |
|         if(coderate == CR_5_6)  return 0;
 | |
|         if(coderate == CR_8_9)  return 0;
 | |
|         if(coderate == CR_9_10) return 0;
 | |
|     }
 | |
|     return -1;
 | |
| }
 | |
| //
 | |
| // index 0 and 1 will only be different when being reconfigured.
 | |
| // Use index 1 as this will be applied in the following transmit
 | |
| // frames
 | |
| //
 | |
| void DVBS2::calc_efficiency( void )
 | |
| {
 | |
|     double p,m,a,s,b,po;
 | |
|     // Calculate the number of symbols in the payload
 | |
|     p = 0;a = 0; m = 0;
 | |
|     if( m_format[1].frame_type == FRAME_NORMAL )  p = (double)FRAME_SIZE_NORMAL;
 | |
|     if( m_format[1].frame_type == FRAME_SHORT  )  p = (double)FRAME_SIZE_SHORT;
 | |
|     if( m_format[1].constellation == M_QPSK )     m = 2.0;
 | |
|     if( m_format[1].constellation == M_8PSK )     m = 3.0;
 | |
|     if( m_format[1].constellation == M_16APSK )   m = 4.0;
 | |
|     if( m_format[1].constellation == M_32APSK )   m = 5.0;
 | |
|     s = p/m;//Number of symbols per frame
 | |
|     // PL header overhead
 | |
|     if( m_format[1].pilots )
 | |
|     {
 | |
|         po = (s/(90*16))-1;// 1 pilot every 16 blocks (of 90 symbols)
 | |
|         po = po*36;        // No pilot at the end
 | |
|         a  = s/(90+po+s);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         a = s/(90+s);// No pilots
 | |
|     }
 | |
|     // Modulation efficiency
 | |
|     a = a*m;
 | |
|     // Take into account pilot symbols
 | |
|     // TBD
 | |
|     // Now calculate the usable data as percentage of the frame
 | |
|     b = ((double)m_format[1].useable_data_bits)/p;
 | |
|     // Now calculate the efficiency by multiplying the
 | |
|     // usable bits efficiency by the modulation efficiency
 | |
|     m_efficiency = b*a;
 | |
| }
 | |
| //
 | |
| // Multiply the efficiency value by the symbol rate
 | |
| // to get the usable bitrate
 | |
| //
 | |
| double DVBS2::s2_get_efficiency( void )
 | |
| {
 | |
|     return m_efficiency;
 | |
| }
 | |
| 
 | |
| int DVBS2::s2_set_configure( DVB2FrameFormat *f )
 | |
| {
 | |
|     if( is_valid( f->constellation, f->code_rate ) == 0 )
 | |
|     {
 | |
|         if( set_configure( f ) == 0 )
 | |
|         {
 | |
|              calc_efficiency();
 | |
|              m_s2_config_updated = 1;
 | |
| 			 m_configured = 1;
 | |
| 
 | |
|              return 0;
 | |
|         }
 | |
|     }
 | |
|     return -1;
 | |
| }
 | |
| void DVBS2::s2_get_configure( DVB2FrameFormat *f )
 | |
| {
 | |
|     get_configure( f );
 | |
| }
 | |
| int DVBS2::s2_add_ts_frame( u8 *ts )
 | |
| {
 | |
|     int res = 0;
 | |
| 	if (m_configured == 0) return 0;
 | |
|     // Call base class
 | |
|     if( next_ts_frame_base( ts ) )
 | |
|     {
 | |
|         // Interleave and pack
 | |
|         s2_interleave();
 | |
|         // create the header
 | |
|         s2_pl_header_create();
 | |
|         // Add the data
 | |
|         res = s2_pl_data_pack();
 | |
|         // Do any updates required for the next frame
 | |
|         end_of_frame_actions();
 | |
|     }
 | |
|     return res;
 | |
| }
 | |
| void DVBS2::physical( void )
 | |
| {
 | |
| 
 | |
| }
 | |
| 
 | |
| DVBS2::DVBS2()
 | |
| {
 | |
| 	m_configured = 0;
 | |
|     modulator_configuration();
 | |
|     build_symbol_scrambler_table();
 | |
|     pl_build_dummy();
 | |
| }
 | |
| 
 |