blob: 0522f20c5ec0d1a6c7183ef0f4eebf491e65648f [file] [log] [blame]
Tom Tsou35222292016-06-22 16:16:30 -07001/*
2 * Polyphase channelizer
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>
29
Tom Tsou35222292016-06-22 16:16:30 -070030#include "Channelizer.h"
31
32extern "C" {
Pau Espin Pedrol43fedb62018-04-24 15:22:57 +020033#include "fft.h"
34#include "convolve.h"
Tom Tsou35222292016-06-22 16:16:30 -070035}
36
37static void deinterleave(const float *in, size_t ilen,
38 float **out, size_t olen, size_t m)
39{
40 size_t i, n;
41
42 for (i = 0; i < olen; i++) {
43 for (n = 0; n < m; n++) {
44 out[m - 1 - n][2 * i + 0] = in[2 * (i * m + n) + 0];
45 out[m - 1 - n][2 * i + 1] = in[2 * (i * m + n) + 1];
46 }
47 }
48}
49
50size_t Channelizer::inputLen() const
51{
52 return blockLen * m;
53}
54
55size_t Channelizer::outputLen() const
56{
57 return blockLen;
58}
59
60float *Channelizer::outputBuffer(size_t chan) const
61{
62 if (chan >= m)
63 return NULL;
64
65 return hInputs[chan];
66}
67
Pau Espin Pedrolbdb970e2019-07-22 12:03:39 +020068/*
Tom Tsou35222292016-06-22 16:16:30 -070069 * Implementation based on material found in:
70 *
71 * "harris, fred, Multirate Signal Processing, Upper Saddle River, NJ,
72 * Prentice Hall, 2006."
73 */
74bool Channelizer::rotate(const float *in, size_t len)
75{
76 size_t hSize = 2 * hLen * sizeof(float);
77
78 if (!checkLen(blockLen, len))
79 return false;
80
81 deinterleave(in, len, hInputs, blockLen, m);
82
Pau Espin Pedrolbdb970e2019-07-22 12:03:39 +020083 /*
84 * Convolve through filterbank while applying and saving sample history
Tom Tsou35222292016-06-22 16:16:30 -070085 */
86 for (size_t i = 0; i < m; i++) {
87 memcpy(&hInputs[i][2 * -hLen], hist[i], hSize);
88 memcpy(hist[i], &hInputs[i][2 * (blockLen - hLen)], hSize);
89
90 convolve_real(hInputs[i], blockLen,
91 subFilters[i], hLen,
92 hOutputs[i], blockLen,
Sylvain Munauta3934a12018-12-20 19:10:26 +010093 0, blockLen);
Tom Tsou35222292016-06-22 16:16:30 -070094 }
95
96 cxvec_fft(fftHandle);
97
98 return true;
99}
100
Martin Hauke066fd042019-10-13 19:08:00 +0200101/* Setup channelizer parameters */
Tom Tsou35222292016-06-22 16:16:30 -0700102Channelizer::Channelizer(size_t m, size_t blockLen, size_t hLen)
103 : ChannelizerBase(m, blockLen, hLen)
104{
105}
106
107Channelizer::~Channelizer()
108{
109}