Imported Upstream version 3.2.2
[debian/gnuradio] / gnuradio-core / src / lib / filter / gr_fir_fff_altivec.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2008 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <gr_fir_fff_altivec.h>
26 #include <stdexcept>
27 #include <assert.h>
28 #include <gr_math.h>
29 #include <gr_altivec.h>
30 #include <dotprod_fff_altivec.h>
31 #include <string.h>
32 #include "posix_memalign.h"
33
34 gr_fir_fff_altivec::gr_fir_fff_altivec()
35   : gr_fir_fff_generic(),
36     d_naligned_taps(0), d_aligned_taps(0)
37 {
38 }
39
40 gr_fir_fff_altivec::gr_fir_fff_altivec (const std::vector<float> &new_taps)
41   : gr_fir_fff_generic(new_taps),
42     d_naligned_taps(0), d_aligned_taps(0)
43 {
44   set_taps(new_taps);
45 }
46
47 gr_fir_fff_altivec::~gr_fir_fff_altivec()
48 {
49   if (d_aligned_taps){
50     free(d_aligned_taps);
51     d_aligned_taps = 0;
52   }
53 }
54
55 void
56 gr_fir_fff_altivec::set_taps(const std::vector<float> &inew_taps)
57 {
58   gr_fir_fff_generic::set_taps(inew_taps);      // call superclass
59   d_naligned_taps = gr_p2_round_up(ntaps(), FLOATS_PER_VEC);
60
61   if (d_aligned_taps){
62     free(d_aligned_taps);
63     d_aligned_taps = 0;
64   }
65   void *p;
66   int r = posix_memalign(&p,  sizeof(vec_float4), d_naligned_taps * sizeof(d_aligned_taps[0]));
67   if (r != 0){
68     throw std::bad_alloc();
69   }
70   d_aligned_taps = (float *) p;
71   memcpy(d_aligned_taps, &d_taps[0], ntaps() * sizeof(d_aligned_taps[0]));
72   for (size_t i = ntaps(); i < d_naligned_taps; i++)
73     d_aligned_taps[i] = 0.0;
74 }
75
76
77 float 
78 gr_fir_fff_altivec::filter (const float input[])
79 {
80   if (d_naligned_taps == 0)
81     return 0.0;
82   
83   return dotprod_fff_altivec(input, d_aligned_taps, d_naligned_taps);
84 }