| 
									
										
										
										
											2020-04-28 18:44:03 +02:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Copyright (C) 2015-2020 Edouard Griffiths, F4EXB                              //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // Symbol synchronizer or symbol clock recovery mostly encapsulating             //
 | 
					
						
							|  |  |  | // liquid-dsp's symsync "object"                                                 //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // 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 <http://www.gnu.org/licenses/>.          //
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "glspectruminterface.h"
 | 
					
						
							|  |  |  | #include "dspcommands.h"
 | 
					
						
							|  |  |  | #include "dspengine.h"
 | 
					
						
							|  |  |  | #include "fftfactory.h"
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | #include "util/messagequeue.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-28 18:44:03 +02:00
										 |  |  | #include "spectrumvis.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | #define MAX_FFT_SIZE 4096
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-06 15:10:22 +01:00
										 |  |  | #ifndef LINUX
 | 
					
						
							|  |  |  | inline double log2f(double n) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	return log(n) / log(2.0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-18 02:47:14 +02:00
										 |  |  | MESSAGE_CLASS_DEFINITION(SpectrumVis::MsgConfigureSpectrumVis, Message) | 
					
						
							| 
									
										
										
										
											2019-10-26 22:30:53 +02:00
										 |  |  | MESSAGE_CLASS_DEFINITION(SpectrumVis::MsgConfigureScalingFactor, Message) | 
					
						
							| 
									
										
										
										
											2020-04-30 09:57:05 +02:00
										 |  |  | MESSAGE_CLASS_DEFINITION(SpectrumVis::MsgConfigureWSpectrumOpenClose, Message) | 
					
						
							|  |  |  | MESSAGE_CLASS_DEFINITION(SpectrumVis::MsgConfigureWSpectrum, Message) | 
					
						
							| 
									
										
										
										
											2020-07-05 10:03:41 +02:00
										 |  |  | MESSAGE_CLASS_DEFINITION(SpectrumVis::MsgStartStop, Message) | 
					
						
							| 
									
										
										
										
											2015-08-18 02:47:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-28 23:47:15 +02:00
										 |  |  | const Real SpectrumVis::m_mult = (10.0f / log2f(10.0f)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-30 09:57:05 +02:00
										 |  |  | SpectrumVis::SpectrumVis(Real scalef) : | 
					
						
							| 
									
										
										
										
											2016-10-02 22:29:04 +02:00
										 |  |  | 	BasebandSampleSink(), | 
					
						
							| 
									
										
										
										
											2020-07-05 10:03:41 +02:00
										 |  |  |     m_running(true), | 
					
						
							| 
									
										
										
										
											2020-03-12 06:27:38 +01:00
										 |  |  | 	m_fft(nullptr), | 
					
						
							|  |  |  |     m_fftEngineSequence(0), | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	m_fftBuffer(MAX_FFT_SIZE), | 
					
						
							| 
									
										
										
										
											2018-07-06 01:34:05 +02:00
										 |  |  | 	m_powerSpectrum(MAX_FFT_SIZE), | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	m_fftBufferFill(0), | 
					
						
							| 
									
										
										
										
											2015-07-15 01:19:39 +02:00
										 |  |  | 	m_needMoreSamples(false), | 
					
						
							| 
									
										
										
										
											2018-01-22 14:07:24 +01:00
										 |  |  | 	m_scalef(scalef), | 
					
						
							| 
									
										
										
										
											2020-04-30 09:57:05 +02:00
										 |  |  | 	m_glSpectrum(nullptr), | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |     m_specMax(0.0f), | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |     m_centerFrequency(0), | 
					
						
							|  |  |  |     m_sampleRate(48000), | 
					
						
							| 
									
										
										
										
											2018-06-30 22:30:42 +02:00
										 |  |  | 	m_ofs(0), | 
					
						
							| 
									
										
										
										
											2018-07-06 01:34:05 +02:00
										 |  |  |     m_powFFTDiv(1.0), | 
					
						
							| 
									
										
										
										
											2015-10-22 02:27:56 +02:00
										 |  |  | 	m_mutex(QMutex::Recursive) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-08-12 09:03:02 +02:00
										 |  |  | 	setObjectName("SpectrumVis"); | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |     applySettings(m_settings, true); | 
					
						
							| 
									
										
										
										
											2020-04-30 09:57:05 +02:00
										 |  |  |     //m_wsSpectrum.openSocket(); // FIXME: conditional
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SpectrumVis::~SpectrumVis() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-03-12 06:27:38 +01:00
										 |  |  |     FFTFactory *fftFactory = DSPEngine::instance()->getFFTFactory(); | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |     fftFactory->releaseEngine(m_settings.m_fftSize, false, m_fftEngineSequence); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-30 09:57:05 +02:00
										 |  |  | void SpectrumVis::openWSSpectrum() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MsgConfigureWSpectrumOpenClose *cmd = new MsgConfigureWSpectrumOpenClose(true); | 
					
						
							|  |  |  |     getInputMessageQueue()->push(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void SpectrumVis::closeWSSpectrum() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MsgConfigureWSpectrumOpenClose *cmd = new MsgConfigureWSpectrumOpenClose(false); | 
					
						
							|  |  |  |     getInputMessageQueue()->push(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-01 02:23:26 +02:00
										 |  |  | void SpectrumVis::configure( | 
					
						
							|  |  |  |     int fftSize, | 
					
						
							|  |  |  |     float refLevel, | 
					
						
							|  |  |  |     float powerRange, | 
					
						
							|  |  |  |     int overlapPercent, | 
					
						
							|  |  |  |     unsigned int averagingNb, | 
					
						
							|  |  |  |     AvgMode averagingMode, | 
					
						
							|  |  |  |     FFTWindow::Function window, | 
					
						
							|  |  |  |     bool linear) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |     GLSpectrumSettings settings = m_settings; | 
					
						
							|  |  |  |     settings.m_fftSize = fftSize; | 
					
						
							|  |  |  |     settings.m_refLevel = refLevel; | 
					
						
							|  |  |  |     settings.m_powerRange = powerRange; | 
					
						
							|  |  |  |     settings.m_fftOverlap = overlapPercent; | 
					
						
							|  |  |  |     settings.m_averagingMode = (GLSpectrumSettings::AveragingMode) averagingMode; | 
					
						
							|  |  |  |     settings.m_averagingIndex = GLSpectrumSettings::getAveragingIndex(averagingNb, settings.m_averagingMode); | 
					
						
							|  |  |  |     settings.m_fftWindow = window; | 
					
						
							|  |  |  |     settings.m_linear = linear; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     MsgConfigureSpectrumVis* cmd = MsgConfigureSpectrumVis::create(settings, false); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-01 02:23:26 +02:00
										 |  |  | 	getInputMessageQueue()->push(cmd); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  | void SpectrumVis::setScalef(Real scalef) | 
					
						
							| 
									
										
										
										
											2019-10-26 22:30:53 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     MsgConfigureScalingFactor* cmd = new MsgConfigureScalingFactor(scalef); | 
					
						
							|  |  |  |     getInputMessageQueue()->push(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-30 09:57:05 +02:00
										 |  |  | void SpectrumVis::configureWSSpectrum(const QString& address, uint16_t port) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MsgConfigureWSpectrum* cmd = new MsgConfigureWSpectrum(address, port); | 
					
						
							|  |  |  |     getInputMessageQueue()->push(cmd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-25 20:13:34 +02:00
										 |  |  | void SpectrumVis::feedTriggered(const SampleVector::const_iterator& triggerPoint, const SampleVector::const_iterator& end, bool positiveOnly) | 
					
						
							| 
									
										
										
										
											2015-07-15 01:19:39 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-07-21 22:52:52 +02:00
										 |  |  | 	feed(triggerPoint, end, positiveOnly); // normal feed from trigger point
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							| 
									
										
										
										
											2015-07-15 01:19:39 +02:00
										 |  |  | 	if (triggerPoint == end) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		// the following piece of code allows to terminate the FFT that ends past the end of scope captured data
 | 
					
						
							|  |  |  | 		// that is the spectrum will include the captured data
 | 
					
						
							|  |  |  | 		// just do nothing if you want the spectrum to be included inside the scope captured data
 | 
					
						
							|  |  |  | 		// that is to drop the FFT that dangles past the end of captured data
 | 
					
						
							|  |  |  | 		if (m_needMoreSamples) { | 
					
						
							|  |  |  | 			feed(begin, end, positiveOnly); | 
					
						
							|  |  |  | 			m_needMoreSamples = false;      // force finish
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		feed(triggerPoint, end, positiveOnly); // normal feed from trigger point
 | 
					
						
							| 
									
										
										
										
											2015-07-21 22:52:52 +02:00
										 |  |  | 	}*/ | 
					
						
							| 
									
										
										
										
											2015-07-15 01:19:39 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  | void SpectrumVis::feed(const Complex *begin, unsigned int length) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!m_glSpectrum && !m_wsSpectrum.socketOpened()) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!m_mutex.tryLock(0)) { // prevent conflicts with configuration process
 | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Complex c; | 
					
						
							|  |  |  |     Real v; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |     if (m_settings.m_averagingMode == GLSpectrumSettings::AvgModeNone) | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |         for (unsigned int i = 0; i < m_settings.m_fftSize; i++) | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             if (i < length) { | 
					
						
							|  |  |  |                 c = begin[i]; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 c = Complex{0,0}; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             v = c.real() * c.real() + c.imag() * c.imag(); | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |             v = m_settings.m_linear ? v/m_powFFTDiv : m_mult * log2f(v) + m_ofs; | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |             m_powerSpectrum[i] = v; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // send new data to visualisation
 | 
					
						
							|  |  |  |         if (m_glSpectrum) { | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |             m_glSpectrum->newSpectrum(m_powerSpectrum, m_settings.m_fftSize); | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // web socket spectrum connections
 | 
					
						
							|  |  |  |         if (m_wsSpectrum.socketOpened()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             m_wsSpectrum.newSpectrum( | 
					
						
							|  |  |  |                 m_powerSpectrum, | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                 m_settings.m_fftSize, | 
					
						
							|  |  |  |                 m_settings.m_refLevel, | 
					
						
							|  |  |  |                 m_settings.m_powerRange, | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                 m_centerFrequency, | 
					
						
							|  |  |  |                 m_sampleRate, | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                 m_settings.m_linear | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |             ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |     else if (m_settings.m_averagingMode == GLSpectrumSettings::AvgModeMoving) | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |         for (unsigned int i = 0; i < m_settings.m_fftSize; i++) | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             if (i < length) { | 
					
						
							|  |  |  |                 c = begin[i]; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 c = Complex{0,0}; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             v = c.real() * c.real() + c.imag() * c.imag(); | 
					
						
							|  |  |  |             v = m_movingAverage.storeAndGetAvg(v, i); | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |             v = m_settings.m_linear ? v/m_powFFTDiv : m_mult * log2f(v) + m_ofs; | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |             m_powerSpectrum[i] = v; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // send new data to visualisation
 | 
					
						
							|  |  |  |         if (m_glSpectrum) { | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |             m_glSpectrum->newSpectrum(m_powerSpectrum, m_settings.m_fftSize); | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // web socket spectrum connections
 | 
					
						
							|  |  |  |         if (m_wsSpectrum.socketOpened()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             m_wsSpectrum.newSpectrum( | 
					
						
							|  |  |  |                 m_powerSpectrum, | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                 m_settings.m_fftSize, | 
					
						
							|  |  |  |                 m_settings.m_refLevel, | 
					
						
							|  |  |  |                 m_settings.m_powerRange, | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                 m_centerFrequency, | 
					
						
							|  |  |  |                 m_sampleRate, | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                 m_settings.m_linear | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |             ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_movingAverage.nextAverage(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |     else if (m_settings.m_averagingMode == GLSpectrumSettings::AvgModeFixed) | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         double avg; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |         for (unsigned int i = 0; i < m_settings.m_fftSize; i++) | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             if (i < length) { | 
					
						
							|  |  |  |                 c = begin[i]; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 c = Complex{0,0}; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             v = c.real() * c.real() + c.imag() * c.imag(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // result available
 | 
					
						
							|  |  |  |             if (m_fixedAverage.storeAndGetAvg(avg, v, i)) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                 avg = m_settings.m_linear ? avg/m_powFFTDiv : m_mult * log2f(avg) + m_ofs; | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                 m_powerSpectrum[i] = avg; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // result available
 | 
					
						
							|  |  |  |         if (m_fixedAverage.nextAverage()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // send new data to visualisation
 | 
					
						
							|  |  |  |             if (m_glSpectrum) { | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                 m_glSpectrum->newSpectrum(m_powerSpectrum, m_settings.m_fftSize); | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // web socket spectrum connections
 | 
					
						
							|  |  |  |             if (m_wsSpectrum.socketOpened()) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 m_wsSpectrum.newSpectrum( | 
					
						
							|  |  |  |                     m_powerSpectrum, | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                     m_settings.m_fftSize, | 
					
						
							|  |  |  |                     m_settings.m_refLevel, | 
					
						
							|  |  |  |                     m_settings.m_powerRange, | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                     m_centerFrequency, | 
					
						
							|  |  |  |                     m_sampleRate, | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                     m_settings.m_linear | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                 ); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |     else if (m_settings.m_averagingMode == GLSpectrumSettings::AvgModeMax) | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         double max; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |         for (unsigned int i = 0; i < m_settings.m_fftSize; i++) | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             if (i < length) { | 
					
						
							|  |  |  |                 c = begin[i]; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 c = Complex{0,0}; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             v = c.real() * c.real() + c.imag() * c.imag(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // result available
 | 
					
						
							|  |  |  |             if (m_max.storeAndGetMax(max, v, i)) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                 max = m_settings.m_linear ? max/m_powFFTDiv : m_mult * log2f(max) + m_ofs; | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                 m_powerSpectrum[i] = max; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // result available
 | 
					
						
							|  |  |  |         if (m_max.nextMax()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // send new data to visualisation
 | 
					
						
							|  |  |  |             if (m_glSpectrum) { | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                 m_glSpectrum->newSpectrum(m_powerSpectrum, m_settings.m_fftSize); | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // web socket spectrum connections
 | 
					
						
							|  |  |  |             if (m_wsSpectrum.socketOpened()) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 m_wsSpectrum.newSpectrum( | 
					
						
							|  |  |  |                     m_powerSpectrum, | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                     m_settings.m_fftSize, | 
					
						
							|  |  |  |                     m_settings.m_refLevel, | 
					
						
							|  |  |  |                     m_settings.m_powerRange, | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                     m_centerFrequency, | 
					
						
							|  |  |  |                     m_sampleRate, | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                     m_settings.m_linear | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                 ); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_mutex.unlock(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 08:24:23 +02:00
										 |  |  | void SpectrumVis::feed(const SampleVector::const_iterator& cbegin, const SampleVector::const_iterator& end, bool positiveOnly) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-05 10:03:41 +02:00
										 |  |  |     if (!m_running) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-08-25 08:24:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-05 10:03:41 +02:00
										 |  |  | 	// if no visualisation is set, send the samples to /dev/null
 | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  | 	if (!m_glSpectrum && !m_wsSpectrum.socketOpened()) { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2015-08-25 08:24:23 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-21 08:58:33 +01:00
										 |  |  |     if (!m_mutex.tryLock(0)) { // prevent conflicts with configuration process
 | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 08:24:23 +02:00
										 |  |  | 	SampleVector::const_iterator begin(cbegin); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (begin < end) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-08-17 08:29:34 +02:00
										 |  |  | 		std::size_t todo = end - begin; | 
					
						
							|  |  |  | 		std::size_t samplesNeeded = m_refillSize - m_fftBufferFill; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 08:24:23 +02:00
										 |  |  | 		if (todo >= samplesNeeded) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 			// fill up the buffer
 | 
					
						
							|  |  |  | 			std::vector<Complex>::iterator it = m_fftBuffer.begin() + m_fftBufferFill; | 
					
						
							| 
									
										
										
										
											2015-08-25 08:24:23 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			for (std::size_t i = 0; i < samplesNeeded; ++i, ++begin) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-01-22 14:07:24 +01:00
										 |  |  | 				*it++ = Complex(begin->real() / m_scalef, begin->imag() / m_scalef); | 
					
						
							| 
									
										
										
										
											2015-08-25 08:24:23 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// apply fft window (and copy from m_fftBuffer to m_fftIn)
 | 
					
						
							|  |  |  | 			m_window.apply(&m_fftBuffer[0], m_fft->in()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// calculate FFT
 | 
					
						
							|  |  |  | 			m_fft->transform(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// extract power spectrum and reorder buckets
 | 
					
						
							|  |  |  | 			const Complex* fftOut = m_fft->out(); | 
					
						
							| 
									
										
										
										
											2014-06-17 20:13:49 +01:00
										 |  |  | 			Complex c; | 
					
						
							|  |  |  | 			Real v; | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  | 			std::size_t halfSize = m_settings.m_fftSize / 2; | 
					
						
							| 
									
										
										
										
											2014-06-15 09:32:25 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  | 			if (m_settings.m_averagingMode == GLSpectrumSettings::AvgModeNone) | 
					
						
							| 
									
										
										
										
											2018-07-01 22:36:36 +02:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                 m_specMax = 0.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-01 22:36:36 +02:00
										 |  |  |                 if ( positiveOnly ) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     for (std::size_t i = 0; i < halfSize; i++) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         c = fftOut[i]; | 
					
						
							|  |  |  |                         v = c.real() * c.real() + c.imag() * c.imag(); | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                         m_specMax = v > m_specMax ? v : m_specMax; | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                         v = m_settings.m_linear ? v/m_powFFTDiv : m_mult * log2f(v) + m_ofs; | 
					
						
							| 
									
										
										
										
											2018-07-06 01:34:05 +02:00
										 |  |  |                         m_powerSpectrum[i * 2] = v; | 
					
						
							|  |  |  |                         m_powerSpectrum[i * 2 + 1] = v; | 
					
						
							| 
									
										
										
										
											2018-07-01 22:36:36 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     for (std::size_t i = 0; i < halfSize; i++) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         c = fftOut[i + halfSize]; | 
					
						
							|  |  |  |                         v = c.real() * c.real() + c.imag() * c.imag(); | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                         m_specMax = v > m_specMax ? v : m_specMax; | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                         v = m_settings.m_linear ? v/m_powFFTDiv : m_mult * log2f(v) + m_ofs; | 
					
						
							| 
									
										
										
										
											2018-07-06 01:34:05 +02:00
										 |  |  |                         m_powerSpectrum[i] = v; | 
					
						
							| 
									
										
										
										
											2018-07-01 22:36:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         c = fftOut[i]; | 
					
						
							|  |  |  |                         v = c.real() * c.real() + c.imag() * c.imag(); | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                         m_specMax = v > m_specMax ? v : m_specMax; | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                         v = m_settings.m_linear ? v/m_powFFTDiv : m_mult * log2f(v) + m_ofs; | 
					
						
							| 
									
										
										
										
											2018-07-06 01:34:05 +02:00
										 |  |  |                         m_powerSpectrum[i + halfSize] = v; | 
					
						
							| 
									
										
										
										
											2018-07-01 22:36:36 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // send new data to visualisation
 | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                 if (m_glSpectrum) { | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                     m_glSpectrum->newSpectrum(m_powerSpectrum, m_settings.m_fftSize); | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // web socket spectrum connections
 | 
					
						
							|  |  |  |                 if (m_wsSpectrum.socketOpened()) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     m_wsSpectrum.newSpectrum( | 
					
						
							|  |  |  |                         m_powerSpectrum, | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                         m_settings.m_fftSize, | 
					
						
							|  |  |  |                         m_settings.m_refLevel, | 
					
						
							|  |  |  |                         m_settings.m_powerRange, | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                         m_centerFrequency, | 
					
						
							|  |  |  |                         m_sampleRate, | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                         m_settings.m_linear | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                     ); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2018-07-01 22:36:36 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  | 			else if (m_settings.m_averagingMode == GLSpectrumSettings::AvgModeMoving) | 
					
						
							| 
									
										
										
										
											2015-08-25 08:24:23 +02:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                 m_specMax = 0.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-01 02:16:59 +02:00
										 |  |  | 	            if ( positiveOnly ) | 
					
						
							|  |  |  | 	            { | 
					
						
							|  |  |  | 	                for (std::size_t i = 0; i < halfSize; i++) | 
					
						
							|  |  |  | 	                { | 
					
						
							|  |  |  | 	                    c = fftOut[i]; | 
					
						
							|  |  |  | 	                    v = c.real() * c.real() + c.imag() * c.imag(); | 
					
						
							|  |  |  | 	                    v = m_movingAverage.storeAndGetAvg(v, i); | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                         m_specMax = v > m_specMax ? v : m_specMax; | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  | 	                    v = m_settings.m_linear ? v/m_powFFTDiv : m_mult * log2f(v) + m_ofs; | 
					
						
							| 
									
										
										
										
											2018-07-06 01:34:05 +02:00
										 |  |  | 	                    m_powerSpectrum[i * 2] = v; | 
					
						
							|  |  |  | 	                    m_powerSpectrum[i * 2 + 1] = v; | 
					
						
							| 
									
										
										
										
											2018-07-01 02:16:59 +02:00
										 |  |  | 	                } | 
					
						
							|  |  |  | 	            } | 
					
						
							|  |  |  | 	            else | 
					
						
							|  |  |  | 	            { | 
					
						
							|  |  |  | 	                for (std::size_t i = 0; i < halfSize; i++) | 
					
						
							|  |  |  | 	                { | 
					
						
							|  |  |  | 	                    c = fftOut[i + halfSize]; | 
					
						
							|  |  |  | 	                    v = c.real() * c.real() + c.imag() * c.imag(); | 
					
						
							|  |  |  | 	                    v = m_movingAverage.storeAndGetAvg(v, i+halfSize); | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                         m_specMax = v > m_specMax ? v : m_specMax; | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  | 	                    v = m_settings.m_linear ? v/m_powFFTDiv : m_mult * log2f(v) + m_ofs; | 
					
						
							| 
									
										
										
										
											2018-07-06 01:34:05 +02:00
										 |  |  | 	                    m_powerSpectrum[i] = v; | 
					
						
							| 
									
										
										
										
											2018-07-01 02:16:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	                    c = fftOut[i]; | 
					
						
							|  |  |  | 	                    v = c.real() * c.real() + c.imag() * c.imag(); | 
					
						
							|  |  |  | 	                    v = m_movingAverage.storeAndGetAvg(v, i); | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                         m_specMax = v > m_specMax ? v : m_specMax; | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  | 	                    v = m_settings.m_linear ? v/m_powFFTDiv : m_mult * log2f(v) + m_ofs; | 
					
						
							| 
									
										
										
										
											2018-07-06 01:34:05 +02:00
										 |  |  | 	                    m_powerSpectrum[i + halfSize] = v; | 
					
						
							| 
									
										
										
										
											2018-07-01 02:16:59 +02:00
										 |  |  | 	                } | 
					
						
							|  |  |  | 	            } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	            // send new data to visualisation
 | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                 if (m_glSpectrum) { | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |     	            m_glSpectrum->newSpectrum(m_powerSpectrum, m_settings.m_fftSize); | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // web socket spectrum connections
 | 
					
						
							|  |  |  |                 if (m_wsSpectrum.socketOpened()) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     m_wsSpectrum.newSpectrum( | 
					
						
							|  |  |  |                         m_powerSpectrum, | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                         m_settings.m_fftSize, | 
					
						
							|  |  |  |                         m_settings.m_refLevel, | 
					
						
							|  |  |  |                         m_settings.m_powerRange, | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                         m_centerFrequency, | 
					
						
							|  |  |  |                         m_sampleRate, | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                         m_settings.m_linear | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                     ); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-01 02:16:59 +02:00
										 |  |  | 	            m_movingAverage.nextAverage(); | 
					
						
							| 
									
										
										
										
											2015-08-25 08:24:23 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  | 			else if (m_settings.m_averagingMode == GLSpectrumSettings::AvgModeFixed) | 
					
						
							| 
									
										
										
										
											2015-08-25 08:24:23 +02:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-07-01 02:16:59 +02:00
										 |  |  | 			    double avg; | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                 Real specMax = 0.0f; | 
					
						
							| 
									
										
										
										
											2018-07-01 02:16:59 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 if ( positiveOnly ) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     for (std::size_t i = 0; i < halfSize; i++) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         c = fftOut[i]; | 
					
						
							|  |  |  |                         v = c.real() * c.real() + c.imag() * c.imag(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                         // result available
 | 
					
						
							| 
									
										
										
										
											2018-07-01 02:16:59 +02:00
										 |  |  |                         if (m_fixedAverage.storeAndGetAvg(avg, v, i)) | 
					
						
							|  |  |  |                         { | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                             specMax = avg > specMax ? avg : specMax; | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                             avg = m_settings.m_linear ? avg/m_powFFTDiv : m_mult * log2f(avg) + m_ofs; | 
					
						
							| 
									
										
										
										
											2018-07-06 01:34:05 +02:00
										 |  |  |                             m_powerSpectrum[i * 2] = avg; | 
					
						
							|  |  |  |                             m_powerSpectrum[i * 2 + 1] = avg; | 
					
						
							| 
									
										
										
										
											2018-07-01 02:16:59 +02:00
										 |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     for (std::size_t i = 0; i < halfSize; i++) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         c = fftOut[i + halfSize]; | 
					
						
							|  |  |  |                         v = c.real() * c.real() + c.imag() * c.imag(); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                         // result available
 | 
					
						
							| 
									
										
										
										
											2018-07-01 02:16:59 +02:00
										 |  |  |                         if (m_fixedAverage.storeAndGetAvg(avg, v, i+halfSize)) | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                         { | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                             specMax = avg > specMax ? avg : specMax; | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                             avg = m_settings.m_linear ? avg/m_powFFTDiv : m_mult * log2f(avg) + m_ofs; | 
					
						
							| 
									
										
										
										
											2018-07-06 01:34:05 +02:00
										 |  |  |                             m_powerSpectrum[i] = avg; | 
					
						
							| 
									
										
										
										
											2018-07-01 02:16:59 +02:00
										 |  |  |                         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         c = fftOut[i]; | 
					
						
							|  |  |  |                         v = c.real() * c.real() + c.imag() * c.imag(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                         // result available
 | 
					
						
							| 
									
										
										
										
											2018-07-01 02:16:59 +02:00
										 |  |  |                         if (m_fixedAverage.storeAndGetAvg(avg, v, i)) | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                         { | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                             specMax = avg > specMax ? avg : specMax; | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                             avg = m_settings.m_linear ? avg/m_powFFTDiv : m_mult * log2f(avg) + m_ofs; | 
					
						
							| 
									
										
										
										
											2018-07-06 01:34:05 +02:00
										 |  |  |                             m_powerSpectrum[i + halfSize] = avg; | 
					
						
							| 
									
										
										
										
											2018-07-01 02:16:59 +02:00
										 |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                 // result available
 | 
					
						
							|  |  |  |                 if (m_fixedAverage.nextAverage()) | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                     m_specMax = specMax; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                     // send new data to visualisation
 | 
					
						
							|  |  |  |                     if (m_glSpectrum) { | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                         m_glSpectrum->newSpectrum(m_powerSpectrum, m_settings.m_fftSize); | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     // web socket spectrum connections
 | 
					
						
							|  |  |  |                     if (m_wsSpectrum.socketOpened()) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         m_wsSpectrum.newSpectrum( | 
					
						
							|  |  |  |                             m_powerSpectrum, | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                             m_settings.m_fftSize, | 
					
						
							|  |  |  |                             m_settings.m_refLevel, | 
					
						
							|  |  |  |                             m_settings.m_powerRange, | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                             m_centerFrequency, | 
					
						
							|  |  |  |                             m_sampleRate, | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                             m_settings.m_linear | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                         ); | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2018-10-12 08:47:14 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  | 			else if (m_settings.m_averagingMode == GLSpectrumSettings::AvgModeMax) | 
					
						
							| 
									
										
										
										
											2018-10-12 08:47:14 +02:00
										 |  |  | 			{ | 
					
						
							|  |  |  | 			    double max; | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                 Real specMax = 0.0f; | 
					
						
							| 
									
										
										
										
											2018-10-12 08:47:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 if ( positiveOnly ) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     for (std::size_t i = 0; i < halfSize; i++) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         c = fftOut[i]; | 
					
						
							|  |  |  |                         v = c.real() * c.real() + c.imag() * c.imag(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                         // result available
 | 
					
						
							| 
									
										
										
										
											2018-10-12 08:47:14 +02:00
										 |  |  |                         if (m_max.storeAndGetMax(max, v, i)) | 
					
						
							|  |  |  |                         { | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                             specMax = max > specMax ? max : specMax; | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                             max = m_settings.m_linear ? max/m_powFFTDiv : m_mult * log2f(max) + m_ofs; | 
					
						
							| 
									
										
										
										
											2018-10-12 08:47:14 +02:00
										 |  |  |                             m_powerSpectrum[i * 2] = max; | 
					
						
							|  |  |  |                             m_powerSpectrum[i * 2 + 1] = max; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     for (std::size_t i = 0; i < halfSize; i++) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         c = fftOut[i + halfSize]; | 
					
						
							|  |  |  |                         v = c.real() * c.real() + c.imag() * c.imag(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                         // result available
 | 
					
						
							| 
									
										
										
										
											2018-10-12 08:47:14 +02:00
										 |  |  |                         if (m_max.storeAndGetMax(max, v, i+halfSize)) | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                         { | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                             specMax = max > specMax ? max : specMax; | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                             max = m_settings.m_linear ? max/m_powFFTDiv : m_mult * log2f(max) + m_ofs; | 
					
						
							| 
									
										
										
										
											2018-10-12 08:47:14 +02:00
										 |  |  |                             m_powerSpectrum[i] = max; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         c = fftOut[i]; | 
					
						
							|  |  |  |                         v = c.real() * c.real() + c.imag() * c.imag(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                         // result available
 | 
					
						
							| 
									
										
										
										
											2018-10-12 08:47:14 +02:00
										 |  |  |                         if (m_max.storeAndGetMax(max, v, i)) | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                         { | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                             specMax = max > specMax ? max : specMax; | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                             max = m_settings.m_linear ? max/m_powFFTDiv : m_mult * log2f(max) + m_ofs; | 
					
						
							| 
									
										
										
										
											2018-10-12 08:47:14 +02:00
										 |  |  |                             m_powerSpectrum[i + halfSize] = max; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                 // result available
 | 
					
						
							|  |  |  |                 if (m_max.nextMax()) | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2020-07-16 16:58:45 +02:00
										 |  |  |                     m_specMax = specMax; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                     // send new data to visualisation
 | 
					
						
							|  |  |  |                     if (m_glSpectrum) { | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                         m_glSpectrum->newSpectrum(m_powerSpectrum, m_settings.m_fftSize); | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     // web socket spectrum connections
 | 
					
						
							|  |  |  |                     if (m_wsSpectrum.socketOpened()) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         m_wsSpectrum.newSpectrum( | 
					
						
							|  |  |  |                             m_powerSpectrum, | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                             m_settings.m_fftSize, | 
					
						
							|  |  |  |                             m_settings.m_refLevel, | 
					
						
							|  |  |  |                             m_settings.m_powerRange, | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                             m_centerFrequency, | 
					
						
							|  |  |  |                             m_sampleRate, | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |                             m_settings.m_linear | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  |                         ); | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2018-07-01 02:16:59 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// advance buffer respecting the fft overlap factor
 | 
					
						
							|  |  |  | 			std::copy(m_fftBuffer.begin() + m_refillSize, m_fftBuffer.end(), m_fftBuffer.begin()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// start over
 | 
					
						
							|  |  |  | 			m_fftBufferFill = m_overlapSize; | 
					
						
							| 
									
										
										
										
											2015-07-15 01:19:39 +02:00
										 |  |  | 			m_needMoreSamples = false; | 
					
						
							| 
									
										
										
										
											2015-08-25 08:24:23 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 			// not enough samples for FFT - just fill in new data and return
 | 
					
						
							|  |  |  | 			for(std::vector<Complex>::iterator it = m_fftBuffer.begin() + m_fftBufferFill; begin < end; ++begin) | 
					
						
							| 
									
										
										
										
											2015-08-25 08:24:23 +02:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2018-01-22 14:07:24 +01:00
										 |  |  | 				*it++ = Complex(begin->real() / m_scalef, begin->imag() / m_scalef); | 
					
						
							| 
									
										
										
										
											2015-08-25 08:24:23 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 			m_fftBufferFill += todo; | 
					
						
							| 
									
										
										
										
											2015-07-15 01:19:39 +02:00
										 |  |  | 			m_needMoreSamples = true; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-11-21 08:58:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	 m_mutex.unlock(); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void SpectrumVis::start() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-10 00:08:42 +02:00
										 |  |  |     setRunning(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (getMessageQueueToGUI()) // propagate to GUI if any
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         MsgStartStop *msg = MsgStartStop::create(true); | 
					
						
							|  |  |  |         getMessageQueueToGUI()->push(msg); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void SpectrumVis::stop() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-10 00:08:42 +02:00
										 |  |  |     setRunning(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (getMessageQueueToGUI()) // propagate to GUI if any
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         MsgStartStop *msg = MsgStartStop::create(false); | 
					
						
							|  |  |  |         getMessageQueueToGUI()->push(msg); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-14 05:00:28 +02:00
										 |  |  | bool SpectrumVis::handleMessage(const Message& message) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-04-30 09:57:05 +02:00
										 |  |  |     if (DSPSignalNotification::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // This is coming from device engine and will apply to main spectrum
 | 
					
						
							|  |  |  |         DSPSignalNotification& notif = (DSPSignalNotification&) message; | 
					
						
							|  |  |  |         qDebug() << "SpectrumVis::handleMessage: DSPSignalNotification:" | 
					
						
							|  |  |  |             << " centerFrequency: " << notif.getCenterFrequency() | 
					
						
							|  |  |  |             << " sampleRate: " << notif.getSampleRate(); | 
					
						
							|  |  |  |         handleConfigureDSP(notif.getCenterFrequency(), notif.getSampleRate()); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 	else if (MsgConfigureSpectrumVis::match(message)) | 
					
						
							| 
									
										
										
										
											2015-08-14 05:00:28 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |         MsgConfigureSpectrumVis& cfg = (MsgConfigureSpectrumVis&) message; | 
					
						
							|  |  |  |         qDebug() << "SpectrumVis::handleMessage: MsgConfigureSpectrumVis"; | 
					
						
							|  |  |  |         applySettings(cfg.getSettings(), cfg.getForce()); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-10-26 22:30:53 +02:00
										 |  |  |     else if (MsgConfigureScalingFactor::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         MsgConfigureScalingFactor& conf = (MsgConfigureScalingFactor&) message; | 
					
						
							|  |  |  |         handleScalef(conf.getScalef()); | 
					
						
							|  |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2020-04-30 09:57:05 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else if (MsgConfigureWSpectrumOpenClose::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         MsgConfigureWSpectrumOpenClose& conf = (MsgConfigureWSpectrumOpenClose&) message; | 
					
						
							|  |  |  |         handleWSOpenClose(conf.getOpenClose()); | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2020-04-30 09:57:05 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else if (MsgConfigureWSpectrum::match(message)) { | 
					
						
							|  |  |  |         MsgConfigureWSpectrum& conf = (MsgConfigureWSpectrum&) message; | 
					
						
							|  |  |  |         handleConfigureWSSpectrum(conf.getAddress(), conf.getPort()); | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2019-10-26 22:30:53 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-07-10 00:08:42 +02:00
										 |  |  |     else if (MsgStartStop::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-07-05 10:03:41 +02:00
										 |  |  |         MsgStartStop& cmd = (MsgStartStop&) message; | 
					
						
							| 
									
										
										
										
											2020-07-10 00:08:42 +02:00
										 |  |  |         setRunning(cmd.getStartStop()); | 
					
						
							| 
									
										
										
										
											2020-07-05 10:03:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-08-14 05:00:28 +02:00
										 |  |  | 	else | 
					
						
							| 
									
										
										
										
											2015-06-23 20:05:28 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2015-08-14 05:00:28 +02:00
										 |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2015-06-23 20:05:28 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  | void SpectrumVis::applySettings(const GLSpectrumSettings& settings, bool force) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |     QMutexLocker mutexLocker(&m_mutex); | 
					
						
							| 
									
										
										
										
											2015-08-14 05:00:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |     int fftSize = settings.m_fftSize > MAX_FFT_SIZE ? | 
					
						
							|  |  |  |         MAX_FFT_SIZE : | 
					
						
							|  |  |  |         settings.m_fftSize < 64 ? | 
					
						
							|  |  |  |             64 : | 
					
						
							|  |  |  |             settings.m_fftSize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int overlapPercent = settings.m_fftOverlap > 100 ? | 
					
						
							|  |  |  |         100 : | 
					
						
							|  |  |  |         settings.m_fftOverlap < 0 ? | 
					
						
							|  |  |  |             0 : | 
					
						
							|  |  |  |             settings.m_fftOverlap; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     qDebug() << "SpectrumVis::applySettings:" | 
					
						
							|  |  |  |         << " m_fftSize: " << fftSize | 
					
						
							|  |  |  |         << " m_fftWindow: " << settings.m_fftWindow | 
					
						
							|  |  |  |         << " m_fftOverlap: " << overlapPercent | 
					
						
							|  |  |  |         << " m_averagingIndex: " << settings.m_averagingIndex | 
					
						
							|  |  |  |         << " m_averagingMode: " << settings.m_averagingMode | 
					
						
							|  |  |  |         << " m_refLevel: " << settings.m_refLevel | 
					
						
							|  |  |  |         << " m_powerRange: " << settings.m_powerRange | 
					
						
							|  |  |  |         << " m_linear: " << settings.m_linear | 
					
						
							|  |  |  |         << " force: " << force; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((fftSize != m_settings.m_fftSize) || force) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         FFTFactory *fftFactory = DSPEngine::instance()->getFFTFactory(); | 
					
						
							| 
									
										
										
										
											2020-05-01 04:57:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // release previous engine allocation if any
 | 
					
						
							|  |  |  |         if (m_fft) { | 
					
						
							|  |  |  |             fftFactory->releaseEngine(m_settings.m_fftSize, false, m_fftEngineSequence); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |         m_fftEngineSequence = fftFactory->getEngine(fftSize, false, &m_fft); | 
					
						
							|  |  |  |         m_ofs = 20.0f * log10f(1.0f / fftSize); | 
					
						
							|  |  |  |         m_powFFTDiv = fftSize * fftSize; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |     if ((fftSize != m_settings.m_fftSize) | 
					
						
							|  |  |  |      || (settings.m_fftWindow != m_settings.m_fftWindow) || force) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_window.create(settings.m_fftWindow, fftSize); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-01 02:12:30 +02:00
										 |  |  |     if ((fftSize != m_settings.m_fftSize) | 
					
						
							|  |  |  |      || (overlapPercent != m_settings.m_fftOverlap) || force) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_overlapSize = (fftSize * overlapPercent) / 100; | 
					
						
							|  |  |  |         m_refillSize = fftSize - m_overlapSize; | 
					
						
							|  |  |  |         m_fftBufferFill = m_overlapSize; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((fftSize != m_settings.m_fftSize) | 
					
						
							|  |  |  |      || (settings.m_averagingIndex != m_settings.m_averagingIndex) | 
					
						
							|  |  |  |      || (settings.m_averagingMode != m_settings.m_averagingMode) || force) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         unsigned int averagingValue = GLSpectrumSettings::getAveragingValue(settings.m_averagingIndex, settings.m_averagingMode); | 
					
						
							|  |  |  |         m_movingAverage.resize(fftSize, averagingValue > 1000 ? 1000 : averagingValue); // Capping to avoid out of memory condition
 | 
					
						
							|  |  |  |         m_fixedAverage.resize(fftSize, averagingValue); | 
					
						
							|  |  |  |         m_max.resize(fftSize, averagingValue); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_settings = settings; | 
					
						
							|  |  |  |     m_settings.m_fftSize = fftSize; | 
					
						
							|  |  |  |     m_settings.m_fftOverlap = overlapPercent; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-10-26 22:30:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-29 17:41:17 +02:00
										 |  |  | void SpectrumVis::handleConfigureDSP(uint64_t centerFrequency, int sampleRate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QMutexLocker mutexLocker(&m_mutex); | 
					
						
							|  |  |  |     m_centerFrequency = centerFrequency; | 
					
						
							|  |  |  |     m_sampleRate = sampleRate; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-26 22:30:53 +02:00
										 |  |  | void SpectrumVis::handleScalef(Real scalef) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QMutexLocker mutexLocker(&m_mutex); | 
					
						
							|  |  |  |     m_scalef = scalef; | 
					
						
							| 
									
										
										
										
											2020-04-30 09:57:05 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void SpectrumVis::handleWSOpenClose(bool openClose) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QMutexLocker mutexLocker(&m_mutex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (openClose) { | 
					
						
							|  |  |  |         m_wsSpectrum.openSocket(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         m_wsSpectrum.closeSocket(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void SpectrumVis::handleConfigureWSSpectrum(const QString& address, uint16_t port) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QMutexLocker mutexLocker(&m_mutex); | 
					
						
							|  |  |  |     bool wsSpectrumWasOpen = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_wsSpectrum.socketOpened()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_wsSpectrum.closeSocket(); | 
					
						
							|  |  |  |         wsSpectrumWasOpen = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_wsSpectrum.setListeningAddress(address); | 
					
						
							|  |  |  |     m_wsSpectrum.setPort(port); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (wsSpectrumWasOpen) { | 
					
						
							|  |  |  |         m_wsSpectrum.openSocket(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-26 22:30:53 +02:00
										 |  |  | } |