14e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* K=7 r=1/2 Viterbi decoder with optional Intel or PowerPC SIMD 24e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi * Copyright Feb 2004, Phil Karn, KA9Q 34e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi */ 44e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#include <stdio.h> 54e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#include <stdlib.h> 64e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#include <memory.h> 74e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#include "fec.h" 84e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 94e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Create a new instance of a Viterbi decoder */ 104e213d510f437769f8a28578dd4f786fb7d16c4Bill Yivoid *create_viterbi27(int len){ 114e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi find_cpu_mode(); 124e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 134e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi switch(Cpu_mode){ 144e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case PORT: 154e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi default: 164e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return create_viterbi27_port(len); 174e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__ 184e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case ALTIVEC: 194e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return create_viterbi27_av(len); 204e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 214e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__ 224e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case MMX: 234e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return create_viterbi27_mmx(len); 244e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE: 254e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return create_viterbi27_sse(len); 264e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE2: 274e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return create_viterbi27_sse2(len); 284e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 294e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } 304e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi} 314e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 324e213d510f437769f8a28578dd4f786fb7d16c4Bill Yivoid set_viterbi27_polynomial(int polys[2]){ 334e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi switch(Cpu_mode){ 344e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case PORT: 354e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi default: 364e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi set_viterbi27_polynomial_port(polys); 374e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 384e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__ 394e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case ALTIVEC: 404e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi set_viterbi27_polynomial_av(polys); 414e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 424e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 434e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__ 444e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case MMX: 454e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi set_viterbi27_polynomial_mmx(polys); 464e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 474e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE: 484e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi set_viterbi27_polynomial_sse(polys); 494e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 504e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE2: 514e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi set_viterbi27_polynomial_sse2(polys); 524e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 534e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 544e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } 554e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi} 564e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 574e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Initialize Viterbi decoder for start of new frame */ 584e213d510f437769f8a28578dd4f786fb7d16c4Bill Yiint init_viterbi27(void *p,int starting_state){ 594e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi switch(Cpu_mode){ 604e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case PORT: 614e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi default: 624e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return init_viterbi27_port(p,starting_state); 634e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__ 644e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case ALTIVEC: 654e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return init_viterbi27_av(p,starting_state); 664e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 674e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__ 684e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case MMX: 694e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return init_viterbi27_mmx(p,starting_state); 704e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE: 714e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return init_viterbi27_sse(p,starting_state); 724e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE2: 734e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return init_viterbi27_sse2(p,starting_state); 744e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 754e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } 764e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi} 774e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 784e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Viterbi chainback */ 794e213d510f437769f8a28578dd4f786fb7d16c4Bill Yiint chainback_viterbi27( 804e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi void *p, 814e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi unsigned char *data, /* Decoded output data */ 824e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi unsigned int nbits, /* Number of data bits */ 834e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi unsigned int endstate){ /* Terminal encoder state */ 844e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 854e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi switch(Cpu_mode){ 864e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case PORT: 874e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi default: 884e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return chainback_viterbi27_port(p,data,nbits,endstate); 894e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__ 904e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case ALTIVEC: 914e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return chainback_viterbi27_av(p,data,nbits,endstate); 924e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 934e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__ 944e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case MMX: 954e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return chainback_viterbi27_mmx(p,data,nbits,endstate); 964e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE: 974e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return chainback_viterbi27_sse(p,data,nbits,endstate); 984e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE2: 994e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return chainback_viterbi27_sse2(p,data,nbits,endstate); 1004e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 1014e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } 1024e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi} 1034e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 1044e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Delete instance of a Viterbi decoder */ 1054e213d510f437769f8a28578dd4f786fb7d16c4Bill Yivoid delete_viterbi27(void *p){ 1064e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi switch(Cpu_mode){ 1074e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case PORT: 1084e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi default: 1094e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi delete_viterbi27_port(p); 1104e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 1114e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__ 1124e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case ALTIVEC: 1134e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi delete_viterbi27_av(p); 1144e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 1154e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 1164e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__ 1174e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case MMX: 1184e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi delete_viterbi27_mmx(p); 1194e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 1204e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE: 1214e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi delete_viterbi27_sse(p); 1224e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 1234e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE2: 1244e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi delete_viterbi27_sse2(p); 1254e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 1264e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 1274e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } 1284e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi} 1294e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 1304e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Update decoder with a block of demodulated symbols 1314e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi * Note that nbits is the number of decoded data bits, not the number 1324e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi * of symbols! 1334e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi */ 1344e213d510f437769f8a28578dd4f786fb7d16c4Bill Yiint update_viterbi27_blk(void *p,unsigned char syms[],int nbits){ 1354e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi if(p == NULL) 1364e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return -1; 1374e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 1384e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi switch(Cpu_mode){ 1394e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case PORT: 1404e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi default: 1414e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi update_viterbi27_blk_port(p,syms,nbits); 1424e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 1434e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__ 1444e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case ALTIVEC: 1454e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi update_viterbi27_blk_av(p,syms,nbits); 1464e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 1474e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 1484e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__ 1494e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case MMX: 1504e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi update_viterbi27_blk_mmx(p,syms,nbits); 1514e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 1524e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE: 1534e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi update_viterbi27_blk_sse(p,syms,nbits); 1544e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 1554e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE2: 1564e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi update_viterbi27_blk_sse2(p,syms,nbits); 1574e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 1584e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 1594e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } 1604e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return 0; 1614e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi} 162