📄 convdec.c
字号:
survivor_metrics[next][new_state] = path_metric; set_previous_state(level, new_state, state); } } /* else */ } /* for over the candidate input symbols */ } /* for over the encoder states */#if 1#ifdef WCDMA_DEBUG_OUTPUT for(state=0; state<this->Numb_Encdr_States; state++) { if(!state_active[next][state]) continue; printf(" at state %d, metric = %f\n", state,survivor_metrics[next][state]); }#endif /* WCDMA_DEBUG_OUTPUT */#endif if (rx_index > this->Decoding_depth-1) { /* * Produce output from the oldest node in the best path. */ state_on_path = best_path_state; for(temp_level=this->Decoding_depth; temp_level>0; temp_level--) { prev_state_on_path = get_prev_state(temp_level, state_on_path);#ifdef WCDMA_DEBUG_OUTPUT printf("at level %d, path goes thru state %d\n", temp_level, prev_state_on_path);#endif /* WCDMA_DEBUG_OUTPUT */ last_state = state_on_path; state_on_path = prev_state_on_path; } /* for */ decoded_bits[output_index++] = MealyEncoder_GetTransitionTrigger( this->Tx_Encoder, prev_state_on_path, last_state);#ifdef WCDMA_DEBUG_OUTPUT printf("Output: bit %d is %d\n", output_index-1, decoded_bits[output_index-1]);#endif /* WCDMA_DEBUG_OUTPUT */ } /* if */ if (rx_index > this->Decoding_depth-2) { /* * Remove oldest node from the trellis. */ shift_prev_state_vecs(this->Decoding_depth); } /* if */ /* * Switch current and next state information vectors. */ current ^= 0x1; next ^= 0x1; } /* for over the received symbols */ return;} /* wcdma_dec_R1o3_k9_conv *//* ----------------------------------------------------------- *//* * Function: wcdma_dec_R1o2_k9_conv * Desc.: Decodes convolutional code (R=1/2, K=9) using * Viterbi algorithm. */void wcdma_dec_R1o2_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; /* * Initialize states. */ 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_R1o2_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]) { survivor_metrics[next][new_state] = path_metric; set_previous_state(level, new_state, state); } } /* else */ } /* for over the candidate input symbols */ } /* for over the encoder states */#if 1#ifdef WCDMA_DEBUG_OUTPUT for(state=0; state<this->Numb_Encdr_States; state++) { if(!state_active[next][state]) continue; printf(" at state %d, metric = %f\n", state,survivor_metrics[next][state]); }#endif /* WCDMA_DEBUG_OUTPUT */#endif if (rx_index > this->Decoding_depth-1) { /* * Produce output from the oldest node in the best path. */ state_on_path = best_path_state; for(temp_level=this->Decoding_depth; temp_level>0; temp_level--) { prev_state_on_path = get_prev_state(temp_level, state_on_path);#ifdef WCDMA_DEBUG_OUTPUT printf("at level %d, path goes thru state %d\n", temp_level, prev_state_on_path);#endif /* WCDMA_DEBUG_OUTPUT */ last_state = state_on_path; state_on_path = prev_state_on_path; } /* for */ decoded_bits[output_index++] = MealyEncoder_GetTransitionTrigger( this->Tx_Encoder, prev_state_on_path, last_state);#ifdef WCDMA_DEBUG_OUTPUT printf("Output: bit %d is %d\n", output_index-1, decoded_bits[output_index-1]);#endif /* WCDMA_DEBUG_OUTPUT */ } /* if */ if (rx_index > this->Decoding_depth-2) { /* * Remove oldest node from the trellis. */ shift_prev_state_vecs(this->Decoding_depth); } /* if */ /* * Switch current and next state information vectors. */ current ^= 0x1; next ^= 0x1; } /* for over the received symbols */ return;} /* wcdma_dec_R1o2_k9_conv *//* ----------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -