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

📄 convdec.c

📁 wcdma模型
💻 C
📖 第 1 页 / 共 2 页
字号:
/* | Project:     WCDMA simulation environment | Module:      Convolutional decoder | Author:      Tommi Makelainen | Date:        January 20, 1999 | | History: |              January 20, 1999 Tommi Makelainen |                      Modified Rorabaugh's example code |                      to rate 1/2 and 1/3 codes with constraint length |                      K=9 (i.e. length of memory shift register). | | Copyright disclaimer: |   This software was developed at the National Institute of Standards |   and Technology by employees of the Federal Government in the course  |   of their official duties. Pursuant to title 17 Section 105 of the  |   United States Code this software is not subject to copyright  |   protection and is in the public domain.  | |   We would appreciate acknowledgement if the software is used.  | */#include <stdlib.h> #include <stdio.h>#include "mealy.h"#include "metrics.h"#include "convdec.h"#include "config_wcdma.h"                  /* * Static data structures. */static int previous_state[50][256];static int *prev_state[50];/* ------------------------------------------------------------------ *//* * Function:    wcdma_dec_R1o3_k9_init * Desc.:       Initializes convolutional decoder (R=1/3, K=9) using *              Viterbi algorithm. * * Note: */void wcdma_dec_R1o3_k9_init(           ViterbiDecoder* this,          /* IN: decoder data */           int info_length,               /* IN: combined length of                                                 input data and tail */           int decoding_depth,            /* IN: depth of a path in trellis */           int tail_length,               /* IN: length of encoder tail */           MealyEncoder* encoder,         /* IN: encoder data */           MetricTable* decoding_metric)  /* IN: data to calculate                                                 trellis path weights */{     this->Decoding_Metric = decoding_metric;    this->Info_Length = info_length;    this->Tail_Length = tail_length;    this->Decoding_depth = decoding_depth;    this->Frame_Length = info_length + tail_length;    this->Tx_Encoder = encoder;    this->Numb_Encdr_States = 256;    this->Numb_Inp_Symbs = 2;    return;} /* wcdma_dec_R1o3_k9_init *//* ------------------------------------------------------------------ *//* * Function:    init_prev_state_vecs * Desc.:       Initializes vectors indicating trellis structure. */static void init_prev_state_vecs(int decoding_depth) {    int i;    for (i=0; i < decoding_depth+1; i++) {      prev_state[i] = previous_state[i];    } /* for */    return;} /* init_prev_state_vecs *//* ------------------------------------------------------------------ *//* * Function:    shift_prev_state_vecs * Desc.:       Remove the oldest level from the encoding trellis. */static void shift_prev_state_vecs(int decoding_depth) {    int i;    int* temp_ptr = prev_state[1];#ifdef WCDMA_DEBUG_OUTPUT    printf("Shifting state vectors ");#endif /* WCDMA_DEBUG_OUTPUT */    for (i=1; i < decoding_depth; i++) {      prev_state[i] = prev_state[i+1];#ifdef WCDMA_DEBUG_OUTPUT      printf("%d<-%d, ", i, i+1);#endif /* WCDMA_DEBUG_OUTPUT */    } /* for */    prev_state[decoding_depth] = temp_ptr;#ifdef WCDMA_DEBUG_OUTPUT    printf("%d <- 1\n", decoding_depth);#endif /* WCDMA_DEBUG_OUTPUT */    return;} /* shift_prev_state_vecs *//* ------------------------------------------------------------------ *//* * Function:    get_prev_state * Desc.:       Returns the previous state for a state in the encoding trellis. */static int get_prev_state(int level, int curr_state) {    return(prev_state[level][curr_state]);}/* ------------------------------------------------------------------ *//* * Function:    set_previous state. * Desc.:       Sets the previous state for a state in the trellis. */static void set_previous_state(int level, int curr_state, int earlier_state) {    *(prev_state[level]+curr_state) = earlier_state;    return;}/* ------------------------------------------------------------------ *//* * Function:    wcdma_dec_R1o3_k9_conv * Desc.:       Decodes convolutional code (R=1/3, K=9) using *              Viterbi algorithm. */void wcdma_dec_R1o3_k9_conv(	ViterbiDecoder* this,	/* IN: decoder state information */	int rx_symbols[],	/* IN: vector of received symbols */	double soft_bits[],	/* IN: vector of soft symbols */	int rx_size,		/* IN: length of received symbols */	int tail[],		/* IN: tail bits */	int tail_size,		/* IN: length of tail */	int decoded_bits[])	/* OUT: vector of decoded bits */{    int state, level, temp_level;    int inp_symb, tx_symb, rx_symb;    int new_state;    unsigned int state_unvisited[256];    double old_path_metric, branch_metric;    double path_metric;    double survivor_metrics[2][256];    int rx_index, tail_index;    int info_symb_size;    double soft_bit;    double best_path_metric;    int best_path_state;    int output_index;    int current, next;    unsigned int state_active[2][256];    int last_state;    int prev_state_on_path,state_on_path;    /*     * Init path metrics and active state tables.     * If state is active, then we can combine two paths.     * If state is inactive, then we have't gone through the state.     */    for(state=0; state < this->Numb_Encdr_States; state++) {	survivor_metrics[0][state] = 0;	survivor_metrics[1][state] = 0;	state_active[0][state] = FALSE;	state_active[1][state] = FALSE;    }     state_active[0][0] = TRUE;    output_index = 0;    /*     * Data structures.     */    current = 0;    next = 1;    init_prev_state_vecs(this->Decoding_depth);        /*     * Loop over the received symbols.     */    info_symb_size = rx_size + tail_size;    tail_index = 0;    for (rx_index=0; rx_index < info_symb_size; rx_index++) {      /*       * Init variables.       */      for(state=0; state < this->Numb_Encdr_States; state++) {		state_unvisited[state] = TRUE;		state_active[next][state] = FALSE;      }      best_path_metric = -10000000.0; /* Init to a very big path metric */      if (rx_index < this->Decoding_depth-1) {        level = rx_index + 1;      } else {        level = this->Decoding_depth-1 + 1;      }      /*       * Get received input symbol. After going through       * received symbols, fill the shift register with       * tail symbols.       */      if (rx_index < rx_size) {        rx_symb = rx_symbols[rx_index];        soft_bit = soft_bits[rx_index];      } else {        rx_symb = tail[tail_index++];        soft_bit = 1.0;      }#ifdef WCDMA_DEBUG_OUTPUT      printf("current rx byte = %d\n",rx_symb);#endif /* WCDMA_DEBUG_OUTPUT */      /*       * Loop over all the encoder states and calculate a path metric       * for each of them.       */      for (state=0; state < this->Numb_Encdr_States; state++) {        /*         * If state was not active on the previous level, jump it over.         */        if (state_active[current][state] == FALSE) continue;        /* fprintf(fptr,"  looping state = %d\n",state); */        /*         * Loop over all candidate input symbols (0,1).         */        for (inp_symb=0; inp_symb < 2; inp_symb++) {          /*           * Get the encoder output for this encoder state and input symbol.           */	  tx_symb = MealyEncoder_GetOutput(this->Tx_Encoder, state, inp_symb);          /*           * Calculate an individual branch metric and a total path metric.           */	  branch_metric = MetricTable_R1o3_GetBranchMetric(			this->Decoding_Metric, rx_symb, soft_bit, tx_symb);        	  old_path_metric = survivor_metrics[current][state];	  path_metric = old_path_metric + branch_metric;	  new_state = MealyEncoder_GetNextState( this->Tx_Encoder,							state, inp_symb);          /*           * Store the current best candidate.           */          if (path_metric > best_path_metric) {            best_path_metric = path_metric;            best_path_state = state;          }	  /*	   * If this is the first time we visit this state,	   * store the branch metrics and previous state.	   */ 	  if(state_unvisited[new_state]) {	    survivor_metrics[next][new_state] = path_metric;	    state_active[next][new_state] = TRUE;	    state_unvisited[new_state] = FALSE;            set_previous_state(level, new_state, state);	  } else {	    /*	     * if the path metric is smaller than the current	     * store value, replace the current survivor path.	     */ 	    if(path_metric > survivor_metrics[next][new_state]) {

⌨️ 快捷键说明

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