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

📄 fading_multi_complex.c

📁 This a framework to test new ideas in transmission technology. Actual development is a LDPC-coder in
💻 C
字号:
/***************************************************************************    fading_multi.c  -  Module for a complex multi-path fading noise channel                            -------------------    begin                :  2003    authors              :  Philippe Roud    emails               :  philippe.roud@epfl.ch ***************************************************************************//***************************************************************************                                 Changes                                 ------- date - name - description 03-11-15 - phil - begin 04/03/01 - ineiti - added auto-receive for transmitting antennas, that is,                     a tx-slot is copied to the rx-part (kind of simulates                     better the hardware 04/03/19 - ineiti - fixed partial rx- or tx- blocks 04/05/14 - ineiti - respect the value of TX_OFF in a more general way  **************************************************************************//*************************************************************************** *                                                                         * *   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.                                   * *                                                                         * ***************************************************************************/#include <math.h>#include <stdlib.h>#include <complex.h>#include "system.h"#include "debugging.h"#include "server.h"#define DBG_LVL 0#define FADING_CHANNEL 0/** * @short a simple fading channel with no reflexions for complex numbers */double path_loss_fading_multi[MAX_CLIENTS][MAX_CLIENTS], noise;double u,v,r,s;double alpha, w,p;unsigned short simrand[3];// The variance of the Gaussian noiseint null_out;// Set the variance of the Gaussian noise// If it is too low, it could hinder some modules to function// properly...double sigma_real = 50.;/** * @short initialises the channel */void fading_multi_complex_init() {  int t, i, j;  struct timeval tp;  // Set the white noise to 0  noise = 0;  // initialize the random generator  gettimeofday(&tp,NULL);  simrand[0]=(unsigned short)(tp.tv_sec&0177777);  simrand[1]=(unsigned short)((tp.tv_sec>>12)&0177777);  simrand[2]=(unsigned short)((tp.tv_sec>>24)&0177777);  // Creates default unitary channels and one 0-channel  for ( i=0; i< MAX_CLIENTS; i++ ) {    PR_DBG( 4, "Receiver %i\n", i );    for( j = 0; j < MAX_CLIENTS; j++){      PR_DBG( 4, "  Sender %i: ", j );      for ( t=0; t<CHANNEL_LENGTH; t++ ) {	//Channel set for BS->MS	channel_tap_cplx[ i ][ j ][ t ] = (t == 0) * (i<MAX_CLIENTS);	PR_DBG_CL( 4, "%i+I*%i ",		   (int)creal(channel_tap_cplx[ i ][ j ][ t ]) > 0.,		   (int)cimag(channel_tap_cplx[ i ][ j ][ t ]) > 0. );      }      PR_DBG_CL( 4, "\n" );    }  }}double getSigma( double amp ){  double u, v, w;  do {    u = 2*erand48(simrand)-1;    v = 2*erand48(simrand)-1;    w = u*u + v*v;  } while (w>=1);  alpha = sqrt( -2 * log(w)/w);  return alpha * u * amp;}#define sign(x) ((x)>=0?1:-1)#define TX_OFF_16 ( 0x101 * TX_OFF )/** * @short calculates the fading */void fading_multi_complex_calc( int nb_clients, int gid ) {  int n,i,j, t;  short *rx, *tx;  double complex res, tx_cplx;  double complex taps[ CHANNEL_LENGTH ];  double gain;  PR_DBG( 4, "calculating block %i\n", tx_block );  for ( i = 0; i < MAX_CLIENTS; i++ ) {    if ( client[i].id == -1 ) {      continue;    }    // For all receiving clients    // Initialise the rx-block. Three cases may occur:    // - whole block in rx-mode: set to zero    // - some in rx-mode, some in tx-mode: zero rx-part and copy tx-part    // - whole block in tx-mode: copy to the rx-block    // We assume that the mode only changes once a block. So it is enough    // to look at the start (tx[0]) and at the end (tx[DAQ_DMA_BLOCK_SIZE_SAMPLES-1])    // to know where we're at    rx = (short*)rx_signal_buffer[i][BLOCK_ACT_RX(tx_block)];    tx = (short*)tx_signal_buffer[i][BLOCK_ACT_TX(tx_block)];    if ( tx[0] == TX_OFF_16 && tx[DAQ_DMA_BLOCK_SIZE_SAMPLES-1] == TX_OFF_16 ){      // We're in reception mode, so start with an empty block      memset( rx, 0, DAQ_DMA_BLOCK_SIZE_BYTES );    } else if ( tx[0] == TX_OFF_16 || tx[DAQ_DMA_BLOCK_SIZE_SAMPLES-1] == TX_OFF_16 ){      // The switching point is somewhere in this block, so put all      // reception-samples to 0 and copy the transmission-samples to itself      for ( n=0; n<DAQ_DMA_BLOCK_SIZE_SAMPLES; n++ ){	if ( tx[n] == TX_OFF_16 ){	  rx[n] = 0;	} else {	  rx[n] = tx[n];	}      }    } else {      // Loop back the sent signal to itself if in transmission mode for      // the whole block      memcpy( rx, tx, DAQ_DMA_BLOCK_SIZE_BYTES );    }    for (j=0;j<MAX_CLIENTS;j++) {      int rcv = 1;      // There is no such client      if ( client[j].id == -1 ){	continue;      }      // Sending to itself is already taken care of      if ( j == i ){        continue;      }      // We don't send a signal between antennas from same      // group      if (  client[j].gid == client[i].gid ) {	continue;      }      tx = (short*)tx_signal_buffer[j][BLOCK_ACT_TX(tx_block)];      // If the sender is TX_OFF_16 throughout, this means that there is nothing      // to send, but rather in receiving mode. So we don't do any      // calculations on this...      for ( n=0; n<DAQ_DMA_BLOCK_SIZE_SAMPLES; n++ ) {	if ( tx[n] != TX_OFF_16 ){	  rcv = 0;	  break;	}      }      if ( rcv ){#if FADING_CHANNEL        // This implements a slowly-fading (constant channel over one slot)        // channel	complex double ct;	// The sender is listening, so let's change the channel	ct = getSigma( 1 ) + getSigma( 1 ) * I;	channel_tap_cplx[ i ][ j ][ 0 ] = ct;	if ( j >= 2 ){	  ct *= 600;	  PR_DBG( 4, "h[%i][%i] = %g + %gi\n", i, j, creal( ct ), cimag( ct ) );	}#endif	continue;      }      // The gain between the sender and receiver      gain = 300. / ( 1 << 14 ) * rx_gain[i] * tx_gain[j];      // Some debug-information      if ( !( tx_block % 1000 ) ) {        PR_DBG( 4, "tx_gain[%i] = %e, rx_gain[%i] = %e\n",                j, tx_gain[j], i, rx_gain[i] );        PR_DBG( 4, "From %i to %i, gain %e\n", j, i, gain );	PR_DBG( 4, "Taps: " );      }      // Calculation of the channel taps      for ( t=0; t<CHANNEL_LENGTH; t++ ) {	taps[ t ] = channel_tap_cplx[ i ][ j ][ t ] * gain;	if ( i == 0 && j == 2 ){	  PR_DBG( 4, "gain: %g, taps is %g + %gI\n", gain,		  creal( taps[ t ] / gain ), cimag( taps[ t ] / gain ) );	}        if ( !( tx_block % 1000 ) ) {          PR_DBG_CL( 4, "%i+I*%i ", creal(taps[ t ]) > 0.,cimag(taps[ t ]) > 0. );        }      }      if ( !( tx_block % 1000 ) ) {        PR_DBG_CL( 4, "\n" );      }      for ( n = 0; n < DAQ_DMA_BLOCK_SIZE_SAMPLES; n+=2 ) {#if 0	rx[n] += tx[n] / 16;	rx[n+1] += tx[n+1] / 16;#else	// Convolution of emitted signal with the channel        for ( t=0, res=0; t<CHANNEL_LENGTH; t++ ) {	  tx_cplx = tx[n-2*t] + I*tx[n+1-2*t];	  res += tx_cplx * taps[t];        }	rx[n]   += creal( res );	rx[n+1] += cimag( res );#endif      }    }    // For all samples, add some noise. If we'd do it in the    // loop, we'd add noise for every incoming channel, which    // would be wrong.    for ( n = 0; n < DAQ_DMA_BLOCK_SIZE_SAMPLES; n++ ) {      // Add noise      rx[n]   += getSigma( sigma_real );      rx[n]   &= 0xfff0;    }  }}

⌨️ 快捷键说明

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