mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-11-03 13:11:20 -05:00 
			
		
		
		
	
		
			
	
	
		
			333 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			333 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								#include "DVBS2.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void DVBS2::b_64_7_code( unsigned char in, int *out )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    unsigned long temp,bit;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    temp = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if(in&0x40) temp ^= g[0];
							 | 
						||
| 
								 | 
							
								    if(in&0x20) temp ^= g[1];
							 | 
						||
| 
								 | 
							
								    if(in&0x10) temp ^= g[2];
							 | 
						||
| 
								 | 
							
								    if(in&0x08) temp ^= g[3];
							 | 
						||
| 
								 | 
							
								    if(in&0x04) temp ^= g[4];
							 | 
						||
| 
								 | 
							
								    if(in&0x02) temp ^= g[5];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    bit = 0x80000000;
							 | 
						||
| 
								 | 
							
								    for( int m = 0; m < 32; m++ )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        out[(m*2)]   = (temp&bit)?1:0;
							 | 
						||
| 
								 | 
							
								        out[(m*2)+1] = out[m*2]^(in&0x01);
							 | 
						||
| 
								 | 
							
								        bit >>= 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    // Randomise it
							 | 
						||
| 
								 | 
							
								    for( int m = 0; m < 64; m++ )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        out[m] = out[m] ^ ph_scram_tab[m];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								//[MODCOD 6:2 ][TYPE 1:0 ]
							 | 
						||
| 
								 | 
							
								void DVBS2::s2_pl_header_encode( u8 modcod, u8 type, int *out)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    unsigned char code;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    code = (modcod<<2) | type;
							 | 
						||
| 
								 | 
							
								    //printf("MODCOD %d TYPE %d %d\n",modcod,type,code);
							 | 
						||
| 
								 | 
							
								    // Add the modcod and type information and scramble it
							 | 
						||
| 
								 | 
							
								    b_64_7_code( code, out );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								void DVBS2::s2_pl_header_create(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int type, modcod;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    modcod = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if( m_format[0].frame_type == FRAME_NORMAL )
							 | 
						||
| 
								 | 
							
								        type = 0;
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								        type = 2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if( m_format[0].pilots ) type |= 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Mode and code rate
							 | 
						||
| 
								 | 
							
								    if( m_format[0].constellation == M_QPSK )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        switch( m_format[0].code_rate )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								        case CR_1_4:
							 | 
						||
| 
								 | 
							
								            modcod = 1;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        case CR_1_3:
							 | 
						||
| 
								 | 
							
								            modcod = 2;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        case CR_2_5:
							 | 
						||
| 
								 | 
							
								            modcod = 3;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        case CR_1_2:
							 | 
						||
| 
								 | 
							
								            modcod = 4;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        case CR_3_5:
							 | 
						||
| 
								 | 
							
								            modcod = 5;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        case CR_2_3:
							 | 
						||
| 
								 | 
							
								            modcod = 6;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        case CR_3_4:
							 | 
						||
| 
								 | 
							
								            modcod = 7;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        case CR_4_5:
							 | 
						||
| 
								 | 
							
								            modcod = 8;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        case CR_5_6:
							 | 
						||
| 
								 | 
							
								            modcod = 9;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        case CR_8_9:
							 | 
						||
| 
								 | 
							
								            modcod = 10;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        case CR_9_10:
							 | 
						||
| 
								 | 
							
								            modcod = 11;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								            modcod = 0;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if( m_format[0].constellation == M_8PSK )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        switch( m_format[0].code_rate )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            case CR_3_5:
							 | 
						||
| 
								 | 
							
								                modcod = 12;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            case CR_2_3:
							 | 
						||
| 
								 | 
							
								                modcod = 13;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            case CR_3_4:
							 | 
						||
| 
								 | 
							
								                modcod = 14;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            case CR_5_6:
							 | 
						||
| 
								 | 
							
								                modcod = 15;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            case CR_8_9:
							 | 
						||
| 
								 | 
							
								                modcod = 16;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            case CR_9_10:
							 | 
						||
| 
								 | 
							
								                modcod = 17;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            default:
							 | 
						||
| 
								 | 
							
								                modcod = 0;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if( m_format[0].constellation == M_16APSK )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        switch( m_format[0].code_rate )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								        case CR_2_3:
							 | 
						||
| 
								 | 
							
								                modcod = 18;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        case CR_3_4:
							 | 
						||
| 
								 | 
							
								                modcod = 19;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        case CR_4_5:
							 | 
						||
| 
								 | 
							
								                modcod = 20;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        case CR_5_6:
							 | 
						||
| 
								 | 
							
								                modcod = 21;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        case CR_8_9:
							 | 
						||
| 
								 | 
							
								                modcod = 22;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        case CR_9_10:
							 | 
						||
| 
								 | 
							
								                modcod = 23;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								                modcod = 0;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if( m_format[0].constellation == M_32APSK )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        switch( m_format[0].code_rate )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								        case CR_3_4:
							 | 
						||
| 
								 | 
							
								                modcod = 24;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        case CR_4_5:
							 | 
						||
| 
								 | 
							
								                modcod = 25;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        case CR_5_6:
							 | 
						||
| 
								 | 
							
								                modcod = 26;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        case CR_8_9:
							 | 
						||
| 
								 | 
							
								                modcod = 27;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        case CR_9_10:
							 | 
						||
| 
								 | 
							
								                modcod = 28;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								                modcod = 0;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    // Now create the PL header.
							 | 
						||
| 
								 | 
							
								    int b[90];
							 | 
						||
| 
								 | 
							
								    // Add the sync sequence SOF
							 | 
						||
| 
								 | 
							
								    for( int i = 0; i < 26; i++ ) b[i] = ph_sync_seq[i];
							 | 
						||
| 
								 | 
							
								    // Add the mode and code
							 | 
						||
| 
								 | 
							
								    s2_pl_header_encode( modcod, type, &b[26] );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // BPSK modulate and add the header
							 | 
						||
| 
								 | 
							
								    for( int i = 0; i < 90; i++ )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								       m_pl[i] =  m_bpsk[i&1][b[i]];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// m_symbols is the total number of complex symbols in the frame
							 | 
						||
| 
								 | 
							
								// Modulate the data starting at symbol 90
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								int  DVBS2::s2_pl_data_pack( void )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int m = 0;
							 | 
						||
| 
								 | 
							
								    int n = 90;// Jump over header
							 | 
						||
| 
								 | 
							
								    int blocks = m_payload_symbols/90;
							 | 
						||
| 
								 | 
							
								    int block_count = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // See if PSK
							 | 
						||
| 
								 | 
							
								    if( m_format[0].constellation == M_QPSK )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        for( int i = 0; i < blocks; i++ )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            for( int j = 0; j < 90; j++ )
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                m_pl[n++] = m_qpsk[m_iframe[m++]&0x3];
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            block_count = (block_count+1)%16;
							 | 
						||
| 
								 | 
							
								            if((block_count == 0)&&(i<blocks-1))
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                if( m_format[0].pilots )
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    // Add pilots if needed
							 | 
						||
| 
								 | 
							
								                    for( int k = 0; k < 36; k++ )
							 | 
						||
| 
								 | 
							
								                    {
							 | 
						||
| 
								 | 
							
								                        m_pl[n++] = m_bpsk[0][0];
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    // See if 8 PSK
							 | 
						||
| 
								 | 
							
								    if( m_format[0].constellation == M_8PSK )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        for( int i = 0; i < blocks; i++ )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            for( int j = 0; j < 90; j++ )
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                m_pl[n++] = m_8psk[m_iframe[m++]&0x7];
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            block_count = (block_count+1)%16;
							 | 
						||
| 
								 | 
							
								            if((block_count == 0)&&(i<blocks-1))
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                if( m_format[0].pilots )
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    // Add pilots if needed
							 | 
						||
| 
								 | 
							
								                    for( int k = 0; k < 36; k++ )
							 | 
						||
| 
								 | 
							
								                    {
							 | 
						||
| 
								 | 
							
								                        m_pl[n++] = m_bpsk[0][0];
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    // See if 16 PSK
							 | 
						||
| 
								 | 
							
								    if( m_format[0].constellation == M_16APSK )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        for( int i = 0; i < blocks; i++ )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            for( int j = 0; j < 90; j++ )
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                   m_pl[n++] = m_16apsk[m_iframe[m++]&0xF];
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            block_count = (block_count+1)%16;
							 | 
						||
| 
								 | 
							
								            if((block_count == 0)&&(i<blocks-1))
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                if( m_format[0].pilots )
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    // Add pilots if needed
							 | 
						||
| 
								 | 
							
								                    for( int k = 0; k < 36; k++ )
							 | 
						||
| 
								 | 
							
								                    {
							 | 
						||
| 
								 | 
							
								                        m_pl[n++] = m_bpsk[0][0];
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    // See if 32 APSK
							 | 
						||
| 
								 | 
							
								    if( m_format[0].constellation == M_32APSK )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        for( int i = 0; i < blocks; i++ )
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            for( int j = 0; j < 90; j++ )
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                m_pl[n++] = m_32apsk[m_iframe[m++]&0x1F];
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            block_count = (block_count+1)%16;
							 | 
						||
| 
								 | 
							
								            if((block_count == 0)&&(i<blocks-1))
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                if( m_format[0].pilots )
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    // Add pilots if needed
							 | 
						||
| 
								 | 
							
								                    for( int k = 0; k < 36; k++ )
							 | 
						||
| 
								 | 
							
								                    {
							 | 
						||
| 
								 | 
							
								                        m_pl[n++] = m_bpsk[0][0];
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    // Now apply the scrambler to the data part not the header
							 | 
						||
| 
								 | 
							
								    pl_scramble_symbols( &m_pl[90], n - 90 );
							 | 
						||
| 
								 | 
							
								    // Return the length
							 | 
						||
| 
								 | 
							
								    return n;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// This is not used for Broadcast mode
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								void DVBS2::pl_build_dummy( void )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int n = 0;
							 | 
						||
| 
								 | 
							
								    int b[90];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Add the sync sequence SOF
							 | 
						||
| 
								 | 
							
								    for( int i = 0; i < 26; i++ ) b[i] = ph_sync_seq[i];
							 | 
						||
| 
								 | 
							
								    // Add the mode and code and sync sequence
							 | 
						||
| 
								 | 
							
								    s2_pl_header_encode( 0, 0, &b[26] );
							 | 
						||
| 
								 | 
							
								    // BPSK Modulate
							 | 
						||
| 
								 | 
							
								    for( int i = 0; i < 90; i++ )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								       m_pl[i].re = m_bpsk[i&1][b[i]].re;
							 | 
						||
| 
								 | 
							
								       m_pl[i].im = m_bpsk[i&1][b[i]].im;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    n += (90*36);
							 | 
						||
| 
								 | 
							
								    pl_scramble_dummy_symbols( n );
							 | 
						||
| 
								 | 
							
								    m_dummy_frame_length = n;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								scmplx * DVBS2::pl_get_frame( void )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return m_pl;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								scmplx * DVBS2::pl_get_dummy( int &len )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    scmplx * frame;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    len   = m_dummy_frame_length;
							 | 
						||
| 
								 | 
							
								    frame = m_pl_dummy;
							 | 
						||
| 
								 | 
							
								    return frame;
							 | 
						||
| 
								 | 
							
								}
							 |