/*************************************************************************** spectrumdisplay.cpp - description ------------------- begin : Fr March 19 2004 copyright : (C) 2004 by Volker Schroer email : dl1ksv@gmx.de ***************************************************************************/ /*************************************************************************** * * * 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; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include #include #include #include #include #include "spectrumdisplay.h" #include "crxchannel.h" #include "parameter.h" #include "color.h" #define SPECTRUMHEIGHT 80 #define WATERFALLHEIGHT 20 #define LABELHEIGHT 10 #define distance 3 extern Parameter settings; SpectrumDisplay::SpectrumDisplay( QWidget* parent, const char* name): QSplitter(QSplitter::Vertical,parent, name) { setBackgroundColor(white); setFrameStyle(QFrame::Box | QFrame::Sunken); setChildrenCollapsible (false); LineSpectrum=new QWidget(this); LineSpectrum->setBackgroundColor(white); pdisplay = new QPixmap(LineSpectrum->width(),LineSpectrum->height()); ColorSpectrum=new QWidget(this); ColorSpectrum->setBackgroundColor(black); pwaterfall = new QPixmap(ColorSpectrum->width(),ColorSpectrum->height()); pwaterfall->fill(black); MaxFreq = new QSpinBox( parent, "MaxFreq" ); MaxFreq->setMaxValue( 2500 ); MaxFreq->setMinValue( 1300 ); MaxFreq->setValue( 2500 ); MaxFreq->setLineStep(100); MinFreq = new QSpinBox( parent, "MinFreq" ); MinFreq->setButtonSymbols( QSpinBox::UpDownArrows ); MinFreq->setMaxValue( 1200 ); MinFreq->setMinValue( 100 ); MinFreq->setLineStep( 100); languageChange(); inputdata=0; Phase=0; Farbe=0; // Connections connect(this,SIGNAL(frequencyChanged(int)),this,SLOT(setnewFrequency(int))); } /* * Destroys the object and frees any allocated resources */ SpectrumDisplay::~SpectrumDisplay() { // no need to delete child widgets, Qt does it all for us } /* * Sets the strings of the subwidgets using the current * language. */ void SpectrumDisplay::languageChange() { MaxFreq->setSuffix(" Hz"); MinFreq->setSuffix(" Hz"); } void SpectrumDisplay::resizeEvent( QResizeEvent *) { calculateSizeofComponents(); translate(); calcFFT(); plotspectrum(false); } void SpectrumDisplay::calculateSizeofComponents() { int xpos,ypos,width,height,innerheight,innerwidth; width=this->width(); height=this->height(); /** Display **/ xpos=0; ypos=height*distance/100; innerwidth=width-2*this->frameWidth()-2*this->margin(); innerwidth=width; innerheight=height*SPECTRUMHEIGHT/100; LineSpectrum->setMinimumHeight(height/2); LineSpectrum->setMaximumHeight(innerheight); //LineSpectrum->setMinimumWidth(innerwidth); //LineSpectrum->setMaximumWidth(innerwidth); //LineSpectrum->setFixedWidth(innerwidth); ColorSpectrum->setMinimumHeight(height-innerheight); ColorSpectrum->setMaximumHeight(height/2); //ColorSpectrum->setFixedWidth(innerwidth); //ColorSpectrum->setMinimumWidth(innerwidth); //ColorSpectrum->setMaximumWidth(innerwidth); /** Controlelements of the display **/ ypos=ypos+height+distance*height/100; innerheight=height*LABELHEIGHT/100; innerwidth=(width-2*xpos)/3; xpos=x(); MinFreq->setGeometry(xpos,ypos,innerwidth,innerheight); //xpos=this->width()-innerwidth; xpos=xpos+width-innerwidth; MaxFreq->setGeometry(xpos,ypos,innerwidth,innerheight); } // Plot Spectrum of decimated Input void SpectrumDisplay::plotspectrum(bool overload) { QPainter p; int dist,y,z,ymax,xmax; int minfreq,maxfreq; double scale; if ( (pwaterfall->width() != ColorSpectrum->width() ) || ( pwaterfall->height() != ColorSpectrum->height())) { pdisplay->resize(LineSpectrum->width(),LineSpectrum->height()); pwaterfall->resize(ColorSpectrum->width(),ColorSpectrum->height()); pwaterfall->fill(black); } //scale = (pdisplay->height())/512.; scale=(pdisplay->height()-15)/100.; minfreq=MinFreq->value(); maxfreq=MaxFreq->value(); ymax=pdisplay->height(); dist=ymax/10; y=ymax-dist; xmax=pdisplay->width(); pdisplay->fill(); p.begin(pdisplay); p.setBrush(white); //Plot Frequencylines for the different Rx- Windows for (CRxChannel *pRx=settings.ChannelChain;pRx != 0;pRx= pRx->getNextChannel()) { if ( Farbe > 0) { int ID = pRx->getID(); if ( ID >= 0 && ID < Farbe->size() ) p.setPen(Farbe->at(ID)); } // Calculate Centerfrequency Coordinates z=(( (int) pRx->getRxFrequency()-minfreq)*xmax)/(maxfreq-minfreq); p.drawLine(z,0,z,ymax); if ( (z = pRx->get2RxFrequency()) != 0 ) // RTTY demands to lines { z=(( z-minfreq)*xmax)/(maxfreq-minfreq); p.drawLine(z,0,z,ymax); } } if(overload) p.setPen(red); else p.setPen(blue); if ( inputdata != 0) { p.moveTo(0,ymax-(int)(scale*fftdata[0])-15); for(int i=1;i 255) y = 255; p.setPen(color[y]); p.drawPoint(i,0); p.drawPoint(i,1); } p.end(); } bitBlt(LineSpectrum,0,0,pdisplay); bitBlt(ColorSpectrum,0,0,pwaterfall); } void SpectrumDisplay::calcFFT() { if (inputdata == 0) return; // No data available for(int i=0;iwidth();i++) //18.4 scales to a range from 0 - 100, as max(inputdata ) = fft_length/4 ^ 2 fftdata[i]=(int)(18.4*(log10(inputdata[xtranslate[i]]+100.)-2.)); // For Color scale should be 18.4 *2.55 } void SpectrumDisplay::translate(void) { int i,to,minfreq,maxfreq,displaywidth; minfreq=MinFreq->value(); maxfreq=MaxFreq->value(); to=int(maxfreq*1024/2756.25); displaywidth=LineSpectrum->width(); for (i=0;iwidth(); freq= (position*(MaxFreq->value()-MinFreq->value()))/ii+MinFreq->value(); settings.ActChannel->setRxFrequency(freq); emit FrequencyChanged(freq); } void SpectrumDisplay::paintLineal(QPainter* p,int xmax,int ymax) { int stepfrequency; float stepwidth; int i,ix,NumberofFreqs,diff; int y; QString frequency; QFontMetrics fm(this->font()); int minfreq=MinFreq->value(); // Calcalute Frequency- Steps diff=(MaxFreq->value()-minfreq); NumberofFreqs=7; while(NumberofFreqs >4) { stepfrequency=diff/NumberofFreqs; if ( stepfrequency * NumberofFreqs != diff ) NumberofFreqs--; else break; } stepwidth=float(xmax)/NumberofFreqs; diff=ymax/10; y=ymax-diff; for( i=1; i < NumberofFreqs; i++) { ix=(int) (i*stepwidth+0.5); p->drawLine(ix,y,ix,y+2); frequency.setNum(minfreq+stepfrequency*i); ix=ix-fm.width(frequency)/2; p->drawText(ix,ymax,frequency); } // Plot Grid for (i=1;i<10; i++) { p->drawLine(0,y,xmax,y); y -=diff; } } void SpectrumDisplay::plotVector(QPainter *p) { int xc,yc; double mag; xc=LineSpectrum->width()/8; yc=LineSpectrum->height()/8; p->drawEllipse(xc,yc,40,40); xc=xc+20; yc=yc+20; p->setPen(green); for(int i=0; i< 11; i++) { p->moveTo( xc,yc); mag=abs(Phase[i]); if ( mag > 0.001) p->lineTo(xc - (int)(20.*Phase[i].imag()/mag), yc - (int)(20.*Phase[i].real()/mag) ); } } void SpectrumDisplay::setPhasePointer(std::complex *p) { Phase=p; } void SpectrumDisplay::setColorList(std::vector *c) { Farbe=c; } void SpectrumDisplay::mousePressEvent(QMouseEvent *e) { emit frequencyChanged(e->x()-lineWidth()); }