diff options
Diffstat (limited to 'Transceiver52M/Channelizer.cpp')
-rw-r--r-- | Transceiver52M/Channelizer.cpp | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/Transceiver52M/Channelizer.cpp b/Transceiver52M/Channelizer.cpp new file mode 100644 index 0000000..4b163b9 --- /dev/null +++ b/Transceiver52M/Channelizer.cpp @@ -0,0 +1,108 @@ +/* + * Polyphase channelizer + * + * Copyright (C) 2012-2014 Tom Tsou <tom@tsou.cc> + * Copyright (C) 2015 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * See the COPYING file in the main directory for details. + */ + +#include <stdlib.h> +#include <math.h> +#include <assert.h> +#include <string.h> +#include <cstdio> + +#include "Logger.h" +#include "Channelizer.h" + +extern "C" { +#include "common/fft.h" +#include "common/convolve.h" +} + +static void deinterleave(const float *in, size_t ilen, + float **out, size_t olen, size_t m) +{ + size_t i, n; + + for (i = 0; i < olen; i++) { + for (n = 0; n < m; n++) { + out[m - 1 - n][2 * i + 0] = in[2 * (i * m + n) + 0]; + out[m - 1 - n][2 * i + 1] = in[2 * (i * m + n) + 1]; + } + } +} + +size_t Channelizer::inputLen() const +{ + return blockLen * m; +} + +size_t Channelizer::outputLen() const +{ + return blockLen; +} + +float *Channelizer::outputBuffer(size_t chan) const +{ + if (chan >= m) + return NULL; + + return hInputs[chan]; +} + +/* + * Implementation based on material found in: + * + * "harris, fred, Multirate Signal Processing, Upper Saddle River, NJ, + * Prentice Hall, 2006." + */ +bool Channelizer::rotate(const float *in, size_t len) +{ + size_t hSize = 2 * hLen * sizeof(float); + + if (!checkLen(blockLen, len)) + return false; + + deinterleave(in, len, hInputs, blockLen, m); + + /* + * Convolve through filterbank while applying and saving sample history + */ + for (size_t i = 0; i < m; i++) { + memcpy(&hInputs[i][2 * -hLen], hist[i], hSize); + memcpy(hist[i], &hInputs[i][2 * (blockLen - hLen)], hSize); + + convolve_real(hInputs[i], blockLen, + subFilters[i], hLen, + hOutputs[i], blockLen, + 0, blockLen, 1, 0); + } + + cxvec_fft(fftHandle); + + return true; +} + +/* Setup channelizer paramaters */ +Channelizer::Channelizer(size_t m, size_t blockLen, size_t hLen) + : ChannelizerBase(m, blockLen, hLen) +{ +} + +Channelizer::~Channelizer() +{ +} |