diff --git a/plugins/samplesource/usrpinput/usrpinput.cpp b/plugins/samplesource/usrpinput/usrpinput.cpp index ab8cfd4d8..8c4909c9f 100644 --- a/plugins/samplesource/usrpinput/usrpinput.cpp +++ b/plugins/samplesource/usrpinput/usrpinput.cpp @@ -35,6 +35,7 @@ #include "device/deviceapi.h" #include "dsp/dspcommands.h" #include "dsp/dspengine.h" +#include "util/poweroftwo.h" #include "usrpinput.h" #include "usrpinputthread.h" #include "usrp/deviceusrpparam.h" @@ -338,8 +339,11 @@ bool USRPInput::acquireChannel() m_streamId = m_deviceShared.m_deviceParams->getDevice()->get_rx_stream(stream_args); - // Match our receive buffer size to what UHD uses + // Decimators require buffers to sized as powers of two (See #1161) m_bufSamples = m_streamId->get_max_num_samps(); + if (!isPowerOfTwo(m_bufSamples)) { + m_bufSamples = lowerPowerOfTwo(m_bufSamples); + } // Wait for reference and LO to lock DeviceUSRP::waitForLock(usrp, m_settings.m_clockSource, m_deviceShared.m_channel); diff --git a/sdrbase/util/poweroftwo.h b/sdrbase/util/poweroftwo.h new file mode 100644 index 000000000..86141eb4c --- /dev/null +++ b/sdrbase/util/poweroftwo.h @@ -0,0 +1,42 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2022 Jon Beniston, M7RCE // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as 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 General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_POWEROFTWO_H +#define INCLUDE_POWEROFTWO_H + +#include + +// Is x a power of two +// From: https://stackoverflow.com/questions/600293/how-to-check-if-a-number-is-a-power-of-2 +static bool isPowerOfTwo(uint32_t x) +{ + return (x & (x - 1)) == 0; +} + +// Calculate next power of 2 lower than x +// From: https://stackoverflow.com/questions/2679815/previous-power-of-2 +static uint32_t lowerPowerOfTwo(uint32_t x) +{ + x = x | (x >> 1); + x = x | (x >> 2); + x = x | (x >> 4); + x = x | (x >> 8); + x = x | (x >> 16); + return x - (x >> 1); +} + +#endif /* INCLUDE_POWEROFTWO_H */