![]() |
Mixxx
|
00001 /*************************************************************************** 00002 vinylcontrolsignalwidget.cpp 00003 ------------------- 00004 begin : July 5, 2008 00005 copyright : (C) 2008 by Albert Santoni 00006 email : gamegod \a\t users.sf.net 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 00024 #include <QtCore> 00025 #include <QtGui> 00026 #include <math.h> 00027 #include "vinylcontrolsignalwidget.h" 00028 #include "vinylcontrolproxy.h" 00029 00030 VinylControlSignalWidget::VinylControlSignalWidget() 00031 : QWidget(), 00032 m_iTimerId(0), 00033 m_pVinylControl(NULL), 00034 m_iSize(MIXXX_VINYL_SCOPE_SIZE), 00035 m_qImage(), 00036 m_bVinylActive(FALSE), 00037 m_imageData(NULL) { 00038 } 00039 00040 void VinylControlSignalWidget::setSize(int size) 00041 { 00042 m_iSize = size; 00043 setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); 00044 setMinimumSize(size, size); 00045 setMaximumSize(size, size); 00046 m_imageData = new uchar[size * size * 4]; 00047 m_qImage = QImage(m_imageData, size, size, 0, QImage::Format_ARGB32); 00048 } 00049 00050 VinylControlSignalWidget::~VinylControlSignalWidget() 00051 { 00052 delete [] m_imageData; 00053 } 00054 00057 void VinylControlSignalWidget::invalidateVinylControl() 00058 { 00059 m_pVinylControl = NULL; 00060 } 00061 00062 void VinylControlSignalWidget::setVinylControlProxy(VinylControlProxy* vc) 00063 { 00064 00065 m_pVinylControl = vc; 00066 //Catch when the VinylControl objects get deleted (like when 00067 //you change your vinyl type) 00068 connect(m_pVinylControl, SIGNAL(destroyed()), 00069 this, SLOT(invalidateVinylControl())); 00070 } 00071 00072 void VinylControlSignalWidget::setVinylActive(bool active) 00073 { 00074 if (m_bVinylActive != active && !active) 00075 resetWidget(); 00076 m_bVinylActive = active; 00077 } 00078 00079 void VinylControlSignalWidget::startDrawing() { 00080 if (m_iTimerId == 0) { 00081 m_iTimerId = startTimer(60); 00082 } 00083 } 00084 00085 void VinylControlSignalWidget::stopDrawing() { 00086 if (m_iTimerId != 0) { 00087 killTimer(m_iTimerId); 00088 m_iTimerId = 0; 00089 } 00090 } 00091 00092 void VinylControlSignalWidget::timerEvent(QTimerEvent *event) 00093 { 00094 if (m_pVinylControl) { 00095 m_iAngle = (int)m_pVinylControl->getAngle(); 00096 00097 unsigned char * buf = m_pVinylControl->getScopeBytemap(); 00098 00099 int r,g,b; 00100 00101 QColor qual_color = QColor(); 00102 m_fSignalQuality = m_pVinylControl->getTimecodeQuality(); 00103 00104 //color is related to signal quality 00105 //hsv: s=1, v=1 00106 //h is the only variable. 00107 //h=0 is red, h=120 is green 00108 qual_color.setHsv((int)(120.0 * m_fSignalQuality), 255, 255); 00109 qual_color.getRgb(&r, &g, &b); 00110 00111 if (buf) { 00112 for (int x=0; x<m_iSize; x++) { 00113 for(int y=0; y<m_iSize; y++) { 00114 //XXX: endianness means this is backwards.... 00115 //does this break on other platforms? 00116 m_imageData[4*(x+m_iSize*y)+0] = (uchar)b; 00117 m_imageData[4*(x+m_iSize*y)+1] = (uchar)g; 00118 m_imageData[4*(x+m_iSize*y)+2] = (uchar)r; 00119 m_imageData[4*(x+m_iSize*y)+3] = (uchar)buf[x+m_iSize*y]; 00120 } 00121 } 00122 } 00123 } else { 00124 m_fSignalQuality = 0.0; 00125 } 00126 update(); 00127 } 00128 00129 void VinylControlSignalWidget::resetWidget() 00130 { 00131 m_controlLock.lock(); 00132 for (int type = 0; type < (int)VINYLCONTROL_SIGTYPE_NUM; type++) { 00133 m_fRMSvolumeSum[type] = 0.0f; 00134 m_fRMSvolume[type] = 0.0f; 00135 m_samplesCalculated[type] = 0; 00136 } 00137 memset(m_imageData, 0, sizeof(uchar) * m_iSize * m_iSize * 4); 00138 m_controlLock.unlock(); 00139 } 00140 00141 void VinylControlSignalWidget::paintEvent(QPaintEvent* event) 00142 { 00143 int sizeX = this->width(); 00144 int sizeY = this->height(); 00145 00146 QPainter painter(this); 00147 painter.fillRect(this->rect(), QBrush(QColor(0, 0, 0))); 00148 00149 if (m_bVinylActive) { //if timer is stopped, only draw the BG 00150 //main axes 00151 painter.setPen(QColor(0, 255, 0)); 00152 painter.drawLine(sizeX / 2, 0, sizeX / 2, sizeY); 00153 painter.drawLine(0, sizeY / 2, sizeX, sizeY / 2); 00154 00155 //quarter axes 00156 painter.setPen(QColor(0, 127, 0)); 00157 painter.drawLine(sizeX * 0.25, 0, sizeX * 0.25, sizeY); 00158 painter.drawLine(sizeX * 0.75, 0, sizeX * 0.75, sizeY); 00159 painter.drawLine(0, sizeY * 0.25, sizeX, sizeY * 0.25); 00160 painter.drawLine(0, sizeY * 0.75, sizeX, sizeY * 0.75); 00161 00162 //sweep 00163 if (m_iAngle >= 0) { 00164 //sweep fades along with signal quality 00165 painter.setPen(QColor(255, 255, 255, (int)(127.0 * m_fSignalQuality))); 00166 painter.setBrush(QColor(255, 255, 255, (int)(127.0 * m_fSignalQuality))); 00167 painter.drawPie(0, 0, sizeX, sizeY, m_iAngle*16, 6*16); 00168 } 00169 00170 if (!m_qImage.isNull()) { 00171 //vinyl signal -- thanks xwax! 00172 painter.drawImage(this->rect(), m_qImage); 00173 } 00174 } 00175 }