00001 // SPUC - Signal processing using C++ - A DSP library 00002 /* Copyright 1999 Phil Karn, KA9Q 00003 * Converted to C++ and modified by Tony Kirke Feb 2003 00004 */ 00005 /* 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2, or (at your option) 00009 * any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00019 */ 00020 /* The two generator polynomials for the NASA Standard K=7 code. 00021 * Since these polynomials are known to be optimal for this constraint 00022 * length there is not much point in changing them. But if you do, you 00023 * will have to regenerate the BUTTERFLY macro calls in viterbi() 00024 */ 00025 #ifndef VITERBIS 00026 #define VITERBIS 00027 #define POLYA 0x6d 00028 #define POLYB 0x4f 00029 namespace SPUC { 00030 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00031 class viterbi_state 00032 { 00033 public: 00034 unsigned long path; /* Decoded path to this state */ 00035 long metric; /* Cumulative metric to this state */ 00036 }; 00037 #endif 00038 00043 class viterbi 00044 { 00045 public: 00046 bool decoded; 00047 bool enable_output; 00048 bool output_ready; 00049 long prev_value; 00050 viterbi_state state0[64],state1[64],*state,*next; 00051 int bitcnt; 00052 int beststate; 00053 long depuncture_bit_number; 00054 bool phase; 00055 00056 viterbi() { 00057 reset(); 00058 state = state0; 00059 next = state1; 00060 for(int i=0;i<64;i++) state[i].metric = -999999; 00061 state[0].path = 0; 00062 } 00063 void reset() { 00064 phase=0; 00065 depuncture_bit_number=0; 00066 decoded=1; 00067 output_ready=0; 00068 enable_output=0; 00069 bitcnt=0; 00070 prev_value=0; 00071 beststate=0; 00072 state = state0; 00073 next = state1; 00074 // Initialize starting metrics 00075 // ...no longer prefer 0 state 00076 for(int i=0;i<64;i++) { 00077 state0[i].metric = -999999; 00078 state1[i].metric = -999999; 00079 state0[i].path = 0; 00080 state1[i].path = 0; 00081 } 00082 } 00083 bool clock(long value) { 00084 bool z; 00085 decoded = !decoded; 00086 if (decoded) z = decode(prev_value,value); 00087 prev_value = value; 00088 if (enable_output) output_ready = decoded; 00089 return(z); 00090 } 00091 bool decode(long s0, long s1); 00092 void minimize_metrics() { 00093 long bestmetric = state[beststate].metric; 00094 for(int i=0;i<64;i++){ 00095 state[i].metric -= bestmetric; 00096 } 00097 } 00098 bool depuncture(const long steal, long soft_in); 00099 }; 00100 } 00101 #endif