| 49 | |
| 50 | template<typename T> |
| 51 | af_array fftconvolve_fallback(const af_array signal, const af_array filter, |
| 52 | const bool expand, const int baseDim) { |
| 53 | using convT = typename conditional<is_integral<T>::value || |
| 54 | is_same<T, float>::value || |
| 55 | is_same<T, cfloat>::value, |
| 56 | float, double>::type; |
| 57 | using cT = typename conditional<is_same<convT, float>::value, cfloat, |
| 58 | cdouble>::type; |
| 59 | |
| 60 | const Array<cT> S = castArray<cT>(signal); |
| 61 | const Array<cT> F = castArray<cT>(filter); |
| 62 | const dim4 &sdims = S.dims(); |
| 63 | const dim4 &fdims = F.dims(); |
| 64 | dim4 odims(1, 1, 1, 1); |
| 65 | dim4 psdims(1, 1, 1, 1); |
| 66 | dim4 pfdims(1, 1, 1, 1); |
| 67 | |
| 68 | vector<af_seq> index(AF_MAX_DIMS); |
| 69 | |
| 70 | int count = 1; |
| 71 | for (int i = 0; i < baseDim; i++) { |
| 72 | dim_t tdim_i = sdims[i] + fdims[i] - 1; |
| 73 | |
| 74 | // Pad temporary buffers to power of 2 for performance |
| 75 | odims[i] = nextpow2(tdim_i); |
| 76 | psdims[i] = nextpow2(tdim_i); |
| 77 | pfdims[i] = nextpow2(tdim_i); |
| 78 | |
| 79 | // The normalization factor |
| 80 | count *= odims[i]; |
| 81 | |
| 82 | // Get the indexing params for output |
| 83 | if (expand) { |
| 84 | index[i].begin = 0.; |
| 85 | index[i].end = static_cast<double>(tdim_i) - 1.; |
| 86 | } else { |
| 87 | index[i].begin = static_cast<double>(fdims[i]) / 2.0; |
| 88 | index[i].end = static_cast<double>(index[i].begin + sdims[i]) - 1.; |
| 89 | } |
| 90 | index[i].step = 1.; |
| 91 | } |
| 92 | |
| 93 | for (int i = baseDim; i < AF_MAX_DIMS; i++) { |
| 94 | odims[i] = max(sdims[i], fdims[i]); |
| 95 | psdims[i] = sdims[i]; |
| 96 | pfdims[i] = fdims[i]; |
| 97 | index[i] = af_span; |
| 98 | } |
| 99 | |
| 100 | // fft(signal) |
| 101 | Array<cT> T1 = fft<cT, cT>(S, 1.0, baseDim, psdims.get(), baseDim, true); |
| 102 | |
| 103 | // fft(filter) |
| 104 | Array<cT> T2 = fft<cT, cT>(F, 1.0, baseDim, pfdims.get(), baseDim, true); |
| 105 | |
| 106 | // fft(signal) * fft(filter) |
| 107 | T1 = arithOp<cT, af_mul_t>(T1, T2, odims); |
| 108 | |