Mercurial > hg > audiostuff
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 } |