blob: 24da8e69987c26375ba4a775d959eceb4ff806a8 [file] [log] [blame]
Tom Tsou35222292016-06-22 16:16:30 -07001/*
2 * Polyphase synthesis filter
Pau Espin Pedrolbdb970e2019-07-22 12:03:39 +02003 *
Tom Tsou35222292016-06-22 16:16:30 -07004 * Copyright (C) 2012-2014 Tom Tsou <tom@tsou.cc>
5 * Copyright (C) 2015 Ettus Research LLC
6 *
Pau Espin Pedrol21d03d32019-07-22 12:05:52 +02007 * SPDX-License-Identifier: AGPL-3.0+
8 *
Tom Tsou35222292016-06-22 16:16:30 -07009 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Affero General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 * See the COPYING file in the main directory for details.
22 */
23
24#include <stdlib.h>
25#include <math.h>
26#include <assert.h>
27#include <string.h>
28#include <cstdio>
Maxd09843c2018-01-04 13:53:15 +010029#include <iostream>
Tom Tsou35222292016-06-22 16:16:30 -070030
Tom Tsou35222292016-06-22 16:16:30 -070031#include "Synthesis.h"
32
33extern "C" {
Pau Espin Pedrol43fedb62018-04-24 15:22:57 +020034#include "fft.h"
35#include "convolve.h"
Tom Tsou35222292016-06-22 16:16:30 -070036}
37
38static void interleave(float **in, size_t ilen,
39 float *out, size_t m)
40{
41 size_t i, n;
42
43 for (i = 0; i < ilen; i++) {
44 for (n = 0; n < m; n++) {
45 out[2 * (i * m + n) + 0] = in[n][2 * i + 0];
46 out[2 * (i * m + n) + 1] = in[n][2 * i + 1];
47 }
48 }
49}
50
51size_t Synthesis::inputLen() const
52{
53 return blockLen;
54}
55
56size_t Synthesis::outputLen() const
57{
58 return blockLen * m;
59}
60
61float *Synthesis::inputBuffer(size_t chan) const
62{
63 if (chan >= m)
64 return NULL;
65
66 return hOutputs[chan];
67}
68
69bool Synthesis::resetBuffer(size_t chan)
70{
71 if (chan >= m)
72 return false;
73
74 memset(hOutputs[chan], 0, blockLen * 2 * sizeof(float));
75
76 return true;
77}
78
Pau Espin Pedrolbdb970e2019-07-22 12:03:39 +020079/*
Tom Tsou35222292016-06-22 16:16:30 -070080 * Implementation based on material found in:
81 *
82 * "harris, fred, Multirate Signal Processing, Upper Saddle River, NJ,
83 * Prentice Hall, 2006."
84 */
85bool Synthesis::rotate(float *out, size_t len)
86{
87 size_t hSize = 2 * hLen * sizeof(float);
88
89 if (!checkLen(blockLen, len)) {
90 std::cout << "Length fail" << std::endl;
91 exit(1);
92 return false;
93 }
94
95 cxvec_fft(fftHandle);
96
Pau Espin Pedrolbdb970e2019-07-22 12:03:39 +020097 /*
98 * Convolve through filterbank while applying and saving sample history
Tom Tsou35222292016-06-22 16:16:30 -070099 */
100 for (size_t i = 0; i < m; i++) {
101 memcpy(&hInputs[i][2 * -hLen], hist[i], hSize);
102 memcpy(hist[i], &hInputs[i][2 * (blockLen - hLen)], hSize);
103
104 convolve_real(hInputs[i], blockLen,
105 subFilters[i], hLen,
106 hOutputs[i], blockLen,
Sylvain Munauta3934a12018-12-20 19:10:26 +0100107 0, blockLen);
Tom Tsou35222292016-06-22 16:16:30 -0700108 }
109
110 /* Interleave into output vector */
111 interleave(hOutputs, blockLen, out, m);
112
113 return true;
114}
115
116Synthesis::Synthesis(size_t m, size_t blockLen, size_t hLen)
117 : ChannelizerBase(m, blockLen, hLen)
118{
119}
120
121Synthesis::~Synthesis()
122{
123}