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

📄 ofdm_rcv.c

📁 软件无线电的平台
💻 C
字号:
/*************************************************************************** *   fft _rcv.c  -  Software Radio template module ***************************************************************************//*************************************************************************** *                                                                         * *   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.                                   * *                                                                         * ***************************************************************************//*************************************************************************** *                                Changelog *                                --------- * 04/03/06 - ineiti - adjusted description **************************************************************************//** *  This module will receive the time domain samples and compute their FFT's * @size_pot is the size of the input as a power of two. */#include "spc.h"#include "ofdm_help.h"#define DBG_LVL 3typedef struct {  // The size of the fft will be 2 ^ size_pot  int size_pot; // 8  // Some multiplicative factor, must be the same as in fft_send.  // In fact it is more like a division factor, but well, I chose to  // take the same name as in fft_send...  double mult; // 1}config_t;typedef struct {}stats_t;typedef struct {  complex_ofdm *temp,*input,*output,*w,*mul,*mul2,*fact1,*fact2;  int nbr_of_fft;  int size;  int size_pot;  double mult;}private_t;/* * The size variable in the private_t is the actual size of the input * so it is (2^size_pot) *nbr_of_fft * The input is accepted in chunks of size length and there are nbr_of_fft  * such chunks. The fft is then performed on each chunk.*//* * 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;  //private_t *private;  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  // 2^8 is 256, so it's an fft of size 256  config->size_pot = 8;  config->mult = 1.;  private->temp = NULL;  private->input=NULL;  private->output=NULL;  private->w=NULL;  private->mul=NULL;  private->mul2=NULL;  private->fact1=NULL;  private->fact2=NULL;  private->size_pot=config->size_pot;  private->size=1<<private->size_pot;  private->nbr_of_fft=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) / private->size ) * private->size; */  /*   private->nbr_of_fft = size_in(0) / private->size; */  // 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->size ) * private->size;  private->nbr_of_fft = size_out(0) / private->size;  // 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=0;  config_t *config;  swr_sdb_get_config_struct( context->id, (void**)&config );  private->size = 1 << config->size_pot;  private->mult = config->mult;  if ( private->temp ) {    swr_free( private->temp );  }  if(private->input)    swr_free(private->input);  if(private->output)    swr_free(private->output);  if(private->w)    swr_free(private->w);  if(private->mul)    swr_free(private->mul);  if(private->mul2)    swr_free(private->mul2);  if(private->fact1)    swr_free(private->fact1);  if(private->fact2)    swr_free(private->fact2);  private->temp = swr_malloc( sizeof( complex_ofdm ) * private->size );  private->input = swr_malloc( sizeof( complex_ofdm ) * private->size );  private->output = swr_malloc( sizeof(  complex_ofdm ) * private->size );  private->w = swr_malloc(sizeof( complex_ofdm) * private->size/2);  private->mul = swr_malloc( sizeof( complex_ofdm ) * private->size );  private->mul2 = swr_malloc( sizeof(complex_ofdm ) * private->size );  private->fact1 = swr_malloc( sizeof(complex_ofdm ) * 2 );  private->fact2 = swr_malloc( sizeof(complex_ofdm ) * 2 );  for(i=0;i<private->size/2;i++) {    private->w[i].real = cos(2*M_PI*i/private->size);    private->w[i].imag = -1*sin(2*M_PI*i/private->size);  }  // Definition - don't touch  swr_sdb_free_config_struct( context->id, (void**)&config );  return 0;}/* * This is the 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, *out;  int iteration, len;  in = buffer_in(0);  out = buffer_out(0);  for ( iteration = 0; iteration < private->nbr_of_fft; iteration++ ) {    // Initialize the complex-input    for ( len = 0; len < private->size; len++ ) {      private->input[len].imag =        in[ iteration * private->size + len ].imag;      private->input[len].real =        in[ iteration * private->size + len ].real;    }    // Now we have the 256 input samples in input array    // Calculate the fft    handle(private->size, private->size, 0, private->input, private->output,           private->temp, private->w, private->mul, private->mul2, 0,           private->fact1,private->fact2);    // Write the complex-output to the output-buffer    for ( len = 0; len < private->size; len++ ) {      //PR_DBG(0,"The output is %f %f \n",private->output[len].real,private->output[len].imag);      out[ iteration * private->size + len ].imag =        (short int) ( private->output[len].imag / private->mult );      out[ iteration * private->size + len ].real =        (short int) ( private->output[len].real / private->mult );    }  }  emms();  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 ( private->temp ) {    swr_free( private->temp );  }  if(private->input)    swr_free(private->input);  if(private->output)    swr_free(private->output);  if(private->w)    swr_free(private->w);  if(private->mul)    swr_free(private->mul);  if(private->mul2)    swr_free(private->mul2);  if(private->fact1)    swr_free(private->fact1);  if(private->fact2)    swr_free(private->fact2);  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, 2, 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,POINTER}( "name" );   * UM_STATS_{INT,DOUBLE,STRING128,POINTER,BLOCK}( "name" );   */  UM_CONFIG_INT( "size_pot" );  UM_CONFIG_DOUBLE( "mult" );  /**   * 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_SYMBOL_COMPLEX, 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, "ofdm_rcv" );  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 + -