Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/midi/midiledhandler.cpp

Go to the documentation of this file.
00001 #include "midiledhandler.h"
00002 #include "widget/wwidget.h"
00003 #include <QList>
00004 #include <QDebug>
00005 
00006 QList<MidiLedHandler*> MidiLedHandler::allhandlers = QList<MidiLedHandler*>();
00007 
00008 MidiLedHandler::MidiLedHandler(QString group, QString key, MidiDevice & midi, double min,
00009                                double max, unsigned char status, unsigned char midino, unsigned char on, unsigned char off)
00010     : m_min(min), m_max(max), m_midi(midi), m_status(status), m_midino(midino), m_on(on), m_off(off) {
00011 
00012     //OMGWTFBBQ: Massive hack to temporarily fix LP #254564 for the 1.6.0 release.
00013     //           Something's funky with our <lights> blocks handling? -- Albert 08/05/2008
00014     if (group.isEmpty() || key.isEmpty()) return;
00015 
00016     m_cobj = ControlObject::getControl(ConfigKey(group, key));
00017 
00018     //m_cobj should never be null, so Q_ASSERT here to make sure that we hear about it if it is null.
00019     //Q_ASSERT(m_cobj);
00020     QByteArray err_tmp = QString("Invalid config group: '%1', name: '%2'").arg(group).arg(key).toAscii();
00021     Q_ASSERT_X(m_cobj, "MidiLedHandler", err_tmp);
00022 
00023     connect(m_cobj, SIGNAL(valueChangedFromEngine(double)), this, SLOT(controlChanged(double)), Qt::DirectConnection);
00024     connect(m_cobj, SIGNAL(valueChanged(double)), this, SLOT(controlChanged(double)), Qt::DirectConnection);
00025 }
00026 
00027 MidiLedHandler::~MidiLedHandler() {
00028     ConfigKey cKey = m_cobj->getKey();
00029     if (m_midi.midiDebugging()) {
00030         qDebug() << QString("Destroying static LED handler on %1 for %2,%3")
00031             .arg(m_midi.getName()).arg(cKey.group).arg(cKey.item);
00032     }
00033 }
00034 
00035 void MidiLedHandler::update() {
00036     controlChanged(m_cobj->get());
00037 }
00038 
00039 void MidiLedHandler::controlChanged(double value) {
00040     //Guh, the valueChangedFromEngine and valueChanged signals can occur simultaneously because we're
00041     //using Qt::DirectConnection. We have to block by hand to prevent re-entrancy. We can't use
00042     //Qt::BlockingQueuedConnection because we don't have an event loop in some of the threads that
00043     //create MidiLedHandlers. (The underlying code is messy - On first run, the LED handlers get created
00044     //in the main thread, and then after you load a new binding, they get created from the Midi thread.)
00045     // - Albert 04/19/2009
00046     m_reentracyBlock.lock();
00047     unsigned char m_byte2 = m_off;
00048     if (value >= m_min && value <= m_max) { m_byte2 = m_on; }
00049 
00050     if (!m_midi.isOpen())
00051         qWarning() << "MIDI device" << m_midi.getName() << "not open for output!";
00052     else if (m_byte2 != 0xff) {
00053 //         qDebug() << "MIDI bytes:" << m_status << ", " << m_midino << ", " << m_byte2 ;
00054         m_midi.sendShortMsg(m_status, m_midino, m_byte2);
00055     }
00056     m_reentracyBlock.unlock();
00057 }
00058 
00059 void MidiLedHandler::createHandlers(QDomNode node, MidiDevice & midi) {
00060     if (!node.isNull() && node.isElement()) {
00061         QDomNode light = node;
00062         while (!light.isNull()) {
00063             if(light.nodeName() == "output") {
00064                 QString group = WWidget::selectNodeQString(light, "group");
00065                 QString key = WWidget::selectNodeQString(light, "key");
00066 
00067                 unsigned char status = (unsigned char)WWidget::selectNodeInt(light, "status");
00068                 unsigned char midino = (unsigned char)WWidget::selectNodeInt(light, "midino");
00069                 unsigned char on = 0x7f;    // Compatible with Hercules and others
00070                 unsigned char off = 0x00;
00071                 float min = 0.0f;
00072                 float max = 1.0f;
00073                 if (!light.firstChildElement("on").isNull()) {
00074                     on = (unsigned char)WWidget::selectNodeInt(light, "on");
00075                 }
00076                 if (!light.firstChildElement("off").isNull()) {
00077                     off = (unsigned char)WWidget::selectNodeInt(light, "off");
00078                 }
00079                 if (!light.firstChildElement("threshold").isNull()) { //Deprecated as of 1.7.0
00080                     min = WWidget::selectNodeFloat(light, "threshold");
00081                 }
00082                 if (!light.firstChildElement("minimum").isNull()) {
00083                     min = WWidget::selectNodeFloat(light, "minimum");
00084                 }
00085                 if (!light.firstChildElement("maximum").isNull()) {
00086                     max = WWidget::selectNodeFloat(light, "maximum");
00087                 }
00088                 if (midi.midiDebugging()) {
00089                     qDebug() << QString(
00090                     "Creating LED handler for %1,%2 between %3 and %4 to MIDI out: 0x%5 0x%6, on: 0x%7 off: 0x%8")
00091                         .arg(group).arg(key).arg(min).arg(max)
00092                         .arg(QString::number(status, 16).toUpper())
00093                         .arg(QString::number(midino, 16).toUpper().rightJustified(2,'0'))
00094                         .arg(QString::number(on, 16).toUpper().rightJustified(2,'0'))
00095                         .arg(QString::number(off, 16).toUpper().rightJustified(2,'0'));
00096                 }
00097 
00098                 allhandlers.append(new MidiLedHandler(group, key, midi, min, max, status, midino, on, off));
00099             }
00100             light = light.nextSibling();
00101         }
00102     }
00103 }
00104 
00105 void MidiLedHandler::updateAll() {
00106     for (int i = 0; i < allhandlers.count(); i++) {
00107         allhandlers.at(i)->update();
00108     }
00109 }
00110 
00111 void MidiLedHandler::destroyHandlers(MidiDevice *midi) {
00112     for (int i = allhandlers.count()-1; i >= 0; --i) {
00113         if (allhandlers.at(i)->getMidiDevice() == midi) {
00114             delete allhandlers.takeAt(i);
00115         }
00116     }
00117 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines