⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mapper_rcv.c

📁 This a framework to test new ideas in transmission technology. Actual development is a LDPC-coder in
💻 C
字号:
/*************************************************************************** *    mapper_rcv.c  - Takes a qpsk-signal and gives back some bits *                           ------------------- *   begin                :  02/01/04 *   authors              :  Ineiti *   emails               :  linus.gasser@epfl.ch ***************************************************************************//*************************************************************************** *                                Changes *                                ------- * date - name - description * 02/01/04 - ineiti - begin * 03/11/11 -  phil  - symbol_type and bits_per_symbol are now variable * 04/03/06 - ineiti - adjusted description * 04/03/06 - ineiti - deleted config->amplitude * **************************************************************************//*************************************************************************** *                                                                         * *   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; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************//** *  This is a hard-decision slicer that works on two tables, one for * {1,2,3,4}-PSK, the other for {1,2,3,4}-QAM. It can either estimate * the amplitude itself, or it takes the calculated amplitude from a * chest-module. */#include "spc.h"#include "mapper.h"#define DBG_LVL 0typedef struct {  // The bits per symbol  int bits_per_symbol; // 2  // Which table to take: 0-PSK   1-QAM  int symbol_type; // 0  // The id of the matched filter  int mafi_id; // -1}config_t;typedef struct {}stats_t;typedef struct {  int bits_per_symbol;  SYMBOL_COMPLEX table[16];  int mafi_id;}private_t;/* * The initialisation function, or constructor,  * is called the first time this module is instantiated. */int rcv_init( swr_sdb_t *context ) {  // Begin system-definitions {  config_t *config;  stats_t *stats;  MOD_INC_USE_COUNT;  if ( sizeof( private_t ) > 0 )    context->private_data = swr_malloc( sizeof( private_t ) );  swr_sdb_get_config_struct( context->id, (void**)&config );  swr_sdb_get_stats_struct( context->id, (void**)&stats );  // } End of system-definitions  config->bits_per_symbol = 2;  config->symbol_type = 0;  config->mafi_id=-1;  private->mafi_id=-1;    // Begin system-definitions  swr_sdb_free_stats_struct( context->id, (void**)&stats );  swr_sdb_free_config_struct( context->id, (void**)&config );  return 0;  // End system-definitions}/* * To configure the inputs * this is called when the output-sizes change. */int rcv_configure_inputs( swr_sdb_t *context ) {  // Definition of variables - don't touch  config_t *config;  swr_sdb_get_config_struct( context->id, (void**)&config );    size_in(0) = size_out(0) * 8 /private->bits_per_symbol;  PR_DBG( 3, "Setting input-size to %i\n", size_in(0) );    // Definition - don't touch  swr_sdb_free_config_struct( context->id, (void**)&config );  return 0;}/* * To configure the outputs * this is called when the input-sizes change */int rcv_configure_outputs( swr_sdb_t *context ) {  // Definition of variables - don't touch  config_t *config;  swr_sdb_get_config_struct( context->id, (void**)&config );    size_out(0) = size_in(0) * private->bits_per_symbol / 8;  PR_DBG( 3, "Setting output-size to %i\n", size_out(0) );    // Definition - don't touch  swr_sdb_free_config_struct( context->id, (void**)&config );  return 0;}/* * Every time modules from the outside change the value of a configuration parameter, * this function is called. */int rcv_reconfig( swr_sdb_t *context ) {  // Definition of variables - don't touch  int i, j;  config_t *config;  swr_sdb_get_config_struct( context->id, (void**)&config );  if ( ( config->bits_per_symbol <= MAX_BITS ) &&       ( config->symbol_type <= 1 ) &&       ( config->bits_per_symbol > 0 ) ) {    if(config->bits_per_symbol!=private->bits_per_symbol){      private->bits_per_symbol = config->bits_per_symbol;    }    size_out(0) =  floor(size_in(0) * private->bits_per_symbol / 8);    j = private->bits_per_symbol;    for ( i=0; i<(1<<j); i++ ) {      switch( config->symbol_type ) {      case 0:        private->table[i].real = (short)(32767 *                                         Symbols_PSK[j-1][i].real / 256 );        private->table[i].imag = (short)(32767 *                                         Symbols_PSK[j-1][i].imag / 256 );        break;      case 1:        private->table[i].real = (short)(32767 *                                         Symbols_QAM[j-1][i].real / 256 );        private->table[i].imag = (short)(32767 *                                         Symbols_QAM[j-1][i].imag / 256 );        break;      }      PR_DBG( 4, "Symbol %i: (%i,%i)\n", i,              private->table[i].real, private->table[i].imag );    }  }    if(private->mafi_id!=config->mafi_id){     //	PR_DBG( 2, "loading mafi with ID %i\n", config->mafi_id );	private->mafi_id = config->mafi_id;  }  // Definition - don't touch  swr_sdb_free_config_struct( context->id, (void**)&config );  return 0;}/* * This is function that implements the `main method' of the class * Every class has got just ONE method/working-mode. */int rcv_pdata( swr_sdb_t *context ) {  // Definition of variables - don't touch  stats_t *stats;  SYMBOL_COMPLEX *in;  U8 *out;  int i, j, k, l, bits, max_val = 0, ampl = 32767, min_k = 0;  double dist, min_dist;    in = buffer_in(0);  out = buffer_out(0);  PR_DBG(4,"Id: %i - Size in & out at begining of mapper_rcv: %d %d\n",	 context->id, size_in(0),size_out(0));  PR_DBG(4,"Out address: %p\n",out);  // Get or compute the max signal amplitude  if( private->mafi_id>0 ){    max_val = swr_sdb_get_stats_int(private->mafi_id, "mid_amp" );    PR_DBG( 4, "max_ampl from mafi : (%d)\n", max_val );  }  // If we don't have a valid max_val, we try to estimate it ourselves  if( max_val<=0 ){    max_val = 1;    for ( i=0; i<size_in(0); i += private->bits_per_symbol, in++ ) {      if( abs(in->real)>max_val ){	max_val = abs(in->real);      }      if( abs(in->imag)>max_val ){ 	max_val = abs(in->imag);      }    }  }    //Perform decoding  in = buffer_in(0);  j = 0;  l = 0;  bits = 0;  ampl /= max_val;  for ( i=0; i<size_in(0); i++ , in++) {        // Search for the minimal distance over all symbols    min_dist=32767 * 2;    for (k=0; k<(1<<(private->bits_per_symbol)); k++) {      dist=hypot( ampl*in->real - private->table[k].real,		  ampl*in->imag - private->table[k].imag );      if( dist<min_dist ) {	min_dist = dist;	min_k = k;      }    }    bits += min_k << (l%8);    // For debuggin output.     if( i<10 ) {      PR_DBG( 4, "received : (%5i, %5i)\n", 	      ampl*in->real, 	      ampl*in->imag );    }    l += private->bits_per_symbol;    if( l>=8 ) {      //If we have enough bits, write this byte and prepare the next.      if ( j >= size_out(0) ){	PR_DBG( 4, "Overwriting output-port of size %d, with j=%d\n" ,size_out(0),j);      }       out[j] = bits;      bits >>=  8;      j++;      l -=8;    }  }    PR_DBG( 4, "ID: %i - J is: %i\n", context->id, j );  swr_sdb_get_stats_struct( context->id, (void**)&stats );  swr_sdb_free_stats_struct( context->id, (void**)&stats );    return(0);}/* * This is the `destructor'. */int rcv_finalize( swr_sdb_t *context ) {  if ( sizeof( private_t ) > 0 )    swr_free( private );  MOD_DEC_USE_COUNT;  return 0;}/* * This function is called upon "insmod" and is used to register the * different parts of the module to the SPM. */swr_spc_id_t rcv_id;int rcv_module_init(void) {  swr_spc_desc_t *desc;  /**   * Get a description-part from SPM   * Give the following parameters:   * Input-ports, output-ports, config-params, stat-params   */  desc = swr_spc_get_new_desc( 1, 1, 3, 0 );  if ( !desc ) {    PR_DBG( 0, "Can't initialise the module. This is BAD!\n" );    return -1;  }  /**   * Define the different parts of config and stats. You have to define   * them in the same order as they appear in the structures. The names   * can be freely chosen.   *   * UM_CONFIG_{INT,DOUBLE,STRING128}( "name" );   * UM_STATS_{INT,DOUBLE,STRING128}( "name" );   */  UM_CONFIG_INT( "bits_per_symbol" );  UM_CONFIG_INT( "symbol_type" );  UM_CONFIG_INT( "mafi_id", PARAMETER_DEBUG );  /**   * The in- and outputs have also to be defined in the right order. First   * port first. The additional flag is not used yet, but it will...   *   * UM_INPUT( SIG_{U8,SYMBOL_{S16,COMPLEX,MMX},SAMPLE_S12,S32}, 0 );   * UM_OUTPUT( SIG_{U8,SYMBOL_{S16,COMPLEX,MMX},SAMPLE_S12,S32}, 0 );   */  UM_INPUT( SIG_SYMBOL_COMPLEX, 0 );  UM_OUTPUT( SIG_U8, 0 );  // Initialise the callback-functions. Delete the ones you don't use  desc->fn_init              = rcv_init;  desc->fn_reconfigure       = rcv_reconfig;  desc->fn_process_data      = rcv_pdata;  desc->fn_configure_inputs  = rcv_configure_inputs;  desc->fn_configure_outputs = rcv_configure_outputs;  desc->fn_finalize          = rcv_finalize;  // And register the module in the SPM. Change the name!  rcv_id = swr_cdb_register_spc( &desc, "slicer" );  if ( rcv_id == SWR_SPM_INVALID_ID ) {    swr_spc_free_desc( desc );    PR_DBG( 0, "Couldn't register the module!\n" );    return 1;  }  PR_DBG( 4, "Ready\n" );  return 0;}/* * This is called upon rmmod */void rcv_module_exit( void ) {  PR_DBG( 4, "Freeing id: %i\n", rcv_id );  if ( swr_cdb_unregister_spc( rcv_id ) < 0 ) {    PR_DBG( 0, "Still in use somewhere\n" );  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -