![]() |
Mixxx
|
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 }