comparison spandsp-0.0.3/user/tfir.c @ 5:f762bf195c4b

import spandsp-0.0.3
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 16:00:21 +0200
parents
children
comparison
equal deleted inserted replaced
4:26cd8f1ef0b1 5:f762bf195c4b
1 /*
2 tfir.c
3 David Rowe
4 Created 30 May 2007
5
6 Test program for Spandsp fir2 function, used for developing optimised
7 Blackfin assembler.
8 */
9
10 /*
11 Copyright (C) 2007 David Rowe
12
13 All rights reserved.
14
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License version 2, as
17 published by the Free Software Foundation.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29 #include <assert.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <inttypes.h>
34
35 #include "fir.h"
36
37 #define TAPS 256
38 #define N 100
39
40 /* C-callable function to return value of CYCLES register */
41
42 int cycles() {
43 int ret;
44
45 __asm__ __volatile__
46 (
47 "%0 = CYCLES;\n\t"
48 : "=&d" (ret)
49 :
50 : "R1"
51 );
52
53 return ret;
54 }
55
56 static int32_t dot(int16_t *x, int16_t *y, int n) {
57 int32_t acc = 0;
58 int i;
59
60 for(i=0; i<n; i++)
61 acc += *x++ * *y++;
62
63 return acc;
64 }
65
66 #ifdef FIRST_TRY
67 static int16_t fir16_asm(fir16_state_t *fir, int16_t sample)
68 {
69 int i;
70 int32_t y, y_dot;
71 int offset1;
72 int offset2;
73
74 fir->history[fir->curr_pos] = sample;
75
76 offset2 = fir->curr_pos;
77 offset1 = fir->taps - offset2;
78 y = 0;
79 for (i = fir->taps - 1; i >= offset1; i--)
80 y += fir->coeffs[i]*fir->history[i - offset1];
81 y_dot = 0;
82 y_dot += dot_asm((int16_t*)&fir->coeffs[offset1], fir->history, fir->curr_pos);
83 printf("offset1 %d offset2: %d y = %d y_dot = %d\n", offset1, offset2, y, y_dot);
84 assert(y_dot == y);
85
86 for ( ; i >= 0; i--)
87 y += fir->coeffs[i]*fir->history[i + offset2];
88 y_dot += dot((int16_t*)fir->coeffs, &fir->history[offset2], offset1);
89 assert(y_dot == y);
90
91 if (fir->curr_pos <= 0)
92 fir->curr_pos = fir->taps;
93 fir->curr_pos--;
94 return (int16_t) (y >> 15);
95 }
96 #endif
97
98 static int16_t fir16_asm(fir16_state_t *fir, int16_t sample)
99 {
100 int i;
101 int32_t y, y_dot;
102
103 fir->history[fir->curr_pos] = sample;
104 fir->history[fir->curr_pos + fir->taps] = sample;
105
106 /*
107 y = 0;
108 for (i=0; i<fir->taps; i++)
109 y += fir->coeffs[i]*fir->history[fir->curr_pos+i];
110 */
111 y_dot = dot_asm((int16_t*)fir->coeffs, &fir->history[fir->curr_pos], fir->taps);
112 //assert(y_dot == y);
113
114 if (fir->curr_pos <= 0)
115 fir->curr_pos = fir->taps;
116 fir->curr_pos--;
117 return (int16_t) (y_dot >> 15);
118 }
119
120 int main() {
121 int16_t taps[TAPS];
122 fir16_state_t fir, fir_asm;
123 int16_t out, out_asm, in;
124 int i, before;
125
126 for(i=0; i<TAPS; i++)
127 taps[i] = 0x8000;
128
129 fir16_create(&fir, taps, TAPS);
130 fir16_create(&fir_asm, taps, TAPS);
131
132 /* first check the results are the same for C and asm */
133
134 for(i=0; i<N; i++) {
135 in = i;
136 out = fir16(&fir, in);
137 out_asm = fir16_asm(&fir_asm, in);
138 //printf("[%d] out = %d out_asm = %d\n", i, out, out_asm);
139 assert(out == out_asm);
140 }
141
142 printf("OK\n");
143
144 /* now measure the speed */
145
146 before = cycles();
147 out = fir16(&fir, in);
148 printf("C version: %d cycles\n", cycles() - before);
149 before = cycles();
150 out_asm = fir16_asm(&fir_asm, in);
151 printf("ASM version: %d cycles\n", cycles() - before);
152
153 return 0;
154 }

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.