kopia lustrzana https://github.com/f4exb/sdrangel
				
				
				
			
		
			
				
	
	
		
			288 wiersze
		
	
	
		
			8.7 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			288 wiersze
		
	
	
		
			8.7 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 "DVB2.h"
 | |
| 
 | |
| 
 | |
| //
 | |
| // Update working parameters for the next frame
 | |
| // This prevents parameters changing during a frame
 | |
| //
 | |
| void DVB2::base_end_of_frame_actions(void)
 | |
| {
 | |
|     if( m_params_changed )
 | |
|     {
 | |
|         m_format[0] = m_format[1];
 | |
|         ldpc_lookup_generate();
 | |
|         m_params_changed = 0;
 | |
|     }
 | |
|     // reset the pointer
 | |
|     m_frame_offset_bits = 0;
 | |
| }
 | |
| 
 | |
| //
 | |
| // This configures the system and calculates
 | |
| // any required intermediate values
 | |
| //
 | |
| int DVB2::set_configure( DVB2FrameFormat *f )
 | |
| {
 | |
|     int bch_bits = 0;
 | |
|     int error = 0;
 | |
| 
 | |
|     if( f->broadcasting )
 | |
|     {
 | |
|         // Set standard parameters for broadcasting
 | |
|         f->frame_type        = FRAME_NORMAL;
 | |
|         f->bb_header.ts_gs   = TS_GS_TRANSPORT;
 | |
|         f->bb_header.sis_mis = SIS_MIS_SINGLE;
 | |
|         f->bb_header.ccm_acm = CCM;
 | |
|         f->bb_header.issyi   = 0;
 | |
|         f->bb_header.npd     = 0;
 | |
|         f->bb_header.upl     = 188*8;
 | |
|         f->bb_header.sync    = 0x47;
 | |
|     }
 | |
|     f->bb_header.ro = f->roll_off;
 | |
|     // Fill in the mode specific values and bit lengths
 | |
|     if( f->frame_type == FRAME_NORMAL )
 | |
|     {
 | |
|         f->nldpc = 64800;
 | |
|         bch_bits = 192;
 | |
|         f->bch_code = BCH_CODE_N12;
 | |
|         // Apply code rate
 | |
|         switch(f->code_rate )
 | |
|         {
 | |
|             case CR_1_4:
 | |
|                 f->q_val = 135;
 | |
|                 f->kbch  = 16008;
 | |
|                 f->bch_code = BCH_CODE_N12;
 | |
|                 break;
 | |
|             case CR_1_3:
 | |
|                 f->q_val = 120;
 | |
|                 f->kbch  = 21408;
 | |
|                 f->bch_code = BCH_CODE_N12;
 | |
|                 break;
 | |
|             case CR_2_5:
 | |
|                 f->q_val = 108;
 | |
|                 f->kbch  = 25728;
 | |
|                 f->bch_code = BCH_CODE_N12;
 | |
|                 break;
 | |
|             case CR_1_2:
 | |
|                 f->q_val = 90;
 | |
|                 f->kbch  = 32208;
 | |
|                 f->bch_code = BCH_CODE_N12;
 | |
|                 break;
 | |
|             case CR_3_5:
 | |
|                 f->q_val = 72;
 | |
|                 f->kbch  = 38688;
 | |
|                 f->bch_code = BCH_CODE_N12;
 | |
|                 break;
 | |
|             case CR_2_3:
 | |
|                 bch_bits = 160;
 | |
|                 f->q_val = 60;
 | |
|                 f->kbch  = 43040;
 | |
|                 f->bch_code = BCH_CODE_N10;
 | |
|                 break;
 | |
|             case CR_3_4:
 | |
|                 f->q_val = 45;
 | |
|                 f->kbch  = 48408;
 | |
|                 f->bch_code = BCH_CODE_N12;
 | |
|                 break;
 | |
|             case CR_4_5:
 | |
|                 f->q_val = 36;
 | |
|                 f->kbch  = 51648;
 | |
|                 f->bch_code = BCH_CODE_N12;
 | |
|                 break;
 | |
|             case CR_5_6:
 | |
|                 bch_bits = 160;
 | |
|                 f->q_val = 30;
 | |
|                 f->kbch  = 53840;
 | |
|                 f->bch_code = BCH_CODE_N10;
 | |
|                 break;
 | |
|             case CR_8_9:
 | |
|                 bch_bits = 128;
 | |
|                 f->q_val = 20;
 | |
|                 f->kbch  = 57472;
 | |
|                 f->bch_code = BCH_CODE_N8;
 | |
|                 break;
 | |
|             case CR_9_10:
 | |
|                 bch_bits = 128;
 | |
|                 f->q_val = 18;
 | |
|                 f->kbch  = 58192;
 | |
|                 f->bch_code = BCH_CODE_N8;
 | |
|                 break;
 | |
|             default:
 | |
| //                loggerf("Configuration error DVB2\n");
 | |
|                 error = -1;
 | |
|                 break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if( f->frame_type == FRAME_SHORT )
 | |
|     {
 | |
|         f->nldpc = 16200;
 | |
|         bch_bits = 168;
 | |
|         f->bch_code = BCH_CODE_S12;
 | |
|         // Apply code rate
 | |
|         switch(f->code_rate )
 | |
|         {
 | |
|             case CR_1_4:
 | |
|                 f->q_val = 36;
 | |
|                 f->kbch  = 3072;
 | |
|                 break;
 | |
|             case CR_1_3:
 | |
|                 f->q_val = 30;
 | |
|                 f->kbch  = 5232;
 | |
|                 break;
 | |
|             case CR_2_5:
 | |
|                 f->q_val = 27;
 | |
|                 f->kbch  = 6312;
 | |
|                 break;
 | |
|             case CR_1_2:
 | |
|                 f->q_val = 25;
 | |
|                 f->kbch  = 7032;
 | |
|                 break;
 | |
|             case CR_3_5:
 | |
|                 f->q_val = 18;
 | |
|                 f->kbch  = 9552;
 | |
|                 break;
 | |
|             case CR_2_3:
 | |
|                 f->q_val = 15;
 | |
|                 f->kbch  = 10632;
 | |
|                 break;
 | |
|             case CR_3_4:
 | |
|                 f->q_val = 12;
 | |
|                 f->kbch  = 11712;
 | |
|                 break;
 | |
|             case CR_4_5:
 | |
|                 f->q_val = 10;
 | |
|                 f->kbch  = 12432;
 | |
|                 break;
 | |
|             case CR_5_6:
 | |
|                 f->q_val = 8;
 | |
|                 f->kbch  = 13152;
 | |
|                 break;
 | |
|             case CR_8_9:
 | |
|                 f->q_val = 5;
 | |
|                 f->kbch  = 14232;
 | |
|                 break;
 | |
|             case CR_9_10:
 | |
|                 error = 1;
 | |
|                 f->kbch  = 0;
 | |
|                 break;
 | |
|             default:
 | |
| //                loggerf("Configuration error DVB2\n");
 | |
|                 error = -1;
 | |
|                 break;
 | |
|         }
 | |
|     }
 | |
|     if( error == 0 )
 | |
|     {
 | |
|         // Length of the user packets
 | |
|         f->bb_header.upl  = 188*8;
 | |
|         // Payload length
 | |
|         f->bb_header.dfl = f->kbch - 80;
 | |
|         // Transport packet sync
 | |
|         f->bb_header.sync = 0x47;
 | |
|         // Start of LDPC bits
 | |
|         f->kldpc = f->kbch + bch_bits;
 | |
|         // Number of padding bits required (not used)
 | |
|         f->padding_bits = 0;
 | |
|         // Number of usable data bits (not used)
 | |
|         f->useable_data_bits = f->kbch - 80;
 | |
|         // Save the configuration, will be updated on next frame
 | |
|         m_format[1] = *f;
 | |
|         // reset various pointers
 | |
|         m_dnp   = 0;// No deleted null packets
 | |
|         // Signal we need to update on the next frame.
 | |
|         if( m_params_changed )
 | |
|             base_end_of_frame_actions();
 | |
|         else
 | |
|             m_params_changed = 1;
 | |
|     }
 | |
|     return error;
 | |
| }
 | |
| void DVB2::get_configure( DVB2FrameFormat *f )
 | |
| {
 | |
|     *f = m_format[1];
 | |
| }
 | |
| 
 | |
| // Points to first byte in transport packet
 | |
| 
 | |
| int DVB2::add_ts_frame_base( u8 *ts )
 | |
| {
 | |
|     if( m_frame_offset_bits == 0 )
 | |
|     {
 | |
|          // New frame needs to be sent
 | |
|         add_bbheader(); // Add the header
 | |
|     }
 | |
|     // Add a new transport packet
 | |
|     unpack_transport_packet_add_crc( ts );
 | |
|     // Have we reached the end?
 | |
|     if( m_frame_offset_bits == m_format[0].kbch )
 | |
|     {
 | |
|         // Yes so now Scramble the BB frame
 | |
|         bb_randomise();
 | |
|         // BCH encode the BB Frame
 | |
|         bch_encode();
 | |
|         // LDPC encode the BB frame and BCHFEC bits
 | |
|         ldpc_encode();
 | |
|         // Signal to the modulation specific class we have something to send
 | |
|         base_end_of_frame_actions();
 | |
|         return 1;
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| //
 | |
| // Dump NULL packets appends a counter to the end of each UP
 | |
| // it is not implemented at the moment.
 | |
| //
 | |
| int DVB2::next_ts_frame_base( u8 *ts )
 | |
| {
 | |
|     int res = 0;
 | |
|     // See if we need to dump null packets
 | |
|     if( m_format[0].null_deletion == 1 )
 | |
|     {
 | |
|         if(((ts[0]&0x1F) == 0x1F)&&(ts[1] == 0xFF ))
 | |
|         {
 | |
|             // Null packet detected
 | |
|             if( m_dnp < 0xFF )
 | |
|             {
 | |
|                 m_dnp++;// Increment the number of null packets
 | |
|                 return 0;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     // Need to send a new transport packet
 | |
|     res = add_ts_frame_base( ts );
 | |
|     if( res ) m_dnp = 0;// Clear the DNP counter
 | |
|     // return whether it is time to transmit a new frame
 | |
|     return res;
 | |
| }
 | |
| DVB2::DVB2(void)
 | |
| {
 | |
|     // Clear the transport queue
 | |
|     m_tp_q.empty();
 | |
|     init_bb_randomiser();
 | |
|     bch_poly_build_tables();
 | |
|     build_crc8_table();
 | |
|     m_dnp   = 0;// No deleted null packets
 | |
|     m_frame_offset_bits = 0;
 | |
|     m_params_changed = 1;
 | |
| }
 | |
| DVB2::~DVB2(void)
 | |
| {
 | |
| }
 |