You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
3.4 KiB
156 lines
3.4 KiB
/* K=15 r=1/6 Viterbi decoder with optional Intel or PowerPC SIMD
|
|
* Copyright Feb 2004, Phil Karn, KA9Q
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <memory.h>
|
|
#include "fec.h"
|
|
|
|
/* Create a new instance of a Viterbi decoder */
|
|
void *create_viterbi615(int len){
|
|
|
|
find_cpu_mode();
|
|
|
|
switch(Cpu_mode){
|
|
case PORT:
|
|
default:
|
|
return create_viterbi615_port(len);
|
|
#ifdef __VEC__
|
|
case ALTIVEC:
|
|
return create_viterbi615_av(len);
|
|
#endif
|
|
#ifdef __i386__
|
|
case MMX:
|
|
return create_viterbi615_mmx(len);
|
|
case SSE:
|
|
return create_viterbi615_sse(len);
|
|
case SSE2:
|
|
return create_viterbi615_sse2(len);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void set_viterbi615_polynomial(int polys[6]){
|
|
|
|
switch(Cpu_mode){
|
|
case PORT:
|
|
default:
|
|
set_viterbi615_polynomial_port(polys);
|
|
break;
|
|
#ifdef __VEC__
|
|
case ALTIVEC:
|
|
set_viterbi615_polynomial_av(polys);
|
|
break;
|
|
#endif
|
|
#ifdef __i386__
|
|
case MMX:
|
|
set_viterbi615_polynomial_mmx(polys);
|
|
break;
|
|
case SSE:
|
|
set_viterbi615_polynomial_sse(polys);
|
|
break;
|
|
case SSE2:
|
|
set_viterbi615_polynomial_sse2(polys);
|
|
break;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* Initialize Viterbi decoder for start of new frame */
|
|
int init_viterbi615(void *p,int starting_state){
|
|
switch(Cpu_mode){
|
|
case PORT:
|
|
default:
|
|
return init_viterbi615_port(p,starting_state);
|
|
#ifdef __VEC__
|
|
case ALTIVEC:
|
|
return init_viterbi615_av(p,starting_state);
|
|
#endif
|
|
#ifdef __i386__
|
|
case MMX:
|
|
return init_viterbi615_mmx(p,starting_state);
|
|
case SSE:
|
|
return init_viterbi615_sse(p,starting_state);
|
|
case SSE2:
|
|
return init_viterbi615_sse2(p,starting_state);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* Viterbi chainback */
|
|
int chainback_viterbi615(
|
|
void *p,
|
|
unsigned char *data, /* Decoded output data */
|
|
unsigned int nbits, /* Number of data bits */
|
|
unsigned int endstate){ /* Terminal encoder state */
|
|
|
|
switch(Cpu_mode){
|
|
case PORT:
|
|
default:
|
|
return chainback_viterbi615_port(p,data,nbits,endstate);
|
|
#ifdef __VEC__
|
|
case ALTIVEC:
|
|
return chainback_viterbi615_av(p,data,nbits,endstate);
|
|
#endif
|
|
#ifdef __i386__
|
|
case MMX:
|
|
return chainback_viterbi615_mmx(p,data,nbits,endstate);
|
|
case SSE:
|
|
return chainback_viterbi615_sse(p,data,nbits,endstate);
|
|
case SSE2:
|
|
return chainback_viterbi615_sse2(p,data,nbits,endstate);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* Delete instance of a Viterbi decoder */
|
|
void delete_viterbi615(void *p){
|
|
switch(Cpu_mode){
|
|
case PORT:
|
|
default:
|
|
delete_viterbi615_port(p);
|
|
break;
|
|
#ifdef __VEC__
|
|
case ALTIVEC:
|
|
delete_viterbi615_av(p);
|
|
break;
|
|
#endif
|
|
#ifdef __i386__
|
|
case MMX:
|
|
delete_viterbi615_mmx(p);
|
|
break;
|
|
case SSE:
|
|
delete_viterbi615_sse(p);
|
|
break;
|
|
case SSE2:
|
|
delete_viterbi615_sse2(p);
|
|
break;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* Update decoder with a block of demodulated symbols
|
|
* Note that nbits is the number of decoded data bits, not the number
|
|
* of symbols!
|
|
*/
|
|
int update_viterbi615_blk(void *p,unsigned char syms[],int nbits){
|
|
switch(Cpu_mode){
|
|
case PORT:
|
|
default:
|
|
return update_viterbi615_blk_port(p,syms,nbits);
|
|
#ifdef __VEC__
|
|
case ALTIVEC:
|
|
return update_viterbi615_blk_av(p,syms,nbits);
|
|
#endif
|
|
#ifdef __i386__
|
|
case MMX:
|
|
return update_viterbi615_blk_mmx(p,syms,nbits);
|
|
case SSE:
|
|
return update_viterbi615_blk_sse(p,syms,nbits);
|
|
case SSE2:
|
|
return update_viterbi615_blk_sse2(p,syms,nbits);
|
|
#endif
|
|
}
|
|
}
|
|
|