00001 #include "standard.h"
00002 #include "rcpcc_hg16.h"
00003
00004 #include "uep_rcpcc.h"
00005
00006
00007 #define TERMINATEPACKET 1
00008
00009
00010
00011 extern int debug;
00012 static int ccx[MAXINPUTBITS][RCPCCDIM];
00013 static double rcx[MAXINPUTBITS][RCPCCDIM];
00014
00015 void ConvBits2Bytes(int *bit_array, unsigned char *byte_array, int N);
00016
00017
00018
00019
00020
00021
00022
00023 int rcpcc16_getK(Rtype,N,CRCBytes)
00024 int Rtype;
00025 int N;
00026 int CRCBytes;
00027 {
00028 int K;
00029
00030 switch(Rtype)
00031 {
00032 case 0: K=(8*(N*8/32)-CRCBytes*8-TAILBITS)/8; break;
00033 case 1: K=(8*(N*8/31)-CRCBytes*8-TAILBITS)/8; break;
00034 case 2: K=(8*(N*8/30)-CRCBytes*8-TAILBITS)/8; break;
00035 case 3: K=(8*(N*8/29)-CRCBytes*8-TAILBITS)/8; break;
00036 case 4: K=(8*(N*8/28)-CRCBytes*8-TAILBITS)/8; break;
00037 case 5: K=(8*(N*8/27)-CRCBytes*8-TAILBITS)/8; break;
00038 case 6: K=(8*(N*8/26)-CRCBytes*8-TAILBITS)/8; break;
00039 case 7: K=(8*(N*8/25)-CRCBytes*8-TAILBITS)/8; break;
00040 case 8: K=(8*(N*8/24)-CRCBytes*8-TAILBITS)/8; break;
00041 case 9: K=(8*(N*8/23)-CRCBytes*8-TAILBITS)/8; break;
00042 case 10: K=(8*(N*8/22)-CRCBytes*8-TAILBITS)/8; break;
00043 case 11: K=(8*(N*8/21)-CRCBytes*8-TAILBITS)/8; break;
00044 case 12: K=(8*(N*8/20)-CRCBytes*8-TAILBITS)/8; break;
00045 case 13: K=(8*(N*8/19)-CRCBytes*8-TAILBITS)/8; break;
00046 case 14: K=(8*(N*8/18)-CRCBytes*8-TAILBITS)/8; break;
00047 case 15: K=(8*(N*8/17)-CRCBytes*8-TAILBITS)/8; break;
00048 case 16: K=(8*(N*8/16)-CRCBytes*8-TAILBITS)/8; break;
00049 case 17: K=(8*(N*8/15)-CRCBytes*8-TAILBITS)/8; break;
00050 case 18: K=(8*(N*8/14)-CRCBytes*8-TAILBITS)/8; break;
00051 case 19: K=(8*(N*8/13)-CRCBytes*8-TAILBITS)/8; break;
00052 case 20: K=(8*(N*8/12)-CRCBytes*8-TAILBITS)/8; break;
00053 case 21: K=(8*(N*8/11)-CRCBytes*8-TAILBITS)/8; break;
00054 case 22: K=(8*(N*8/10)-CRCBytes*8-TAILBITS)/8; break;
00055 case 23:
00056 K=(8*(N*8/9)-CRCBytes*8-TAILBITS)/8;
00057 break;
00058 case 24: K=( (N*8)-CRCBytes*8 - TAILBITS)/8; break;
00059 default: return(0);
00060 }
00061
00062 if(K<=0) return(0);
00063
00064 return(K);
00065 }
00066
00067
00068 int rcpcc16_encode(u,K, a1 , Rtype, N)
00069 int u[];
00070 int K;
00071 buf_rcpc *a1;
00072 int Rtype;
00073 int N;
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 {
00098 int row;
00099 int i,d;
00100 int *temp;
00101
00102
00103
00104 int *tt;
00105 int step = 32 - Rtype;
00106
00107 temp = (int *)calloc(N * 8, sizeof(int ));
00108
00109 if (debug >= 2) {
00110 printf(" inside routine rcpcc16_encode\n");
00111 printf(" Rtype, N, K are %d %d %d \n", Rtype, N, K);
00112
00113 printf(" temp %d temp + N * 8 %d\n", temp, temp + N * 8);
00114 }
00115 row = 0;
00116 while (Rtype >=0)
00117 {
00118 if (debug >= 2)
00119 printf(" Rtype, row are %d %d \n", Rtype, row);
00120
00121 rcpcc_coder(u,ccx,Rtype,K+TAILBITS);
00122
00123
00124
00125
00126 tt = temp;
00127
00128 if (row >0){
00129 for(i=0; i<(K+TAILBITS); i++)
00130 for(d=0; d<RCPCCDIM; d++)
00131 if ((ccx[i][d]!=0) && (px[Rtype][i%8][d] - px[Rtype + step][i%8][d] == 1)) {
00132 if(ccx[i][d]==-1) *tt++ = 0;
00133 else *tt++ = 1;
00134 }
00135 }
00136 else if (row == 0)
00137 {
00138 for(i=0; i<(K+TAILBITS); i++)
00139 for(d=0; d<RCPCCDIM; d++)
00140 if ((ccx[i][d]!=0) ) {
00141 if(ccx[i][d]==-1) *tt++ = 0;
00142 else *tt++ = 1;
00143 }
00144 }
00145
00146 ConvBits2Bytes(temp, a1->block[row], N);
00147
00148 row++;
00149 Rtype = Rtype - step;
00150 }
00151
00152 free(temp);
00153 return(1);
00154
00155 }
00156
00157 void rcpcc_coder(ix,ccx,rateType,packetLength)
00158 int ix[];
00159 int ccx[][RCPCCDIM];
00160 int rateType;
00161 int packetLength;
00162 {
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 int i;
00195 int d;
00196 int k;
00197
00198 for(i=0;i<packetLength;i++) {
00199 for (d=0;d<RCPCCDIM;d++) {
00200
00201
00202 ccx[i][d] = 0;
00203
00204
00205
00206
00207
00208 for (k=0;k<CONSTRAINTLENGTH;k++)
00209 if ( (i >= k) && !(((i-k)>=(packetLength-TAILBITS)) && TERMINATEPACKET) )
00210 ccx[i][d] = (ccx[i][d] + ix[i-k]*gx[k][d]) % 2;
00211
00212
00213 ccx[i][d] = (2*ccx[i][d] - 1) * px[rateType][i%puncturePeriod][d];
00214
00215 }
00216 }
00217
00218 }
00219
00220 void ConvBits2Bytes(int *bit_array, unsigned char *byte_array, int N)
00221 {
00222 int i, j;
00223
00224 for (i =0;i< N; i++){
00225 byte_array[i] = 0;
00226 for (j=0; j< 8; j++){
00227 byte_array[i] = byte_array[i] | (bit_array[i* 8+j] << (7-j) );
00228 }
00229 }
00230 }
00231
00232
00233 void ConvBytes2Bits(unsigned char *byte_array, int *bit_array, int N)
00234 {
00235 int i, j;
00236
00237 for (i =0;i< N; i++){
00238 for (j=0; j< 8; j++){
00239 bit_array[i* 8 + j] = (byte_array[i] >> (7-j)) &1;
00240 }
00241 }
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 int rcpcc16_decode(rx,du,Rtype,N, ppx, CRCBytes)
00258 int rx[];
00259 int du[];
00260 int Rtype;
00261 int N;
00262 int ppx[8][4];
00263 int CRCBytes;
00264 {
00265 int K;
00266 int i,d,j;
00267 int info_dim;
00268
00269
00270 K=rcpcc16_getK(Rtype,N,CRCBytes);
00271 if(K==0) return(0);
00272 info_dim =(K+ CRCBytes) * 8 + TAILBITS;
00273 if (debug >= 2) {
00274 printf(" K, info_dim %d %d\n", K, info_dim);
00275
00276
00277
00278
00279 for (i=0; i< 8; i++){
00280 for (j=0; j< 4; j++){
00281 printf("%d ", ppx[i][j]);
00282 }printf("\n");
00283 }
00284 }
00285
00286
00287 for(i=0; i<(info_dim); i++)
00288 for(d=0; d<RCPCCDIM; d++)
00289 if(ppx[i%puncturePeriod][d]==0)
00290 rcx[i][d] = 0.0;
00291 else
00292 if(*rx++) rcx[i][d] = 1.0;
00293 else rcx[i][d] = -1.0;
00294
00295
00296
00297 if (debug >= 2)
00298 printf(" before rcpcc_decoder\n");
00299 fflush(stdout);
00300 rcpcc_decoder(rcx,du,Rtype,info_dim, ppx);
00301 if (debug >= 2)
00302 printf(" after rcpcc_decoder\n");
00303
00304 return(1);
00305 }
00306
00307 void rcpcc_decoder(rcx,rix,rateType,packetLength, ppx)
00308 double rcx[][RCPCCDIM];
00309 int rix[];
00310 int rateType;
00311 int packetLength;
00312 int ppx[8][4];
00313 {
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 double VAmetric[TL][STATES];
00344 int VAstate[TL][STATES];
00345 double branchMetric[OUTPUTS];
00346
00347 int bin;
00348 int state;
00349
00350 int i, j;
00351 int d;
00352 int output;
00353 int branch;
00354
00355 int trace;
00356
00357 double metric;
00358 double minMetric;
00359 int minState;
00360
00361 printf("rcpcc_decoder - rateType %d packetLength %d\n",rateType, packetLength);
00362
00363
00364
00365 for(bin=0;bin<TL;bin++) {
00366 for(state=0;state<STATES;state++) {
00367 if (state==0)
00368 VAmetric[bin][state] = 0;
00369 else
00370 VAmetric[bin][state] = LARGENUMBER;
00371 VAstate[bin][state] = 0;
00372 }
00373 }
00374
00375
00376 for(i=0;i<packetLength;i++) {
00377
00378
00379
00380 for (output=0;output<OUTPUTS;output++) {
00381 branchMetric[output] = distance(rcx[i],
00382 dsignal[output],
00383 ppx[i%puncturePeriod]);
00384 }
00385
00386
00387
00388
00389
00390 bin = i%TL;
00391
00392 for (state=0;state<STATES;state++) {
00393 for (branch=0;branch<BRANCHES;branch++) {
00394 metric = VAmetric[(bin-1+TL)%TL][prevState[state][branch]] +
00395 branchMetric[prevOutput[state][branch]];
00396 if(metric<VAmetric[bin][state] || (branch==0)) {
00397 VAmetric[bin][state] = metric;
00398 VAstate[bin][state] = prevState[state][branch];
00399 }
00400 }
00401 }
00402
00403
00404
00405 if((i+TAILBITS>=packetLength) && TERMINATEPACKET)
00406 for (state=0;state<STATES;state++)
00407 if (state % (2<<(TAILBITS+i-packetLength)) != 0)
00408 VAmetric[bin][state] = VAmetric[bin][state] + LARGENUMBER;
00409
00410
00411 minState = 0;
00412 minMetric = VAmetric[bin%TL][0];
00413 for(state=1;state<STATES;state++) {
00414 if (VAmetric[bin%TL][state] < minMetric) {
00415 minState = state;
00416 minMetric = VAmetric[bin%TL][state];
00417 }
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427 if ( (i>=TL) || (i==(packetLength-1)) ) {
00428
00429 for(trace=0;((trace<i)&&(trace<TL));trace++) {
00430 rix[i-trace] = minState % 2;
00431
00432 minState = VAstate[(bin-trace+TL)%TL][minState];
00433
00434 }
00435 rix[i-trace] = minState % 2;
00436
00437 }
00438
00439 }
00440
00441 }
00442
00443 double distance(rcx,dsignal,px)
00444 double *rcx;
00445 double *dsignal;
00446 int *px;
00447 {
00448
00449
00450
00451
00452
00453 double error;
00454 int i;
00455 error = 0;
00456 for(i=0;i<RCPCCDIM;i++)
00457 error += (rcx[i]-dsignal[i])*(rcx[i]-dsignal[i])*px[i];
00458 return(error);
00459 }
00460
00461
00462
00463
00464
00465
00466
00467
00468