![]() |
Mixxx
|
00001 #include "numberrecorder.h" 00002 #include "../controlobjectthreadmain.h" 00003 #include "../controlobject.h" 00004 #include "../configobject.h" 00005 00006 #include <qdatetime.h> 00007 00008 NumberRecorder::NumberRecorder(const char* group, const char* name 00009 , int interp) : SignalRecorder() { 00010 m_group = group; 00011 m_name = name; 00012 m_interp = interp; 00013 m_evcount = 0; 00014 m_p = 0; 00015 00016 m_times = QList<int>(); 00017 m_values = QList<double>(); 00018 } 00019 00020 NumberRecorder::~NumberRecorder() { 00021 } 00022 00023 void NumberRecorder::reset() { 00024 m_times = QList<int>(); 00025 m_values = QList<double>(); 00026 m_evcount = 0; 00027 00028 stopRecord(); 00029 00030 // This broke a lot of stuff 00031 //delete m_p; 00032 00033 // TODO: The SDateTime object which holds the start time is probably a 00034 // memory leak 00035 } 00036 00037 void NumberRecorder::startRecord(SDateTime *base) { 00038 m_base = base; 00039 00040 if (m_p == 0) { 00041 ControlObject *obj = ControlObject::getControl(\ 00042 ConfigKey(m_group, m_name)); 00043 m_p = new ControlObjectThreadMain(obj); 00044 qDebug("Created cotm %x", m_p); 00045 } 00046 qDebug("Connecting..."); 00047 connect(m_p, SIGNAL(valueChanged(double)), this, SLOT(valueCaught(double))); 00048 //qDebug("Started recorder for %s:%s", m_group, m_name); 00049 } 00050 00051 void NumberRecorder::stopRecord() { 00052 if (!m_p) { return; } 00053 qDebug("Stopping %s:%s", m_group, m_name); 00054 m_p->disconnect(this); 00055 qDebug("Stopped successfully"); 00056 simplify(); 00057 } 00058 00059 void NumberRecorder::valueCaught(double value) { 00060 //qDebug("%i gone", m_base->msecsTo(&QDateTime::currentDateTime())); 00061 m_evcount++; 00062 00063 // This whole stack/heap thing is getting to me 00064 // Couldn't we have done it in Java instead :) 00065 QDateTime now = QDateTime::currentDateTime(); 00066 00067 int delta = m_base->msecsTo(&now); 00068 00069 if (m_times.empty()) { 00070 m_times.append(delta); 00071 m_values.append(value); 00072 } else { 00073 int last = m_times.last(); 00074 if (delta > last) { 00075 m_times.append(delta); 00076 m_values.append(value); 00077 } 00078 } 00079 } 00080 00081 void NumberRecorder::writeToScript(Recorder* rec) { 00082 if (m_values.empty()) { 00083 return; 00084 } 00085 rec->beginInterpolate(m_group, m_name, m_interp); 00086 00087 QList<int>::const_iterator tit; 00088 QList<double>::const_iterator vit; 00089 00090 vit = m_values.begin(); 00091 for (tit = m_times.begin(); tit != m_times.end(); tit++) { 00092 rec->addInterPoint(*tit, *vit); 00093 vit++; 00094 } 00095 rec->endInterpolate(); 00096 } 00097 00098 #define TOLERANCE 0.05 00099 00105 void NumberRecorder::simplify() { 00106 if (m_times.count() < 3) { 00107 return; 00108 } 00109 for (int i = 0; i < m_times.count() - 2; i++) { 00110 // qDebug("Count: %i", m_times.count()); 00111 int end = findFurthest(i); 00112 // qDebug("End: %i->%i", i, end); 00113 if (i > 200) { exit(0); } 00114 if (end > i + 1) { 00115 QList<int>::iterator tst = m_times.begin(); 00116 tst++; 00117 QList<double>::iterator vst = m_values.begin(); 00118 vst++; 00119 // qDebug("Erasing %i at %i", ((end - i) - 1), i); 00120 for (int d = 0; d < ((end - i) - 1); d++) { 00121 tst = m_times.erase(tst); 00122 vst = m_values.erase(vst); 00123 } 00124 } 00125 } 00126 } 00127 00128 int NumberRecorder::findFurthest(int start) { 00129 int max = m_times.count() - 1; 00130 if (start + 1 == max) { 00131 return max; 00132 } 00133 for (int i = start+2; i <= max; i++) { 00134 if (!tryLineFit(start, i)) { 00135 return i - 1; 00136 } 00137 } 00138 return max; 00139 } 00140 00141 bool NumberRecorder::tryLineFit(int start, int end) { 00142 double m = (m_values[end]-m_values[start])/ 00143 (m_times[end]-m_times[start]); 00144 double c = m_values[start] - (m*m_times[start]); 00145 // qDebug("Linear fit: %f, %f", (float)m, (float)c); 00146 // qDebug("From: %i, %f", m_times[start], (float)m_values[start]); 00147 // qDebug("To: %i, %f", m_times[end], (float)m_values[end]); 00148 for (int i = start + 1; i < end; i++) { 00149 double y = (m * m_times[i]) + c; 00150 double diff = y - m_values[i]; 00151 if (diff < 0.0) { diff = -diff; } 00152 //qDebug("Diff here: %f", (float)diff); 00153 if (diff > TOLERANCE) { return false; } 00154 } 00155 00156 return true; 00157 }