blob: 22481d5365f4333cd151c023eebba2fb3566fc71 [file] [log] [blame]
Tom Tsou35222292016-06-22 16:16:30 -07001/*
2 * Polyphase synthesis filter
3 *
4 * Copyright (C) 2012-2014 Tom Tsou <tom@tsou.cc>
5 * Copyright (C) 2015 Ettus Research LLC
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program 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 Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * See the COPYING file in the main directory for details.
20 */
21
22#include <stdlib.h>
23#include <math.h>
24#include <assert.h>
25#include <string.h>
26#include <cstdio>
Maxd09843c2018-01-04 13:53:15 +010027#include <iostream>
Tom Tsou35222292016-06-22 16:16:30 -070028
Tom Tsou35222292016-06-22 16:16:30 -070029#include "Synthesis.h"
30
31extern "C" {
32#include "common/fft.h"
33#include "common/convolve.h"
34}
35
36static void interleave(float **in, size_t ilen,
37 float *out, size_t m)
38{
39 size_t i, n;
40
41 for (i = 0; i < ilen; i++) {
42 for (n = 0; n < m; n++) {
43 out[2 * (i * m + n) + 0] = in[n][2 * i + 0];
44 out[2 * (i * m + n) + 1] = in[n][2 * i + 1];
45 }
46 }
47}
48
49size_t Synthesis::inputLen() const
50{
51 return blockLen;
52}
53
54size_t Synthesis::outputLen() const
55{
56 return blockLen * m;
57}
58
59float *Synthesis::inputBuffer(size_t chan) const
60{
61 if (chan >= m)
62 return NULL;
63
64 return hOutputs[chan];
65}
66
67bool Synthesis::resetBuffer(size_t chan)
68{
69 if (chan >= m)
70 return false;
71
72 memset(hOutputs[chan], 0, blockLen * 2 * sizeof(float));
73
74 return true;
75}
76
77/*
78 * Implementation based on material found in:
79 *
80 * "harris, fred, Multirate Signal Processing, Upper Saddle River, NJ,
81 * Prentice Hall, 2006."
82 */
83bool Synthesis::rotate(float *out, size_t len)
84{
85 size_t hSize = 2 * hLen * sizeof(float);
86
87 if (!checkLen(blockLen, len)) {
88 std::cout << "Length fail" << std::endl;
89 exit(1);
90 return false;
91 }
92
93 cxvec_fft(fftHandle);
94
95 /*
96 * Convolve through filterbank while applying and saving sample history
97 */
98 for (size_t i = 0; i < m; i++) {
99 memcpy(&hInputs[i][2 * -hLen], hist[i], hSize);
100 memcpy(hist[i], &hInputs[i][2 * (blockLen - hLen)], hSize);
101
102 convolve_real(hInputs[i], blockLen,
103 subFilters[i], hLen,
104 hOutputs[i], blockLen,
105 0, blockLen, 1, 0);
106 }
107
108 /* Interleave into output vector */
109 interleave(hOutputs, blockLen, out, m);
110
111 return true;
112}
113
114Synthesis::Synthesis(size_t m, size_t blockLen, size_t hLen)
115 : ChannelizerBase(m, blockLen, hLen)
116{
117}
118
119Synthesis::~Synthesis()
120{
121}