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 } |
