Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/script/numberrecorder.cpp

Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines