aboutsummaryrefslogtreecommitdiff
path: root/viterbi615.c
diff options
context:
space:
mode:
Diffstat (limited to 'viterbi615.c')
-rw-r--r--viterbi615.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/viterbi615.c b/viterbi615.c
new file mode 100644
index 0000000..6dda51f
--- /dev/null
+++ b/viterbi615.c
@@ -0,0 +1,155 @@
+/* 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
+ }
+}
+