#ifndef WATERFALL_GLOBAL_DATA_CPP #define WATERFALL_GLOBAL_DATA_CPP #include WaterfallData::WaterfallData(const double minimumFrequency, const double maximumFrequency, const uint64_t fftPoints, const unsigned int historyExtent) #if QWT_VERSION < 0x060000 : QwtRasterData(QwtDoubleRect(minimumFrequency /* X START */, 0 /* Y START */, maximumFrequency - minimumFrequency /* WIDTH */, static_cast(historyExtent)/* HEIGHT */)) #else : QwtRasterData() #endif { _bounding_rect = QRectF(minimumFrequency, 0, maximumFrequency - minimumFrequency, static_cast(historyExtent)); #if QWT_VERSION >= 0x060000 pixelHint(_bounding_rect); #endif _intensityRange = QwtDoubleInterval(-200.0, 0.0); _fftPoints = fftPoints; _historyLength = historyExtent; _spectrumData = new double[_fftPoints * _historyLength]; Reset(); } WaterfallData::~WaterfallData() { delete[] _spectrumData; } void WaterfallData::Reset() { memset(_spectrumData, 0x0, _fftPoints*_historyLength*sizeof(double)); _numLinesToUpdate = -1; } void WaterfallData::Copy(const WaterfallData* rhs) { #if QWT_VERSION < 0x060000 if((_fftPoints != rhs->GetNumFFTPoints()) || (boundingRect() != rhs->boundingRect()) ){ _fftPoints = rhs->GetNumFFTPoints(); setBoundingRect(rhs->boundingRect()); delete[] _spectrumData; _spectrumData = new double[_fftPoints * _historyLength]; } #else if(_fftPoints != rhs->GetNumFFTPoints()) { _fftPoints = rhs->GetNumFFTPoints(); delete[] _spectrumData; _spectrumData = new double[_fftPoints * _historyLength]; } #endif Reset(); SetSpectrumDataBuffer(rhs->GetSpectrumDataBuffer()); SetNumLinesToUpdate(rhs->GetNumLinesToUpdate()); #if QWT_VERSION < 0x060000 setRange(rhs->range()); #else setInterval(Qt::ZAxis, rhs->interval()); #endif } void WaterfallData::ResizeData(const double startFreq, const double stopFreq, const uint64_t fftPoints) { #if QWT_VERSION < 0x060000 if((fftPoints != GetNumFFTPoints()) || (boundingRect().width() != (stopFreq - startFreq)) || (boundingRect().left() != startFreq)){ setBoundingRect(QwtDoubleRect(startFreq, 0, stopFreq-startFreq, boundingRect().height())); _fftPoints = fftPoints; delete[] _spectrumData; _spectrumData = new double[_fftPoints * _historyLength]; } #else if((fftPoints != GetNumFFTPoints()) || (_bounding_rect.width() != (stopFreq - startFreq)) || (_bounding_rect.left() != startFreq)){ _bounding_rect = QRectF(startFreq, 0, stopFreq-startFreq, _bounding_rect.height()); pixelHint(_bounding_rect); _fftPoints = fftPoints; delete[] _spectrumData; _spectrumData = new double[_fftPoints * _historyLength]; } #endif Reset(); } QwtRasterData *WaterfallData::copy() const { WaterfallData* returnData = new WaterfallData(_bounding_rect.left(), _bounding_rect.right(), _fftPoints, _historyLength); returnData->Copy(this); return returnData; } #if QWT_VERSION < 0x060000 QwtDoubleInterval WaterfallData::range() const { return _intensityRange; } void WaterfallData::setRange(const QwtDoubleInterval& newRange) { _intensityRange = newRange; } #else QwtInterval WaterfallData::interval() const { return _intensityRange; } void WaterfallData::setInterval(Qt::Axis axis, const QwtInterval& newRange) { _intensityRange = newRange; } #endif double WaterfallData::value(double x, double y) const { double returnValue = 0.0; const unsigned int intY = static_cast((1.0 - (y/_bounding_rect.height())) * static_cast(_historyLength-1)); const unsigned int intX = static_cast((((x - _bounding_rect.left()) / _bounding_rect.width()) * static_cast(_fftPoints-1)) + 0.5); const int location = (intY * _fftPoints) + intX; if((location > -1) && (location < static_cast(_fftPoints * _historyLength))){ returnValue = _spectrumData[location]; } return returnValue; } uint64_t WaterfallData::GetNumFFTPoints() const { return _fftPoints; } void WaterfallData::addFFTData(const double* fftData, const uint64_t fftDataSize, const int droppedFrames){ if(fftDataSize == _fftPoints){ int64_t heightOffset = _historyLength - 1 - droppedFrames; uint64_t drawingDroppedFrames = droppedFrames; // Any valid data rolled off the display so just fill in zeros and write new data if(heightOffset < 0){ heightOffset = 0; drawingDroppedFrames = static_cast(_historyLength-1); } // Copy the old data over if any available if(heightOffset > 0){ memmove( _spectrumData, &_spectrumData[(drawingDroppedFrames+1) * _fftPoints], heightOffset * _fftPoints * sizeof(double)) ; } if(drawingDroppedFrames > 0){ // Fill in zeros data for dropped data memset(&_spectrumData[heightOffset * _fftPoints], 0x00, static_cast(drawingDroppedFrames) * _fftPoints * sizeof(double)); } // add the new buffer memcpy(&_spectrumData[(_historyLength - 1) * _fftPoints], fftData, _fftPoints*sizeof(double)); } } double* WaterfallData::GetSpectrumDataBuffer() const { return _spectrumData; } void WaterfallData::SetSpectrumDataBuffer(const double* newData) { memcpy(_spectrumData, newData, _fftPoints * _historyLength * sizeof(double)); } int WaterfallData::GetNumLinesToUpdate() const { return _numLinesToUpdate; } void WaterfallData::SetNumLinesToUpdate(const int newNum) { _numLinesToUpdate = newNum; } void WaterfallData::IncrementNumLinesToUpdate() { _numLinesToUpdate++; } #endif /* WATERFALL_GLOBAL_DATA_CPP */