14e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* K=15 r=1/6 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_viterbi615(int len){ 114e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 124e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi find_cpu_mode(); 134e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 144e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi switch(Cpu_mode){ 154e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case PORT: 164e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi default: 174e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return create_viterbi615_port(len); 184e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__ 194e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case ALTIVEC: 204e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return create_viterbi615_av(len); 214e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 224e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__ 234e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case MMX: 244e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return create_viterbi615_mmx(len); 254e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE: 264e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return create_viterbi615_sse(len); 274e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE2: 284e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return create_viterbi615_sse2(len); 294e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 304e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } 314e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi} 324e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 334e213d510f437769f8a28578dd4f786fb7d16c4Bill Yivoid set_viterbi615_polynomial(int polys[6]){ 344e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 354e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi switch(Cpu_mode){ 364e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case PORT: 374e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi default: 384e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi set_viterbi615_polynomial_port(polys); 394e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 404e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__ 414e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case ALTIVEC: 424e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi set_viterbi615_polynomial_av(polys); 434e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 444e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 454e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__ 464e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case MMX: 474e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi set_viterbi615_polynomial_mmx(polys); 484e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 494e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE: 504e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi set_viterbi615_polynomial_sse(polys); 514e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 524e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE2: 534e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi set_viterbi615_polynomial_sse2(polys); 544e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 554e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 564e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } 574e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi} 584e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 594e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Initialize Viterbi decoder for start of new frame */ 604e213d510f437769f8a28578dd4f786fb7d16c4Bill Yiint init_viterbi615(void *p,int starting_state){ 614e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi switch(Cpu_mode){ 624e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case PORT: 634e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi default: 644e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return init_viterbi615_port(p,starting_state); 654e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__ 664e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case ALTIVEC: 674e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return init_viterbi615_av(p,starting_state); 684e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 694e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__ 704e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case MMX: 714e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return init_viterbi615_mmx(p,starting_state); 724e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE: 734e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return init_viterbi615_sse(p,starting_state); 744e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE2: 754e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return init_viterbi615_sse2(p,starting_state); 764e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 774e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } 784e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi} 794e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 804e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Viterbi chainback */ 814e213d510f437769f8a28578dd4f786fb7d16c4Bill Yiint chainback_viterbi615( 824e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi void *p, 834e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi unsigned char *data, /* Decoded output data */ 844e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi unsigned int nbits, /* Number of data bits */ 854e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi unsigned int endstate){ /* Terminal encoder state */ 864e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 874e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi switch(Cpu_mode){ 884e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case PORT: 894e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi default: 904e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return chainback_viterbi615_port(p,data,nbits,endstate); 914e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__ 924e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case ALTIVEC: 934e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return chainback_viterbi615_av(p,data,nbits,endstate); 944e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 954e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__ 964e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case MMX: 974e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return chainback_viterbi615_mmx(p,data,nbits,endstate); 984e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE: 994e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return chainback_viterbi615_sse(p,data,nbits,endstate); 1004e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE2: 1014e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return chainback_viterbi615_sse2(p,data,nbits,endstate); 1024e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 1034e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } 1044e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi} 1054e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 1064e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Delete instance of a Viterbi decoder */ 1074e213d510f437769f8a28578dd4f786fb7d16c4Bill Yivoid delete_viterbi615(void *p){ 1084e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi switch(Cpu_mode){ 1094e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case PORT: 1104e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi default: 1114e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi delete_viterbi615_port(p); 1124e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 1134e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__ 1144e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case ALTIVEC: 1154e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi delete_viterbi615_av(p); 1164e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 1174e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 1184e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__ 1194e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case MMX: 1204e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi delete_viterbi615_mmx(p); 1214e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 1224e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE: 1234e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi delete_viterbi615_sse(p); 1244e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 1254e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE2: 1264e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi delete_viterbi615_sse2(p); 1274e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi break; 1284e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 1294e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } 1304e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi} 1314e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 1324e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi/* Update decoder with a block of demodulated symbols 1334e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi * Note that nbits is the number of decoded data bits, not the number 1344e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi * of symbols! 1354e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi */ 1364e213d510f437769f8a28578dd4f786fb7d16c4Bill Yiint update_viterbi615_blk(void *p,unsigned char syms[],int nbits){ 1374e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi switch(Cpu_mode){ 1384e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case PORT: 1394e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi default: 1404e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return update_viterbi615_blk_port(p,syms,nbits); 1414e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __VEC__ 1424e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case ALTIVEC: 1434e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return update_viterbi615_blk_av(p,syms,nbits); 1444e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 1454e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#ifdef __i386__ 1464e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case MMX: 1474e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return update_viterbi615_blk_mmx(p,syms,nbits); 1484e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE: 1494e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return update_viterbi615_blk_sse(p,syms,nbits); 1504e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi case SSE2: 1514e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi return update_viterbi615_blk_sse2(p,syms,nbits); 1524e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi#endif 1534e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi } 1544e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi} 1554e213d510f437769f8a28578dd4f786fb7d16c4Bill Yi 156